Public Member Functions | Static Public Attributes | Protected Member Functions | Private Member Functions | Private Attributes | List of all members
SurgSim::Collision::SegmentSegmentCcdMovingContact Class Reference

SegmentSegmentCcdMovingContact computes the self collisions among a SegmentMesh under motion at two time points parametrized over the time interval [0,1]. More...

#include <SurgSim/Collision/SegmentSegmentCcdMovingContact.h>

Public Member Functions

 SegmentSegmentCcdMovingContact ()
 Constructor. More...
 
bool collideMovingSegmentSegment (const std::array< Math::Vector3d, 2 > &pt0Positions, const std::array< Math::Vector3d, 2 > &pt1Positions, const std::array< Math::Vector3d, 2 > &qt0Positions, const std::array< Math::Vector3d, 2 > &qt1Positions, double thicknessEpsilon, double timePrecisionEpsilon, double *t, double *r, double *s, Math::Vector3d *pToQDir)
 Calculate if, where, and when the segments p and q collide in the interval from t = 0 to t = 1 for "zero" thickness segments. More...
 
bool collideMovingSegmentSegment (const std::array< Math::Vector3d, 2 > &pt0Positions, const std::array< Math::Vector3d, 2 > &pt1Positions, const std::array< Math::Vector3d, 2 > &qt0Positions, const std::array< Math::Vector3d, 2 > &qt1Positions, double thicknessP, double thicknessQ, double timePrecisionEpsilon, double *t, double *r, double *s, Math::Vector3d *pToQDir)
 Calculate if, where, and when the segments p and q collide in the interval from t = 0 to t = 1 for thick segments. More...
 

Static Public Attributes

static const int SUB_POINTS_PARALLEL_CASE = 5
 
static const int SUB_POINTS_COPLANAR_CASE = 10
 

Protected Member Functions

bool collideSegmentSegmentBaseCase (const std::array< Math::Vector3d, 2 > &pT0, const std::array< Math::Vector3d, 2 > &pT1, const std::array< Math::Vector3d, 2 > &qT0, const std::array< Math::Vector3d, 2 > &qT1, double thicknessP, double thicknessQ, double timePrecisionEpsilon, double *t, double *r, double *s)
 Manage the collision of moving segments as a series of cases based on the segment relationships over the moving interval. More...
 
bool collideSegmentSegmentParallelCase (const std::array< Math::Vector3d, 2 > &pT0, const std::array< Math::Vector3d, 2 > &pT1, const std::array< Math::Vector3d, 2 > &qT0, const std::array< Math::Vector3d, 2 > &qT1, double a, double b, double thicknessP, double thicknessQ, double timePrecisionEpsilon, double *t, double *r, double *s, int depth=0)
 Manage the specific case of detecting collisions between segments p and q which are parallel throughout the parametric time interval of interest [a, b]. More...
 
bool collideSegmentSegmentCoplanarCase (const std::array< Math::Vector3d, 2 > &pT0, const std::array< Math::Vector3d, 2 > &pT1, const std::array< Math::Vector3d, 2 > &qT0, const std::array< Math::Vector3d, 2 > &qT1, double a, double b, double timePrecisionEpsilon, double thicknessP, double thicknessQ, double *t, double *r, double *s, int depth=0)
 Manage the specific case of detecting collisions between segments p and q which are coplanar throughout the parametric time interval of interest [a, b]. More...
 
bool collideSegmentSegmentGeneralCase (const SegmentSegmentCcdIntervalCheck &state, double a, double b, double *t, double *r, double *s, int depth=0)
 Manage the general case of detecting collisions between segments p and q over the parametric time interval [a, b] when no special spatial relationships can be observed that improve performance. More...
 
void normalizeSegmentsConsistently (Math::Vector3d *t0, Math::Vector3d *t1, double epsilon) const
 Safely normalize segments t0 and t1 consistently with each other. More...
 

Private Member Functions

bool checkForCoplanarContactWithinInterval (double rCurrent, double rNext, double sCurrent, double sNext, const Math::Vector3d &nCurrent, const Math::Vector3d &nNext) const
 Utility routine to perform a series of checks to determine if a collision is likely within an interval. More...
 

