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

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

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
395 {
396  //check if particle overlaps
397  distance = getDistance(p.getPosition());
398  //return if distance is large, or particle has too much overlap
399  if (fabs(distance) >= interactionRadius)
400  return false;
401 
402  //Contact radius squared
403  Mdouble allowedDistanceSquared = interactionRadius * interactionRadius - distance * distance;
404  int touchingEdge = -1;
405  Vec3D* touchingVertex = nullptr;
406  //loop through edges to find out if there is a contact with face, edge, vertex, or neither.
407  for (unsigned i = 0; i < 3; i++)
408  {
409  //distance from the edge
410  Mdouble edgeDistance = Vec3D::dot(edgeNormal[i], *vertex[i] - p.getPosition());
411  if (edgeDistance <= 0) //if in contact with the face
412  continue;
413  if (edgeDistance * edgeDistance >= allowedDistanceSquared) //if not in contact with anything
414  return false;
415  //this point is only reached if in contact, but not with the face
416  //if edge is convex, treat as face, not edge contact
417  bool convex = (neighbor[i] && ((neighbor[i]->getDistance(p.getPosition()) < 0) ? (
418  Vec3D::dot(neighbor[i]->normal, edgeNormal[i]) > 1e-12) : (
419  Vec3D::dot(neighbor[i]->normal, edgeNormal[i]) < -1e-12)));
420  if (touchingEdge == -1)
421  {
422  //edge or vertex contact (depending if more edges are found)
423  touchingEdge = i;
424  }
425  else
426  {
427  //vertex contact
428  touchingVertex = vertex[(i == 2 && touchingEdge == 0) ? 0 : i];
429  }
430  //if (!convex) continue;
431  //do not compute if neighbor exists and has lower index or face contact.
432  if (neighbor[i] > this)
433  { //if neighbor has higher index
434  if (neighbor[i]->neighbor[0] == this)
435  {
436  edgeDistance = Vec3D::dot(neighbor[i]->edgeNormal[0], *vertex[i] - p.getPosition());
437  }
438  else if (neighbor[i]->neighbor[1] == this)
439  {
440  edgeDistance = Vec3D::dot(neighbor[i]->edgeNormal[1], *vertex[i] - p.getPosition());
441  }
442  else
443  { //if (neighbor[i]->neighbor[2]==this)
444  edgeDistance = Vec3D::dot(neighbor[i]->edgeNormal[2], *vertex[i] - p.getPosition());
445  }
446  if (edgeDistance <= 0 && !convex) //if neighbor has face contact, ignore the edge contact
447  return false;
448  }
449  else if (neighbor[i] && !convex)
450  {
451  return false;
452  }
453  }
454 
455 
456  //check if convex neighbours are overlapping as well
457  if (touchingVertex)
458  { //vertex contact
459  normal_return = *touchingVertex - p.getPosition();
460  distance = Vec3D::getLength(normal_return);
461  normal_return /= distance;
462  //return false;
463  //logger(INFO,"vertex contact");
464  }
465  else if (touchingEdge == -1)
466  { //face contact
467  if (distance >= 0)
468  { // front face contact
469  normal_return = normal;
470  }
471  else
472  { // back face contact
473  normal_return = -normal;
474  distance = -distance;
475  }
476  //return false;
477  //logger(INFO,"face contact");
478  }
479  else
480  { //edge contact
481  Vec3D VP = *vertex[touchingEdge] - p.getPosition();
482  Vec3D VW = *vertex[touchingEdge] - *vertex[(touchingEdge == 2) ? 0 : (touchingEdge + 1)];
483  normal_return = VP - Vec3D::dot(VP, VW) / Vec3D::getLengthSquared(VW) * VW;
484  distance = Vec3D::getLength(normal_return);
485  normal_return /= distance;
486  //return false;
487  //logger(INFO,"edge contact at c=% p=% d=% n=%",p.getPosition() + distance * normal_return,p.getPosition(), distance, normal_return);
488  }
489  return true;
490 }
double Mdouble
Definition: GeneralDefine.h:34
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Definition: BaseInteractable.h:218
Definition: Vector.h:51
Mdouble getLengthSquared() const
Calculates the squared length of this Vec3D: .
Definition: Vector.cc:184
Mdouble getLength() const
Calculates the length of this Vec3D: .
Definition: Vector.cc:320
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51
Mdouble getDistance(const Vec3D &otherPosition) const
computes the signed distance to the face in normal direction
Definition: TriangulatedWall.cc:385
std::array< Face *, 3 > neighbor
For each edge, stores the neighboring face (nullptr if none)
Definition: TriangulatedWall.h:64
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:66

References Vec3D::dot(), Vec3D::getLength(), Vec3D::getLengthSquared(), BaseInteractable::getPosition(), and constants::i.

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(), TriangulatedWall::readVTK(), and TriangulatedWall::set().


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