TriangulatedWall::Face Struct Reference

#include <TriangulatedWall.h>

Public Member Functions

Mdouble getDistance (const Vec3D &otherPosition) const
 computes the signed distance to the face in normal direction More...
 
bool getDistanceAndNormal (const BaseParticle &p, Mdouble &distance, Vec3D &normal_return, Mdouble interactionRadius) const
 Returns true if contact with the face exists, false if not. If contact exists, then the distance and normal is returned as well. More...
 

Public Attributes

std::array< Vec3D *, 3 > vertex
 defines the three vertices (anticlockwise direction around the normal) More...
 
std::array< Face *, 3 > neighbor = {{nullptr}}
 For each edge, stores the neighboring face (nullptr if none) More...
 
std::array< Vec3D, 3 > edgeNormal
 For each edge, stores the vector normal to the face normal and the edge direction (vector between the vertices). More...
 
Vec3D normal
 face normal (vertices are ordered anticlockwise direction around the normal) More...
 

Detailed Description

Struct used to store the properties of a face needed for contact detection.

Member Function Documentation

◆ getDistance()

Mdouble TriangulatedWall::Face::getDistance ( const Vec3D otherPosition) const

computes the signed distance to the face in normal direction

365 {
366  return Vec3D::dot(*vertex[0] - otherPosition, normal);
367 }
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:56
Vec3D normal
face normal (vertices are ordered anticlockwise direction around the normal)
Definition: TriangulatedWall.h:47
std::array< Vec3D *, 3 > vertex
defines the three vertices (anticlockwise direction around the normal)
Definition: TriangulatedWall.h:41

References Vec3D::dot(), normal, and vertex.

◆ getDistanceAndNormal()

bool TriangulatedWall::Face::getDistanceAndNormal ( const BaseParticle p,
Mdouble distance,
Vec3D normal_return,
Mdouble  interactionRadius 
) const

Returns true if contact with the face exists, false if not. If contact exists, then the distance and normal is returned as well.

check if there is contact with the face, determine if contact is with face, edge, vertex, return distance and normal; only return edge, vertex contact if neighbor face pointer is higher to avoid doubles