Private Attributes

const double m_distanceEpsilon
 Minimum distance precision epsilon used in continuous collision detection. More...
 
Collision::SegmentSegmentCcdStaticContact m_staticTest
 Utility class for testing interval boundary collisions. More...
 
std::shared_ptr< SurgSim::Framework::Loggerm_logger
 Logger. More...
 

Detailed Description

SegmentSegmentCcdMovingContact computes the self collisions among a SegmentMesh under motion at two time points parametrized over the time interval [0,1].

An initial phase uses the AABB tree to select a set of potentially colliding segments from the SegmentMesh. For each of these candidate segment pairs, the goal is to determine the point of earliest contact should any exist.

At the highest level the actual collision detection of candidate segment pairs is a two phase algorithm. First determine if there is contact at the start of an interval and report the contact if found. If no contact is found at the start, subdivide the interval, determine which of the resulting candidate subintervals may have collisions, and then recursively check those promising subintervals. Note that a simple algorithm based on interval arithmetic (including the Interval, LinearMotion and Polynomial interval classes) allows for a quick determination of promising subintervals allowing many of the subintervals to be pruned during the subdivision step without forcing the recursion to bottom out.

See also
Interval, LinearMotion, Polynomial, SegmentSegmentCcdIntervalCheck

Constructor & Destructor Documentation

◆ SegmentSegmentCcdMovingContact()

SurgSim::Collision::SegmentSegmentCcdMovingContact::SegmentSegmentCcdMovingContact ( )

Constructor.

Member Function Documentation

◆ checkForCoplanarContactWithinInterval()

bool SurgSim::Collision::SegmentSegmentCcdMovingContact::checkForCoplanarContactWithinInterval ( double  rCurrent,
double  rNext,
double  sCurrent,
double  sNext,
const Math::Vector3d nCurrent,
const Math::Vector3d nNext 
) const
private

Utility routine to perform a series of checks to determine if a collision is likely within an interval.

The checks seek to determine if two coplanar segments could have been out of contact at the start of an interval, and then moved through a contact and back away. Among the values checked are the normals because a change in normal direction of p X q indicates that p is now on the other side of q. Other checks are made for flipping segments, etc.

Parameters
rCurrentis the parametric location on segment p at the start of the current time interval
rNextis the parametric location on segment p at the end of the current time interval
sCurrentis the parametric location on segment q at the start of the current time interval
sNextis the parametric location on segment q at the end of the current time interval
nCurrentis the normal of p x q at the start of the current time interval
nNextis the normal of p x q at the current time point
Returns
true if the check indicates a collision may be possible for coplanar segments p and q at the current time interval.

◆ collideMovingSegmentSegment() [1/2]

bool SurgSim::Collision::SegmentSegmentCcdMovingContact::collideMovingSegmentSegment ( const std::array< Math::Vector3d, 2 > &  pt0Positions,
const std::array< Math::Vector3d, 2 > &  pt1Positions,
const std::array< Math::Vector3d, 2 > &  qt0Positions,
const std::array< Math::Vector3d, 2 > &  qt1Positions,
double  thicknessEpsilon,
double  timePrecisionEpsilon,
double *  t,
double *  r,
double *  s,
Math::Vector3d pToQDir 
)

Calculate if, where, and when the segments p and q collide in the interval from t = 0 to t = 1 for "zero" thickness segments.

Parameters
pt0Positionsare the segment endpoints for the first segment at time t=0.
pt1Positionsare the segment endpoints for the first segment at time t=1.
qt0Positionsare the segment endpoints for the second segment at time t=0.
qt1Positionsare the segment endpoints for the second segment at time t=1.
thicknessEpsilonspatial nearness criteria for declaring a contact.
timePrecisionEpsilontime nearness criteria for declaring a contact.
t[out] parametric location of the collision along the time axes in the interval [0, 1]
r[out] parametric location of the collision along p in the interval [0, 1]
s[out] parametric location of the collision along q in the interval [0, 1]
pToQDir[out] direction from the contact point on p to the contact point on q
Returns
true if p and q collide in interval [0, 1]

