Points&Forces (survey)
Software tools facilitating the task of surveying architecture
a_face_2d4.cxx
Go to the documentation of this file.
1 /*
2 Copyright 2010-2016 Pierre SMARS (smars@yuntech.edu.tw)
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 2 of the License, or
6 (at your option) any later version.
7 
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16 #include "a_face_2d4.h"
17 #include "a_block_2d3.h"
18 #include "a_block_2d4.h"
19 #include "a_block_2d5.h"
20 
21 #include "a_debug.h"
22 
23 const double verysmall = 1.e-6;
24 
25 //---------------------------------------------------------------------------
26 a_face_2d4 * cf_2d4(a_face * f) {return dynamic_cast<a_face_2d4*>(f); }
27 const a_face_2d4 * cf_2d4(const a_face * f) {return dynamic_cast<const a_face_2d4*>(f); }
28 //---------------------------------------------------------------------------
29 double a_face_2d4::thickness() const
30 {
31  if (this->block_->name()=="a_block_2d3")
32  return cb_2d3(this->block_)->thickness();
33  if (this->block_->name()=="a_block_2d4")
34  return cb_2d4(this->block_)->thickness();
35  if (this->block_->name()=="a_block_2d5")
36  return cb_2d5(this->block_)->thickness();
37  return 0.; //problem!
38 }
39 //---------------------------------------------------------------------------
40 double a_face_2d4::dyM() const
41 {
42  return this->thickness()/2.;
43 }
44 //---------------------------------------------------------------------------
45 double a_face_2d4::dym() const
46 {
47  return this->thickness()/2.;
48 }
49 //---------------------------------------------------------------------------
50 double a_face_2d4::length() const
51 {
52  a_point * p1 = this->vl(0);
53  a_point * p2 = this->vl(1);
54  return (*p2-*p1).norm();
55 }
56 //---------------------------------------------------------------------------
57 void a_face_2d4::slide(const double& u, const double& v)
58 {
59  if (v!=0.)
60  std::cout << "do not expect much with v different from 0. with this type of face" << std::endl;
61  a_face::slide(u,v);
62 }
63 //---------------------------------------------------------------------------
64 double a_face_2d4::S() const
65 {
66  return (this->length())*(this->thickness());
67 }
68 //---------------------------------------------------------------------------
69 a_point a_face_2d4::cl() const
70 {
71  a_point * p1 = this->vl(0);
72  a_point * p2 = this->vl(1);
73  return ((*p1)+(*p2))/2.;
74 }
75 //---------------------------------------------------------------------------
76 a_point a_face_2d4::v3d(const int i) const
77 {
78  a_point n = this->ny();//normal to the block
79  n *= this->thickness()/2.;
80  if (i==0)
81  return v(0)-n;
82  if (i==1)
83  return v(0)+n;
84  if (i==2)
85  return v(1)+n;
86  return v(1)-n;
87 }
88 //---------------------------------------------------------------------------
89 a_point a_face_2d4::nx() const
90 {
91  a_point p1,p2;
92  if (block_->name()=="a_block_2d4")
93  {
94  a_block_2d4 * b = dynamic_cast<a_block_2d4*>(block_);
95  p1 = (*(b->pos())) * (*(this->vl(0)));
96  p2 = (*(b->pos())) * (*(this->vl(1)));
97  }
98  if (block_->name()=="a_block_2d3")
99  {
100  a_block_2d3 * b = dynamic_cast<a_block_2d3*>(block_);
101  p1 = (*(b->pos())) * (*(this->vl(0)));
102  p2 = (*(b->pos())) * (*(this->vl(1)));
103  }
104  if (block_->name()=="a_block_2d5")
105  {
106  a_block_2d5 * b = dynamic_cast<a_block_2d5*>(block_);
107  p1 = (*(b->pos())) * (*(this->vl(0)));
108  p2 = (*(b->pos())) * (*(this->vl(1)));
109  }
110  return (p2-p1).normalise();
111 }
112 //---------------------------------------------------------------------------
113 a_point a_face_2d4::ny() const
114 {
115  if (block_->name()=="a_block_2d4")
116  {
117  a_block_2d4 * b = dynamic_cast<a_block_2d4*>(block_);
118  return b->normal();
119  }
120  if (block_->name()=="a_block_2d3")
121  {
122  a_block_2d3 * b = dynamic_cast<a_block_2d3*>(block_);
123  return b->normal();
124  }
125  if (block_->name()=="a_block_2d5")
126  {
127  a_block_2d5 * b = dynamic_cast<a_block_2d5*>(block_);
128  return b->normal();
129  }
130  return a_point(); // problem
131 }
132 //---------------------------------------------------------------------------
133 a_point a_face_2d4::normal() const
134 {
135  a_point px = this->nx();
136  a_point py = this->ny();
137  return cross(px,py).normalise();
138 }
139 //---------------------------------------------------------------------------
140 int a_face_2d4::ptsinplane(const a_plane& p) const
141 {
142  int n = 0;
143  for (int i=0; i<4; i++)
144  {
145  if (p.contains(this->v3d(i)))
146  n++;
147  }
148  return n;
149 }
150 //---------------------------------------------------------------------------
151 double a_face_2d4::exrx() const
152 {
153  return 2*(this->exx()/this->length());
154 }
155 //---------------------------------------------------------------------------
156 double a_face_2d4::exry() const
157 {
158  return 2*(this->exy()/this->length());
159 }
160 //---------------------------------------------------------------------------
161 std::vector<a_triangle> a_face_2d4::triangles() const
162 {
163  //find the 4 corners of face
164  a_point p01 = v(0);
165  a_point p02 = v(1);
166  a_point n = this->ny();//normal to the block
167  double th = this->thickness()/2.;
168  a_point p1 = p01-n*th;
169  a_point p2 = p01+n*th;
170  a_point p3 = p02+n*th;
171  a_point p4 = p02-n*th;
172  a_triangle t1(p1,p2,p3);
173  a_triangle t2(p1,p3,p4);
174  std::vector<a_triangle> list;
175  list.push_back(t1);
176  list.push_back(t2);
177  return list;
178 }
179 //---------------------------------------------------------------------------
181 {
182  if (lface_==0)
183  return -2;
184  a_face_2d4 * f2 = cf_2d4(lface_);
185  int n1 = this->ptsinplane(f2->plane());
186  int n2 = f2->ptsinplane(this->plane());
187  int n=n2;
188  if (n1>n2)
189  n=n1;
190  if (n==0)
191  return -1;
192  if (n>2)
193  return 2;
194  return n-1;
195 }
196 //---------------------------------------------------------------------------
197 bool a_face_2d4::contains(const a_point& p) const
198 {
199  std::vector<a_triangle> t = this->triangles();
200  bool i1 = t[0].contains(p);
201  bool i2 = t[1].contains(p);
202  return (i1||i2);
203 }
204 //---------------------------------------------------------------------------
205 a_segment a_face_2d4::segment(const int i) const
206 {
207  return a_segment(this->v3d(i%4),this->v3d((i+1)%4));
208 }
209 //---------------------------------------------------------------------------
210 void a_face_2d4::grow(const double& val)
211 {
212  a_point c = this->c();
213  a_point d = (val/2.)*this->nx();
214  int r0 = r_vertices_[0];
215  int r1 = r_vertices_[1];
216  a_point p0n = this->v(0)-d;
217  a_point p1n = this->v(1)+d;
218  this->block()->v(r0)->set(p0n.x(),p0n.y(),p0n.z());
219  this->block()->v(r1)->set(p1n.x(),p1n.y(),p1n.z());
220 }
221 //---------------------------------------------------------------------------
222 a_segment a_face_2d4::intersect(const a_segment& s) const
223 {
224  a_segment s1;
225  a_segment s2;
226  bool t1 = true;
227  bool t2 = true;
228  std::vector<a_triangle> t = this->triangles();
229  try {
230  s1 = t[0].intersect(s);
231  }
232  catch(a_segment::null_segment_error) {
233  t1 =false;
234  }
235  try {
236  s2 = t[1].intersect(s);
237  }
238  catch(a_segment::null_segment_error) {
239  t2 =false;
240  }
241  if (!t1&&!t2)
243  if (t1&&t2)
244  {
246  a_point v1 = s1.p1();
247  a_point v2 = s1.p2();
248  a_point v3 = s2.p1();
249  a_point v4 = s2.p2();
250  if ((v2-v3).norm()<verysmall)
251  return a_segment(v1,v4);
252  if ((v1-v3).norm()<verysmall)
253  return a_segment(v2,v4);
254  if ((v1-v4).norm()<verysmall)
255  return a_segment(v2,v3);
256  return a_segment(v1,v3);
257  }
258  if (t1) return s1;
259  //if (t2) return s2; // test not necessary
260  return s2;
261 }
262 //---------------------------------------------------------------------------
264 {
265  int code = this->contacttype();
266  if (code != 0)
268  a_face_2d4 * f2 = cf_2d4(lface_);
269  std::vector<a_triangle> t1 = this->triangles();
270  std::vector<a_triangle> t2 = f2->triangles();
272  a_point p0;
273  for (int i=0; i<2; i++)
274  {
275  for (int j=0; j<3; j++)
276  {
277  a_point p = t1[i][j];
278  double d = t2[0].distp(p);
279  if (d<verysmall)
280  {
281  p0 = p;
282  break;
283  }
284  }
285  }
286  //check if p0 is inside f2
287  if (f2->contains(p0))
288  return p0;
289  else
291 }
292 //---------------------------------------------------------------------------
293 a_segment a_face_2d4::contactsegment() const
294 {
295  int code = this->contacttype();
296  if (code != 1)
298  const a_face_2d4 * f2 = cf_2d4(lface_);
299  const a_face_2d4 * f;
301  int n1 = this->ptsinplane(f2->plane());
302  if (n1==2)
303  f = this;
304  else
305  {
306  f = f2;
307  f2 = this;
308  }
309  //find edge on f
310  std::vector<a_point> pts;
311  a_plane p = f2->plane();
312  for (int i=0; i<4; i++)
313  {
314  a_point x = f->v3d(i);
315  if (p.contains(x))
316  pts.push_back(x);
317  }
318  a_segment s1(pts[0],pts[1]);
320  a_segment s2 = f2->intersect(s1);
321  return s2;
322 }
323 //---------------------------------------------------------------------------
325 {
326  int code = this->contacttype();
327  if (code != 2)
329  a_face_2d4 * f2 = cf_2d4(lface_);
330  std::vector<a_triangle> t1 = this->triangles();
331  std::vector<a_triangle> t2 = f2->triangles();
332  std::vector<a_segment> segs;
334  for (int i=0; i<4; i++)
335  {
336  a_segment s = this->segment(i);
338  for (int k=0; k<2; k++)
339  {
340  try {
342  a_segment s2 = t2[k].intersect(s);
343  segs.push_back(s2);
344  }
345  catch(a_segment::null_segment_error) { }
346  }
347  }
349  for (int i=0; i<4; i++)
350  {
351  a_segment s = f2->segment(i);
353  for (int k=0; k<2; k++)
354  {
355  try {
357  a_segment s2 = t1[k].intersect(s);
358  segs.push_back(s2);
359  }
360  catch(a_segment::null_segment_error) { }
361  }
362  }
363  int nsegs = segs.size();
364  if (nsegs==0)
366  a_contact faces;
367  faces.f(this->f());
369  faces.av(segs[0].p1());
370  int i = 0;
371  int npts = 1;
372  while (npts!=nsegs)
373  {
374  a_point p = segs[i].p2();
375  bool stop;
376  for (int j=0; j<nsegs; j++)
377  {
378  if (j != i)
379  {
380  a_point p2 = segs[j].p1();
381  double d = (p-p2).norm();
382  if (d<verysmall)
383  {
384  i=j;
385  faces.av(p2);
386  npts++;
387  break;
388  }
389  p2 = segs[j].p2();
390  d = (p-p2).norm();
391  if (d<verysmall)
392  {
393  i=j;
394  faces.av(p2);
395  npts++;
396  a_point p3 = segs[j].p2();
397  segs[j].p2(segs[j].p1());
398  segs[j].p1(p3);
399  break;
400  }
401 
402  }
403  }
404  }
405  faces.clean();
406  return faces;
407 }
408 /*
409 // ***************************************************************************
410 //-operator>>----------------------------------------------------------------
411 std::istream& operator>> (std::istream& in, a_face& f)
412 {
413  int nv;
414  in >> nv;
415  f.r_vertices_.clear();
416  for (int i=0; i<nv; i++)
417  {
418  int ref;
419  in >> ref;
420  f.r_vertices_.push_back(ref);
421  }
422  return in;
423 }
424 //-operator<<----------------------------------------------------------------
425 std::ostream& operator<< (std::ostream& o, const a_face& f)
426 {
427  std::cout << f.nv() << " ";
428  for (int i=0; i<f.nv(); i++)
429  std::cout << f.rv(i) << " ";
430  return o;
431 }
432 */
a_block_2d3 * cb_2d3(a_block *b)
Definition: a_block_2d3.cxx:21
a_block_2d4 * cb_2d4(a_block *b)
Definition: a_block_2d4.cxx:21
a_block_2d5 * cb_2d5(a_block *b)
Definition: a_block_2d5.cxx:21
const double verysmall
Definition: a_face_2d4.cxx:23
a_face_2d4 * cf_2d4(a_face *f)
Definition: a_face_2d4.cxx:26
a_point normal() const
normal to the definition plan of the block (world coordinates)
void thickness(const double thickness)
set block thickness
Definition: a_block_2d3.h:37
void thickness(const double thickness)
set block thickness
Definition: a_block_2d4.h:37
a_point normal() const
normal to the definition plan of the block (world coordinates)
void thickness(const double thickness)
set block thickness
Definition: a_block_2d5.h:37
a_point normal() const
normal to the definition plan of the block (world coordinates)
virtual std::string name() const
Definition: a_block.h:47
a_twist * pos() const
get pointer to position handle
Definition: a_block.h:101
a_point * v(const int i)
get pointer to vertex
Definition: a_block.cxx:134
void f(const a_wrench &f)
set force on the face
Definition: a_contact.h:43
void clean()
clean
Definition: a_contact.cxx:36
void av(const a_point p)
add a vertex
Definition: a_contact.h:35
virtual double S() const
Surface.
Definition: a_face_2d4.cxx:64
std::vector< a_triangle > triangles() const
get 2 triangles defining the face
Definition: a_face_2d4.cxx:161
a_plane plane() const
plane defined by face
Definition: a_face_2d4.h:51
double dym() const
distance from center to min y
Definition: a_face_2d4.cxx:45
double exry() const
relative excentricity in y direction (between 0 and 1)
Definition: a_face_2d4.cxx:156
void slide(const double &u, const double &v)
slide the face in its plane
Definition: a_face_2d4.cxx:57
virtual int contacttype() const
contact type: (-2: no sister face, -1: not touching, 2: plane contact, 1: edge contact,...
Definition: a_face_2d4.cxx:180
double length() const
length of the face
Definition: a_face_2d4.cxx:50
a_point nx() const
direction of face
Definition: a_face_2d4.cxx:89
int ptsinplane(const a_plane &p) const
get number of points in plane
Definition: a_face_2d4.cxx:140
a_segment segment(const int i) const
get segment (world coordinate)
Definition: a_face_2d4.cxx:205
virtual a_point cl() const
centre of gravity of the face (in local coordinates)
Definition: a_face_2d4.cxx:69
bool contains(const a_point &p) const
check whether a point is inside the face
Definition: a_face_2d4.cxx:197
virtual a_segment contactsegment() const
return edge of contact if faces touch by one edge: hinge
Definition: a_face_2d4.cxx:293
virtual a_point contactpoint() const
return point of contact if faces just touch by one point
Definition: a_face_2d4.cxx:263
a_segment intersect(const a_segment &s) const
intersection of face with a segment
Definition: a_face_2d4.cxx:222
a_point normal() const
normal to the face
Definition: a_face_2d4.cxx:133
virtual a_contact contactface() const
return common surface of contact
Definition: a_face_2d4.cxx:324
double thickness() const
thickness of the face
Definition: a_face_2d4.cxx:29
void grow(const double &val)
grow face
Definition: a_face_2d4.cxx:210
double dyM() const
distance from center to max y
Definition: a_face_2d4.cxx:40
a_point v3d(const int i) const
get vertex (world coordinate, 3D: 4 points: order v0-n, v0+n, v1+n, v1-n
Definition: a_face_2d4.cxx:76
a_point ny() const
normal to the vertices of the block
Definition: a_face_2d4.cxx:113
double exrx() const
relative excentricity in x direction (between 0 and 1)
Definition: a_face_2d4.cxx:151
Definition: a_face.h:33
virtual void slide(const double &u, const double &v)
slide the face in its plane
Definition: a_face.cxx:217
a_face * lface_
face in contact
Definition: a_face.h:196
std::vector< int > r_vertices_
references to the points of the block defining the face
Definition: a_face.h:190
double exy() const
excentricity in y direction
Definition: a_face.cxx:446
a_point c() const
centre of mass (in world coordinate)
Definition: a_face.cxx:311
virtual a_point x() const
application point of f on face
Definition: a_face.cxx:400
a_point * vl(const int i)
get vertex (in local coordinate)
Definition: a_face.cxx:301
a_point v(const int i) const
get vertex (in world coordinate)
Definition: a_face.cxx:289
a_wrench f() const
get force on the face
Definition: a_face.h:141
double exx() const
excentricity in x direction
Definition: a_face.cxx:432
a_block * block_
block to which the face belongs
Definition: a_face.h:186
a_block * block()
get block
Definition: a_face.h:49