Points&Forces (survey)
Software tools facilitating the task of surveying architecture
a_face.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.h"
17 #include "a_block.h"
18 
19 #include "config.h"
20 
21 const double verysmall = 1.e-8;
22 
23 //---------------------------------------------------------------------------
24 a_face::a_face() : exit_face_(false), lface_(0)
25 {
26  r_vertices_.clear();
27  criteria_ = 0;
28  f_ = new a_wrench;
29  f_original_ = true;
30 }
31 //---------------------------------------------------------------------------
32 a_face::a_face(a_block * b, int ref_face) : exit_face_(false), lface_(0), ref_(ref_face)
33 {
34  r_vertices_.clear();
35  block_=b;
36  criteria_ = 0;
37  f_ = new a_wrench;
38  f_original_ = true;
39 }
40 //---------------------------------------------------------------------------
42 {
43  this->clear();
44  if (f_original_)
45  delete f_;
46 }
47 //---------------------------------------------------------------------------
49 {
50  //nothing special to do, just a vector of int
51  r_vertices_.clear();
52 }
53 //---------------------------------------------------------------------------
54 const std::string a_face::help()
55 {
56  std::ostringstream o;
57  o << "********" << std::endl;
58  o << "a_face:" << std::endl;
59  o << "********" << std::endl;
60  o << "This class is used to model the face of a 'a_block' (see a_block_help for more information)" << std::endl;
61  o << "This is a virtual class, it cannot be used directly, see a_face_... for usable classes" << std::endl;
62  o << "Commands:" << std::endl;
63  o << "--------" << std::endl;
64  o << "c: centre of gravity" << std::endl;
65  o << "cl: centre of gravity (in local coordinate system)" << std::endl;
66  o << "dx: x dimension of face" << std::endl;
67  o << "dy: y dimension of face" << std::endl;
68  o << "dxM: maximum x-distance between centre of gravity and vertices" << std::endl;
69  o << "dxm: minimum x-distance between centre of gravity and vertices" << std::endl;
70  o << "dyM: maximum y-distance between centre of gravity and vertices" << std::endl;
71  o << "dym: minimum y-distance between centre of gravity and vertices" << std::endl;
72  o << "point 'u' 'v': get point given excentricities u and v" << std::endl;
73  o << "exit 'bool': set face as an exit face" << std::endl;
74  o << "exit: check whether face is an exit face" << std::endl;
75  o << "S: surface" << std::endl;
76  o << "Sx: projection of surface perpendicular to x" << std::endl;
77  o << "Sy: projection of surface perpendicular to y" << std::endl;
78  o << "Sz: projection of surface perpendicular to z" << std::endl;
79  o << "nx: direction x" << std::endl;
80  o << "ny: direction y" << std::endl;
81  o << "normal: normal to the face" << std::endl;
82  o << "normale 'i': normal to edge i" << std::endl;
83  o << "plane: gets a a_plane" << std::endl;
84  o << "N: normal force" << std::endl;
85  o << "Qx: shear force" << std::endl;
86  o << "Qy: shear force" << std::endl;
87  o << "Mx: torque (bending)" << std::endl;
88  o << "My: torque (bending)" << std::endl;
89  o << "Mt: torque (torsion)" << std::endl;
90  o << "ax: angle of incidence" << std::endl;
91  o << "ay: angle of incidence" << std::endl;
92  o << "x: application point of f on face" << std::endl;
93  o << "exx: excentricity in x direction" << std::endl;
94  o << "exy: excentricity in y direction" << std::endl;
95  o << "exn: excentricity in normal direction (should be 0)" << std::endl;
96  o << "nv: get number of vertices" << std::endl;
97  o << "av 'ref': add reference to a vertex" << std::endl;
98  o << "rv 'i': gets vertex reference" << std::endl;
99  o << "block: gets block to which the face belongs" << std::endl;
100  o << "f 'a_wrench': apply wrench to face" << std::endl;
101  o << "f 'a_point': apply force to centre of gravity of face" << std::endl;
102  o << "f 'fx' 'fy' 'fz': apply force to centre of gravity of face" << std::endl;
103  o << "f: gets force applied to face" << std::endl;
104  o << "lface: gets connected face" << std::endl;
105  o << "lblock: gets connected block" << std::endl;
106  o << "in: face is connected to other faces, inside the structure" << std::endl;
107  o << "out: face is not connected to other faces, on the boudary" << std::endl;
108  o << "hinge: hinge opening: rotation vector" << std::endl;
109  o << "contacttype: contact type: (-2: no sister face, -1: not touching, 2: plane contact, 1: edge contact, 0: point contact)" << std::endl;
110  o << "contactpoint: return point of contact if faces just touch by one point" << std::endl;
111  o << "contactsegment: return edge of contact if faces touch by one edge: hinge" << std::endl;
112  o << "contactface: return common surface of contact" << std::endl;
113  o << "grow 'val': incread the size of the face" << std::endl;
114  o << "slide 'u' 'v': slide face in its own plane (values are relative excentricities)" << std::endl;
115  o << "deform 'i' 'val': move edge 'i' perpendicularly to itself" << std::endl;
116  return o.str();
117 }
118 //---------------------------------------------------------------------------
119 a_point a_face::vc(const int i) const
120 {
121  return this->v(i)-this->c();
122 }
123 //---------------------------------------------------------------------------
124 double a_face::dxM() const
125 {
126  double dmax = 0.;
127  a_point c = this->c();
128  for (unsigned short i=0; i<this->nv(); i++)
129  {
130  double d;
131  d = (this->vc(i))*(this->nx());
132  if (d>dmax)
133  dmax = d;
134  }
135  return dmax;
136 }
137 //---------------------------------------------------------------------------
138 double a_face::dxm() const
139 {
140  double dmin = 0.;
141  for (unsigned short i=0; i<this->nv(); i++)
142  {
143  double d;
144  d = (this->vc(i))*(this->nx());
145  if (d<dmin)
146  dmin = d;
147  }
148  return -dmin;
149 }
150 //---------------------------------------------------------------------------
151 double a_face::dyM() const
152 {
153  double dmax = 0.;
154  for (unsigned short i=0; i<this->nv(); i++)
155  {
156  double d;
157  d = (this->vc(i))*(this->ny());
158  if (d>dmax)
159  dmax = d;
160  }
161  return dmax;
162 }
163 //---------------------------------------------------------------------------
164 double a_face::dym() const
165 {
166  double dmin = 0.;
167  for (unsigned short i=0; i<this->nv(); i++)
168  {
169  double d;
170  d = (this->vc(i))*(this->ny());
171  if (d<dmin)
172  dmin = d;
173  }
174  return -dmin;
175 }
176 //---------------------------------------------------------------------------
177 double a_face::dx() const
178 {
179  return this->dxM()+this->dxm();
180 }
181 //---------------------------------------------------------------------------
182 double a_face::dy() const
183 {
184  return this->dyM()+this->dym();
185 }
186 //---------------------------------------------------------------------------
187 a_point a_face::normale(const unsigned short ref)
188 {
189  if (ref>this->nv()) throw a_face::bad_indexing_error();
190  a_point c = this->c();
191  a_point p0 = this->v(ref);
192  if (this->nv()==2)
193  {
194  //we are then in 2D, edge is a point
195  return (p0-c).normalise();
196  }
197  else
198  {
199  //we are then in 3D, find perp to edge
200  int ref1 = (ref+1)%this->nv();
201  a_point p1 = this->v(ref1);
202  //direction of the edge
203  a_point l = p1-p0;
204  //normal to the face
205  a_point n = this->normal();
206  a_point ne = cross(n,l);
207  //direction has to be checked...
208  return ne.normalise();
209  }
210 }
211 //---------------------------------------------------------------------------
212 a_point a_face::point(const double& u, const double& v) const
213 {
214  return this->c()+(u*this->dx()/2.)*this->nx()+(v*this->dy()/2.)*this->ny();
215 }
216 //---------------------------------------------------------------------------
217 void a_face::slide(const double& u, const double& v)
218 {
219  a_point d = (u*this->dx()/2.)*this->nx()+(v*this->dy()/2.)*this->ny();
220  for (unsigned short i=0; i<this->nv(); i++)
221  {
222  a_point pn = this->v(i)+d;
223  int r = r_vertices_[i];
224  this->block()->v(r)->set(pn.x(),pn.y(),pn.z());
225  }
226 }
227 //---------------------------------------------------------------------------
228 void a_face::deform(const unsigned short& ref, const double& val)
229 {
230  if (ref>this->nv()) throw a_face::bad_indexing_error();
231  int r0 = r_vertices_[ref];
232  a_point d = val*this->normale(ref);
233  a_point p0n = this->v(ref)+d;
234  this->block()->v(r0)->set(p0n.x(),p0n.y(),p0n.z());
235  if (this->nv()>2)
236  {
237  //we are then in 3D, next point also need to be moved
238  int ref1 = (ref+1)%this->nv();
239  int r1 = r_vertices_[ref1];
240  a_point p1n = this->v(ref1)+d;
241  this->block()->v(r1)->set(p1n.x(),p1n.y(),p1n.z());
242  }
243 }
244 //---------------------------------------------------------------------------
245 bool a_face::ok() const
246 {
247  //if no criteria was linked, should be always good!
248  if (criteria_==0)
249  return true;
250  else
251  return criteria_->ok(this);
252 }
253 //---------------------------------------------------------------------------
254 double a_face::penalty() const
255 {
256  //if no criteria was linked, should be always good!
257  if (criteria_==0)
258  return 0.;
259  else
260  return criteria_->penalty(this);
261 }
262 //---------------------------------------------------------------------------
264 {
265 // if (f_ != 0)
266 // delete f_;
267  f_original_ = false;
268  f_ = f;
269 }
270 //---------------------------------------------------------------------------
271 double a_face::Sx() const
272 {
273  double c = fabs(this->normal().x());
274  return (this->S())*c;
275 }
276 //---------------------------------------------------------------------------
277 double a_face::Sy() const
278 {
279  double c = fabs(this->normal().y());
280  return (this->S())*c;
281 }
282 //---------------------------------------------------------------------------
283 double a_face::Sz() const
284 {
285  double c = fabs(this->normal().z());
286  return (this->S())*c;
287 }
288 //---------------------------------------------------------------------------
289 a_point a_face::v(const int i) const
290 {
291  return (*(block_->pos())) * (*(this->vl(i)));
292 }
293 //---------------------------------------------------------------------------
294 int a_face::rv(const int i) const
295 {
296  if ((i<0)||(i>r_vertices_.size()-1))
297  return -1;
298  return r_vertices_[i];
299 }
300 //---------------------------------------------------------------------------
301 a_point * a_face::vl(const int i)
302 {
303  return block_->v(this->rv(i));
304 }
305 //---------------------------------------------------------------------------
306 a_point * a_face::vl(const int i) const
307 {
308  return block_->v(this->rv(i));
309 }
310 //---------------------------------------------------------------------------
311 a_point a_face::c() const
312 {
313  return (*block_->pos())*this->cl();
314 }
315 //---------------------------------------------------------------------------
316 void a_face::f(const a_point& f)
317 {
318  a_point c = this->c();
319  f_->set(c,f);
320 }
321 //---------------------------------------------------------------------------
322 void a_face::f(const double fx, const double fy, const double fz)
323 {
324  a_point f(fx,fy,fz);
325  this->f(f);
326 }
327 //---------------------------------------------------------------------------
328 double a_face::N() const
329 {
330  a_point f = f_->p1();
331  return f*this->normal();
332 }
333 //---------------------------------------------------------------------------
334 double a_face::N(const a_wrench& fe) const
335 {
336  a_point f = fe.p1();
337  return f*this->normal();
338 }
339 //---------------------------------------------------------------------------
340 double a_face::Qx() const
341 {
342  a_point f = f_->p1();
343  return -f*this->nx();
344 }
345 //---------------------------------------------------------------------------
346 double a_face::Qy() const
347 {
348  a_point f = f_->p1();
349  return f*this->ny();
350 }
351 //---------------------------------------------------------------------------
352 double a_face::Mt() const
353 {
354  a_point m = f_->M();
355  return m*this->normal();
356 }
357 //---------------------------------------------------------------------------
358 double a_face::Mx() const
359 {
360  a_point m = f_->M();
361  m -= cross(this->c(),f_->F());
362  return m*this->nx();
363 }
364 //---------------------------------------------------------------------------
365 double a_face::Mx(const a_wrench& f) const
366 {
367  a_point m = f.M();
368  m -= cross(this->c(),f.F());
369  return m*this->nx();
370 }
371 //---------------------------------------------------------------------------
372 double a_face::My() const
373 {
374  a_point m = f_->M();
375  m -= cross(this->c(),f_->F());
376  return m*this->ny();
377 }
378 //---------------------------------------------------------------------------
379 double a_face::My(const a_wrench& f) const
380 {
381  a_point m = f.M();
382  m -= cross(this->c(),f.F());
383  return m*this->ny();
384 }
385 //---------------------------------------------------------------------------
386 double a_face::ax() const
387 {
388  double n = this->N();
389  double qx = this->Qx();
390  return atan2(-qx,-n);
391 }
392 //---------------------------------------------------------------------------
393 double a_face::ay() const
394 {
395  double n = this->N();
396  double qy = this->Qx();
397  return atan2(-qy,-n);
398 }
399 //---------------------------------------------------------------------------
400 a_point a_face::x() const
401 {
402  a_point c = this->c();
403  double N = this->N();
404  double Mx = this->Mx();
405  double My = this->My();
406  double x = 0.;
407  double y = 0.;
408  if (fabs(N)>verysmall)
409  {
410  x = -My/N;
411  y = Mx/N;
412  }
413  return c+x*this->nx()+y*this->ny();
414 }
415 //---------------------------------------------------------------------------
416 a_point a_face::x(const a_wrench& f) const
417 {
418  a_point c = this->c();
419  double N = this->N(f);
420  double Mx = this->Mx(f);
421  double My = this->My(f);
422  double x = 0.;
423  double y = 0.;
424  if (fabs(N)>verysmall)
425  {
426  x = -My/N;
427  y = Mx/N;
428  }
429  return c+x*this->nx()+y*this->ny();
430 }
431 //---------------------------------------------------------------------------
432 double a_face::exx() const
433 {
434  a_point x = this->x()-this->c();
435  a_point d = this->nx();
436  return d*x;
437 }
438 //---------------------------------------------------------------------------
439 double a_face::exx(const a_wrench& f) const
440 {
441  a_point x = this->x(f)-this->c();
442  a_point d = this->nx();
443  return d*x;
444 }
445 //---------------------------------------------------------------------------
446 double a_face::exy() const
447 {
448  a_point x = this->x()-this->c();
449  a_point d = this->ny();
450  return d*x;
451 }
452 //---------------------------------------------------------------------------
453 double a_face::exy(const a_wrench& f) const
454 {
455  a_point x = this->x(f)-this->c();
456  a_point d = this->ny();
457  return d*x;
458 }
459 //---------------------------------------------------------------------------
460 double a_face::exn() const
461 {
462  a_point x = this->x()-this->c();
463  a_point d = this->normal();
464  return d*x;
465 }
466 //---------------------------------------------------------------------------
468 {
469  if (lface_ == 0)
470  return 0;
471  else
472  return lface_->block();
473 }
474 //---------------------------------------------------------------------------
475 a_point a_face::hinge() const
476 {
477  a_point n1 = this->normal();
478  a_face * f2 = this->lface();
479  if (f2==0)
480  return a_point(0,0,0);
481  a_point n2 = f2->normal();
482  //takes care of numerical errors
483  double v = -n1*n2;
484  if (v>1.) v=1.;
485  if (v<-1.) v=-1.;
486  double angle = acos(v);
487  a_point n = cross(n1,-n2);
488  return n*angle;
489 }
490 //***************************************************************************
491 //---------------------------------------------------------------------------
492 void a_face::read(std::istream &in)
493 {
494  int nv;
495  in >> nv;
496  r_vertices_.clear();
497  for (int i=0; i<nv; i++)
498  {
499  int ref;
500  in >> ref;
501  r_vertices_.push_back(ref);
502  }
503 }
504 //---------------------------------------------------------------------------
505 void a_face::write(std::ostream &o) const
506 {
507  o << this->nv() << " ";
508  for (int i=0; i<this->nv(); i++)
509  o << this->rv(i) << " ";
510  o << std::endl;
511 }
512 //-operator>>----------------------------------------------------------------
513 std::istream& operator>> (std::istream& in, a_face& f)
514 {
515  f.read(in);
516  return in;
517 }
518 //-operator<<----------------------------------------------------------------
519 std::ostream& operator<< (std::ostream& o, const a_face& f)
520 {
521  f.write(o);
522  return o;
523 }
524 
std::istream & operator>>(std::istream &in, a_face &f)
Definition: a_face.cxx:513
const double verysmall
Definition: a_face.cxx:21
std::ostream & operator<<(std::ostream &o, const a_face &f)
Definition: a_face.cxx:519
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
Definition: a_face.h:33
virtual a_point normal() const =0
normal to the face (in world coordinate)
virtual double Mt() const
get torque on the face
Definition: a_face.cxx:352
virtual double Qy() const
get shear force on the face
Definition: a_face.cxx:346
a_face * lface() const
get connected face
Definition: a_face.h:155
a_wrench * f_
force on the face
Definition: a_face.h:193
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
virtual double dyM() const
distance from center to max y
Definition: a_face.cxx:151
virtual a_point nx() const =0
direction of face (in world coordinate)
virtual double Qx() const
get shear force on the face
Definition: a_face.cxx:340
virtual void read(std::istream &i)
Definition: a_face.cxx:492
virtual a_point normale(const unsigned short i)
return the edge normal
Definition: a_face.cxx:187
int rv(const int i) const
get vertex reference
Definition: a_face.cxx:294
a_point hinge() const
hinge opening: rotation vector
Definition: a_face.cxx:475
double dy() const
Definition: a_face.cxx:182
virtual ~a_face()
Definition: a_face.cxx:41
bool ok() const
check if forces on face are acceptable
Definition: a_face.cxx:245
bool in() const
face is connected to other faces, inside the structure
Definition: a_face.h:159
double exy() const
excentricity in y direction
Definition: a_face.cxx:446
virtual void clear()
set force to 0
Definition: a_face.cxx:48
int nv() const
get number of vertices
Definition: a_face.h:41
a_point c() const
centre of mass (in world coordinate)
Definition: a_face.cxx:311
virtual double Mx() const
get torque on the face
Definition: a_face.cxx:358
virtual a_point x() const
application point of f on face
Definition: a_face.cxx:400
void deform(const unsigned short &i, const double &val)
slide a given edge
Definition: a_face.cxx:228
a_point vc(const int i) const
vertex (relative to centre of gravity)
Definition: a_face.cxx:119
static const std::string help()
get information about the class
Definition: a_face.cxx:54
double ay() const
get angle of incidence in yn plane
Definition: a_face.cxx:393
virtual void write(std::ostream &o) const
Definition: a_face.cxx:505
double Sx() const
projection of surface perp to x (in world coordinate)
Definition: a_face.cxx:271
double dxm() const
distance from center to min x
Definition: a_face.cxx:138
double Sy() const
projection of surface perp to y (in world coordinate)
Definition: a_face.cxx:277
double dx() const
Definition: a_face.cxx:177
double exn() const
excentricity in normal direction (should be 0)
Definition: a_face.cxx:460
virtual double S() const =0
Surface.
a_point * vl(const int i)
get vertex (in local coordinate)
Definition: a_face.cxx:301
virtual double N() const
get normal force on the face
Definition: a_face.cxx:328
virtual a_point point(const double &u, const double &v=0.) const
get point on face given excentricities
Definition: a_face.cxx:212
a_point v(const int i) const
get vertex (in world coordinate)
Definition: a_face.cxx:289
virtual double My() const
get torque on the face
Definition: a_face.cxx:372
double ax() const
get angle of incidence in xn plane
Definition: a_face.cxx:386
double Sz() const
projection of surface perp to z (in world coordinate)
Definition: a_face.cxx:283
double dxM() const
distance from center to max x
Definition: a_face.cxx:124
a_wrench f() const
get force on the face
Definition: a_face.h:141
a_face()
Definition: a_face.cxx:24
bool f_original_
Definition: a_face.h:194
a_fcriteria * criteria_
resistance criteria
Definition: a_face.h:198
virtual a_point ny() const =0
normal to the vertices of the block (in world coordinate)
virtual double dym() const
distance from center to min y
Definition: a_face.cxx:164
a_block * lblock() const
get connected block
Definition: a_face.cxx:467
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
double penalty() const
penalty value used for optimization
Definition: a_face.cxx:254
virtual a_point cl() const =0
centre of mass (in local system)
a_block * block()
get block
Definition: a_face.h:49
virtual double penalty(const a_face *f) const
penalty value used in minimisation
Definition: a_fcriteria.h:35
virtual bool ok(const a_face *f) const
return true if forces on the face are acceptable (derived class makes it interesting....
Definition: a_fcriteria.h:33
a_point p1() const
Definition: a_plucker.h:41
a wrench class
Definition: a_wrench.h:30
a_point M() const
torque
Definition: a_wrench.h:59
void set(const a_point &p, a_point f, double m=0)
apply a force f at p, possibly with a moment having same direction
Definition: a_wrench.cxx:68
a_point F() const
force
Definition: a_wrench.h:51