Todo:
make the triangle work from both sides
374 {
375  //check if particle overlaps
376  distance = getDistance(p.getPosition());
377  //return if distance is large, or particle has too much overlap
378  if (fabs(distance) >= interactionRadius)
379  return false;
380 
381  //Contact radius squared
382  Mdouble allowedDistanceSquared = interactionRadius * interactionRadius - distance * distance;
383  int touchingEdge = -1;
384  Vec3D* touchingVertex = nullptr;
385  //loop through edges to find out if there is a contact with face, edge, vertex, or neither.
386  for (unsigned i = 0; i < 3; i++)
387  {
388  //distance from the edge
389  Mdouble edgeDistance = Vec3D::dot(edgeNormal[i], *vertex[i] - p.getPosition());
390  if (edgeDistance <= 0) //if in contact with the face
391  continue;
392  if (edgeDistance * edgeDistance >= allowedDistanceSquared) //if not in contact with anything
393  return false;
394  //this point is only reached if in contact, but not with the face
395  //if edge is convex, treat as face, not edge contact
396  bool convex = (neighbor[i] && ((neighbor[i]->getDistance(p.getPosition()) < 0) ? (
397  Vec3D::dot(neighbor[i]->normal, edgeNormal[i]) > 1e-12) : (
398  Vec3D::dot(neighbor[i]->normal, edgeNormal[i]) < -1e-12)));
399  if (touchingEdge == -1)
400  {
401  //edge or vertex contact (depending if more edges are found)
402  touchingEdge = i;
403  }
404  else
405  {
406  //vertex contact
407  touchingVertex = vertex[(i == 2 && touchingEdge == 0) ? 0 : i];
408  }
409  //if (!convex) continue;
410  //do not compute if neighbor exists and has lower index or face contact.
411  if (neighbor[i] > this)
412  { //if neighbor has higher index
413  if (neighbor[i]->neighbor[0] == this)
414  {
415  edgeDistance = Vec3D::dot(neighbor[i]->edgeNormal[0], *vertex[i] - p.getPosition());
416  }
417  else if (neighbor[i]->neighbor[1] == this)
418  {
419  edgeDistance = Vec3D::dot(neighbor[i]->edgeNormal[1], *vertex[i] - p.getPosition());
420  }
421  else
422  { //if (neighbor[i]->neighbor[2]==this)
423  edgeDistance = Vec3D::dot(neighbor[i]->edgeNormal[2], *vertex[i] - p.getPosition());
424  }
425  if (edgeDistance <= 0 && !convex) //if neighbor has face contact, ignore the edge contact
426  return false;
427  }
428  else if (neighbor[i] && !convex)
429  {
430  return false;
431  }
432  }
433 
434 
435  //check if convex neighbours are overlapping as well
436  if (touchingVertex)
437  { //vertex contact
438  normal_return = *touchingVertex - p.getPosition();
439  distance = Vec3D::getLength(normal_return);
440  normal_return /= distance;
441  //return false;
442  //logger(INFO,"vertex contact");
443  }
444  else if (touchingEdge == -1)
445  { //face contact
446  if (distance >= 0)
447  { // front face contact
448  normal_return = normal;
449  }
450  else
451  { // back face contact
452  normal_return = -normal;
453  distance = -distance;
454  }
455  //return false;
456  //logger(INFO,"face contact");
457  }
458  else
459  { //edge contact
460  Vec3D VP = *vertex[touchingEdge] - p.getPosition();
461  Vec3D VW = *vertex[touchingEdge] - *vertex[(touchingEdge == 2) ? 0 : (touchingEdge + 1)];
462  normal_return = VP - Vec3D::dot(VP, VW) / Vec3D::getLengthSquared(VW) * VW;
463  distance = Vec3D::getLength(normal_return);
464  normal_return /= distance;
465  //return false;
466  //logger(INFO,"edge contact at c=% p=% d=% n=%",p.getPosition() + distance * normal_return,p.getPosition(), distance, normal_return);
467  }
468  return true;
469 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
float * p
Definition: Tutorial_Map_using.cpp:9
Definition: Kernel/Math/Vector.h:30
Mdouble getLengthSquared() const
Calculates the squared length of this Vec3D: .
Definition: Vector.cc:164
Mdouble getLength() const
Calculates the length of this Vec3D: .
Definition: Vector.cc:339
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117
Mdouble getDistance(const Vec3D &otherPosition) const
computes the signed distance to the face in normal direction
Definition: TriangulatedWall.cc:364
std::array< Face *, 3 > neighbor
For each edge, stores the neighboring face (nullptr if none)
Definition: TriangulatedWall.h:43
std::array< Vec3D, 3 > edgeNormal
For each edge, stores the vector normal to the face normal and the edge direction (vector between the...
Definition: TriangulatedWall.h:45

References Vec3D::dot(), e(), boost::multiprecision::fabs(), Vec3D::getLength(), Vec3D::getLengthSquared(), i, WallFunction::normal(), and p.

Member Data Documentation

◆ edgeNormal

std::array<Vec3D, 3> TriangulatedWall::Face::edgeNormal

For each edge, stores the vector normal to the face normal and the edge direction (vector between the vertices).

◆ neighbor

std::array<Face*, 3> TriangulatedWall::Face::neighbor = {{nullptr}}

For each edge, stores the neighboring face (nullptr if none)

◆ normal

Vec3D TriangulatedWall::Face::normal

face normal (vertices are ordered anticlockwise direction around the normal)

Referenced by getDistance().

◆ vertex

std::array<Vec3D*, 3> TriangulatedWall::Face::vertex

defines the three vertices (anticlockwise direction around the normal)

Referenced by getDistance().


The documentation for this struct was generated from the following files: