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::Logger > | m_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

  rCurrent | is the parametric location on segment p at the start of the current time interval
  rNext | is the parametric location on segment p at the end of the current time interval
  sCurrent | is the parametric location on segment q at the start of the current time interval
  sNext | is the parametric location on segment q at the end of the current time interval
  nCurrent | is the normal of p x q at the start of the current time interval
  nNext | is 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

  pt0Positions | are the segment endpoints for the first segment at time t=0.
  pt1Positions | are the segment endpoints for the first segment at time t=1.
  qt0Positions | are the segment endpoints for the second segment at time t=0.
  qt1Positions | are the segment endpoints for the second segment at time t=1.
  thicknessEpsilon | spatial nearness criteria for declaring a contact.
  timePrecisionEpsilon | time 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

  pt0Positions | are the segment endpoints for the first segment at time t=0.
  pt1Positions | are the segment endpoints for the first segment at time t=1.
  qt0Positions | are the segment endpoints for the second segment at time t=0.
  qt1Positions | are the segment endpoints for the second segment at time t=1.
  thicknessP | radius of segment p.
  thicknessQ | radius of segment q.
  timePrecisionEpsilon | time 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

  pT0 | are the segment endpoints for the first segment at time t=0.
  pT1 | are the segment endpoints for the first segment at time t=1.
  qT0 | are the segment endpoints for the second segment at time t=0.
  qT1 | are the segment endpoints for the second segment at time t=1.
  thicknessP | radius of segment p.
  thicknessQ | radius of segment q.
  timePrecisionEpsilon | time 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

  pT0 | are the segment endpoints for the first segment at time t=0.
  pT1 | are the segment endpoints for the first segment at time t=1.
  qT0 | are the segment endpoints for the second segment at time t=0.
  qT1 | are the segment endpoints for the second segment at time t=1.
  a | parametric starting point of the interval of interest.
  b | parametric ending point of the interval of interest.
  thicknessP | radius of segment p.
  thicknessQ | radius of segment q.
  timePrecisionEpsilon | time 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]
  depth | recursion 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

  state | an encapsulation of the segment locations, movements, and detection parameters.
  a | parametric starting point of the interval of interest.
  b | parametric 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]
  depth | recursion 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

  pT0 | are the segment endpoints for the first segment at time t=0.
  pT1 | are the segment endpoints for the first segment at time t=1.
  qT0 | are the segment endpoints for the second segment at time t=0.
  qT1 | are the segment endpoints for the second segment at time t=1.
  a | parametric starting point of the interval of interest.
  b | parametric ending point of the interval of interest.
  thicknessP | radius of segment p.
  thicknessQ | radius of segment q.
  timePrecisionEpsilon | time 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]
  depth | recursion 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

  t0 | segment at time 0
  t1 | segment at time 1
  epsilon | threshold 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:

- SurgSim/Collision/SegmentSegmentCcdMovingContact.h
- SurgSim/Collision/SegmentSegmentCcdMovingContact.cpp