◆ collideMovingSegmentSegment() [2/2]

bool SurgSim::Collision::SegmentSegmentCcdMovingContact::collideMovingSegmentSegment ( const std::array< Math::Vector3d, 2 > &  pt0Positions,
const std::array< Math::Vector3d, 2 > &  pt1Positions,
const std::array< Math::Vector3d, 2 > &  qt0Positions,
const std::array< Math::Vector3d, 2 > &  qt1Positions,
double  thicknessP,
double  thicknessQ,
double  timePrecisionEpsilon,
double *  t,
double *  r,
double *  s,
Math::Vector3d pToQDir 
)

Calculate if, where, and when the segments p and q collide in the interval from t = 0 to t = 1 for thick segments.

Parameters
pt0Positionsare the segment endpoints for the first segment at time t=0.
pt1Positionsare the segment endpoints for the first segment at time t=1.
qt0Positionsare the segment endpoints for the second segment at time t=0.
qt1Positionsare the segment endpoints for the second segment at time t=1.
thicknessPradius of segment p.
thicknessQradius of segment q.
timePrecisionEpsilontime nearness criteria for declaring a contact.
t[out] parametric location of the collision along the time axes in the interval [0, 1]
r[out] parametric location of the collision along p in the interval [0, 1]
s[out] parametric location of the collision along q in the interval [0, 1]
pToQDir[out] direction from the contact point on p to the contact point on q at time t
Returns
true if p and q collide in interval [0, 1]

◆ collideSegmentSegmentBaseCase()

bool SurgSim::Collision::SegmentSegmentCcdMovingContact::collideSegmentSegmentBaseCase ( const std::array< Math::Vector3d, 2 > &  pT0,
const std::array< Math::Vector3d, 2 > &  pT1,
const std::array< Math::Vector3d, 2 > &  qT0,
const std::array< Math::Vector3d, 2 > &  qT1,
double  thicknessP,
double  thicknessQ,
double  timePrecisionEpsilon,
double *  t,
double *  r,
double *  s 
)
protected

Manage the collision of moving segments as a series of cases based on the segment relationships over the moving interval.

Parameters
pT0are the segment endpoints for the first segment at time t=0.
pT1are the segment endpoints for the first segment at time t=1.
qT0are the segment endpoints for the second segment at time t=0.
qT1are the segment endpoints for the second segment at time t=1.
thicknessPradius of segment p.
thicknessQradius of segment q.
timePrecisionEpsilontime nearness criteria for declaring a contact.
t[out] parametric location of the collision along the time axes in the interval [0, 1]
r[out] parametric location of the collision along p in the interval [0, 1]
s[out] parametric location of the collision along q in the interval [0, 1]
Returns
true if p and q collide in interval [0, 1]

◆ collideSegmentSegmentCoplanarCase()

bool SurgSim::Collision::SegmentSegmentCcdMovingContact::collideSegmentSegmentCoplanarCase ( const std::array< Math::Vector3d, 2 > &  pT0,
const std::array< Math::Vector3d, 2 > &  pT1,
const std::array< Math::Vector3d, 2 > &  qT0,
const std::array< Math::Vector3d, 2 > &  qT1,
double  a,
double  b,
double  timePrecisionEpsilon,
double  thicknessP,
double  thicknessQ,
double *  t,
double *  r,
double *  s,
int  depth = 0 
)
protected

Manage the specific case of detecting collisions between segments p and q which are coplanar throughout the parametric time interval of interest [a, b].

Parameters
pT0are the segment endpoints for the first segment at time t=0.
pT1are the segment endpoints for the first segment at time t=1.
qT0are the segment endpoints for the second segment at time t=0.
qT1are the segment endpoints for the second segment at time t=1.
aparametric starting point of the interval of interest.
bparametric ending point of the interval of interest.
thicknessPradius of segment p.
thicknessQradius of segment q.
timePrecisionEpsilontime nearness criteria for declaring a contact.
t[out] parametric location of the collision along the time axes in the interval [0, 1]
r[in/out] parametric location of the collision along p in the interval [0, 1]
s[in/out] parametric location of the collision along q in the interval [0, 1]
depthrecursion depth.
Returns
true if p and q collide in interval [a, b]

