MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TriangulatedWall::Face Struct Reference

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

#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) 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.

Definition at line 59 of file TriangulatedWall.h.

Member Function Documentation

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

computes the signed distance to the face in normal direction

Definition at line 318 of file TriangulatedWall.cc.

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

319 {
320  return Vec3D::dot(*vertex[0] - otherPosition, normal);
321 }
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:167
std::array< Vec3D *, 3 > vertex
defines the three vertices (anticlockwise direction around the normal)
Vec3D normal
face normal (vertices are ordered anticlockwise direction around the normal)
bool TriangulatedWall::Face::getDistanceAndNormal ( const BaseParticle p,
Mdouble distance,
Vec3D normal_return 
) 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

Definition at line 327 of file TriangulatedWall.cc.

References Vec3D::dot(), Vec3D::getLength(), Vec3D::getLengthSquared(), BaseInteractable::getPosition(), and BaseParticle::getWallInteractionRadius().

328 {
329  //check if particle overlaps
330  distance = getDistance(p.getPosition());
331  //return if distance is large, or particle has too much overlap
332  Mdouble interactionRadius = p.getWallInteractionRadius();
333  if (fabs(distance) >= interactionRadius)
334  return false;
335 
336  //Contact radius squared
337  Mdouble allowedDistanceSquared = interactionRadius*interactionRadius-distance*distance;
338  int touchingEdge = -1;
339  Vec3D* touchingVertex = nullptr;
340  //loop through edges to find out if there is a contact with face, edge, vertex, or neither.
341  for (unsigned i=0; i<3; i++)
342  {
343  //distance from the edge
344  Mdouble edgeDistance = Vec3D::dot(edgeNormal[i], *vertex[i] - p.getPosition());
345  if (edgeDistance<=0) //if in contact with the face
346  continue;
347  if (edgeDistance * edgeDistance >= allowedDistanceSquared) //if not in contact with anything
348  return false;
349  //this point is only reached if in contact, but not with the face
350  //if edge is convex, treat as face, not edge contact
351  bool convex = (neighbor[i] && ((neighbor[i]->getDistance(p.getPosition())<0)?(Vec3D::dot(neighbor[i]->normal,edgeNormal[i])>1e-12):(Vec3D::dot(neighbor[i]->normal,edgeNormal[i])<-1e-12)));
352  if (touchingEdge==-1) {
353  //edge or vertex contact (depending if more edges are found)
354  touchingEdge = i;
355  } else {
356  //vertex contact
357  touchingVertex = vertex[(i==2 && touchingEdge==0)?0:i];
358  }
359  //if (!convex) continue;
360  //do not compute if neighbor exists and has lower index or face contact.
361  if (neighbor[i] > this){ //if neighbor has higher index
362  if (neighbor[i]->neighbor[0]==this) {
363  edgeDistance = Vec3D::dot(neighbor[i]->edgeNormal[0], *vertex[i] - p.getPosition());
364  } else if (neighbor[i]->neighbor[1]==this) {
365  edgeDistance = Vec3D::dot(neighbor[i]->edgeNormal[1], *vertex[i] - p.getPosition());
366  } else { //if (neighbor[i]->neighbor[2]==this)
367  edgeDistance = Vec3D::dot(neighbor[i]->edgeNormal[2], *vertex[i] - p.getPosition());
368  }
369  if (edgeDistance<=0 && !convex) //if neighbor has face contact, ignore the edge contact
370  return false;
371  } else if (neighbor[i] && !convex) {
372  return false;
373  }
374  }
375 
376 
377  //check if convex neighbours are overlapping as well
378  if (touchingVertex) { //vertex contact
379  normal_return = *touchingVertex -p.getPosition();
380  distance = Vec3D::getLength(normal_return);
381  normal_return /= distance;
382  //return false;
383  //logger(INFO,"vertex contact");
384  } else if (touchingEdge==-1) { //face contact
385  if (distance>=0) { // front face contact
386  normal_return = normal;
387  } else { // back face contact
388  normal_return = -normal;
389  distance = -distance;
390  }
391  //return false;
392  //logger(INFO,"face contact");
393  } else { //edge contact
394  Vec3D VP = *vertex[touchingEdge] - p.getPosition();
395  Vec3D VW = *vertex[touchingEdge] - *vertex[(touchingEdge==2)?0:(touchingEdge+1)];
396  normal_return = VP - Vec3D::dot(VP, VW)/Vec3D::getLengthSquared(VW)*VW;
397  distance = Vec3D::getLength(normal_return);
398  normal_return /= distance;
399  //return false;
400  //logger(INFO,"edge contact at c=% p=% d=% n=%",p.getPosition() + distance * normal_return,p.getPosition(), distance, normal_return);
401  }
402  return true;
403 }
double Mdouble
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:167
Mdouble getLengthSquared() const
Calculates the squared length of this Vec3D: .
Definition: Vector.cc:300
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Mdouble getWallInteractionRadius() const
Returns the interaction radius for interaction with walls. See also BaseParticle::getInteractionRadiu...
std::array< Vec3D *, 3 > vertex
defines the three vertices (anticlockwise direction around the normal)
Vec3D normal
face normal (vertices are ordered anticlockwise direction around the normal)
Mdouble getLength() const
Calculates the length of this Vec3D: .
Definition: Vector.cc:403
std::array< Vec3D, 3 > edgeNormal
For each edge, stores the vector normal to the face normal and the edge direction (vector between the...
Mdouble getDistance(const Vec3D &otherPosition) const
computes the signed distance to the face in normal direction
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
std::array< Face *, 3 > neighbor
For each edge, stores the neighboring face (nullptr if none)

Member Data Documentation

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).

Definition at line 66 of file TriangulatedWall.h.

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

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

Definition at line 64 of file TriangulatedWall.h.

Vec3D TriangulatedWall::Face::normal

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

Definition at line 68 of file TriangulatedWall.h.

Referenced by getDistance().

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

defines the three vertices (anticlockwise direction around the normal)

Definition at line 62 of file TriangulatedWall.h.

Referenced by getDistance(), and TriangulatedWall::readVTK().


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