◆ collideSegmentSegmentGeneralCase()

bool SurgSim::Collision::SegmentSegmentCcdMovingContact::collideSegmentSegmentGeneralCase ( const SegmentSegmentCcdIntervalCheck state,
double  a,
double  b,
double *  t,
double *  r,
double *  s,
int  depth = 0 
)
protected

Manage the general case of detecting collisions between segments p and q over the parametric time interval [a, b] when no special spatial relationships can be observed that improve performance.

Parameters
statean encapsulation of the segment locations, movements, and detection parameters.
aparametric starting point of the interval of interest.
bparametric ending point of the interval of interest.
t[out] parametric location of the collision along the time axes in the interval [0, 1]
r[out] parametric location of the collision along p in the interval [0, 1]
s[out] parametric location of the collision along q in the interval [0, 1]
depthrecursion depth.
Returns
true if p and q collide in interval [a, b]

◆ collideSegmentSegmentParallelCase()

bool SurgSim::Collision::SegmentSegmentCcdMovingContact::collideSegmentSegmentParallelCase ( const std::array< Math::Vector3d, 2 > &  pT0,
const std::array< Math::Vector3d, 2 > &  pT1,
const std::array< Math::Vector3d, 2 > &  qT0,
const std::array< Math::Vector3d, 2 > &  qT1,
double  a,
double  b,
double  thicknessP,
double  thicknessQ,
double  timePrecisionEpsilon,
double *  t,
double *  r,
double *  s,
int  depth = 0 
)
protected

Manage the specific case of detecting collisions between segments p and q which are parallel throughout the parametric time interval of interest [a, b].

Parameters
pT0are the segment endpoints for the first segment at time t=0.
pT1are the segment endpoints for the first segment at time t=1.
qT0are the segment endpoints for the second segment at time t=0.
qT1are the segment endpoints for the second segment at time t=1.
aparametric starting point of the interval of interest.
bparametric ending point of the interval of interest.
thicknessPradius of segment p.
thicknessQradius of segment q.
timePrecisionEpsilontime nearness criteria for declaring a contact.
t[out] parametric location of the collision along the time axes in the interval [0, 1]
r[in/out] parametric location of the collision along p in the interval [0, 1]
s[in/out] parametric location of the collision along q in the interval [0, 1]
depthrecursion depth.
Returns
true if p and q collide in interval [a, b]

◆ normalizeSegmentsConsistently()

void SurgSim::Collision::SegmentSegmentCcdMovingContact::normalizeSegmentsConsistently ( Math::Vector3d t0,
Math::Vector3d t1,
double  epsilon 
) const
protected

Safely normalize segments t0 and t1 consistently with each other.

Under the assumption that they both represent the same segment at two different time points. Ensure that for cases where the segment is too small at one or both time points (i.e. they essentially degenerate to a point) that we make an intelligent choice.

Parameters
t0segment at time 0
t1segment at time 1
epsilonthreshold for valid normalization value.

Member Data Documentation

◆ m_distanceEpsilon

const double SurgSim::Collision::SegmentSegmentCcdMovingContact::m_distanceEpsilon
private

Minimum distance precision epsilon used in continuous collision detection.

◆ m_logger

std::shared_ptr<SurgSim::Framework::Logger> SurgSim::Collision::SegmentSegmentCcdMovingContact::m_logger
private

Logger.

◆ m_staticTest

Collision::SegmentSegmentCcdStaticContact SurgSim::Collision::SegmentSegmentCcdMovingContact::m_staticTest
private

Utility class for testing interval boundary collisions.

◆ SUB_POINTS_COPLANAR_CASE

const int SurgSim::Collision::SegmentSegmentCcdMovingContact::SUB_POINTS_COPLANAR_CASE = 10
static

◆ SUB_POINTS_PARALLEL_CASE

const int SurgSim::Collision::SegmentSegmentCcdMovingContact::SUB_POINTS_PARALLEL_CASE = 5
static

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