cgma
IntersectionTool Class Reference

#include <IntersectionTool.hpp>

List of all members.

Public Member Functions

 IntersectionTool (const double &tol=0.0001)
virtual ~IntersectionTool ()
virtual CubitStatus closest_points_on_segments (CubitVector &p0, CubitVector &p1, CubitVector &p2, CubitVector &p3, CubitVector &point_1, CubitVector &point_2, double &sc, double &tc)
double distance_point_line (const double point[3], const double start[3], const double end[3], double &t)
int point_on_polyline (CubitVector &pt, DLIList< CubitVector * > &pt_list, double *tol_in=NULL)
double parametric_position (const double node[3], const double pt1[3], const double pt2[3])
virtual CubitStatus initialize ()

Static Public Member Functions

static int intersect_triangle_with_ray (CubitVector &ray_origin, CubitVector &ray_direction, const CubitVector *p0, const CubitVector *p1, const CubitVector *p2, CubitVector *point, double &distance, int &edge_hit)
static int intersect_segment_with_ray (CubitVector &ray_origin, CubitVector &ray_direction, const CubitVector *p0, const CubitVector *p1, CubitVector *point, double &distance, int &point_hit, double tol=0.0)
static int intersect_point_with_ray (CubitVector &ray_origin, CubitVector &ray_direction, const CubitVector *point, double &distance, double tol=0.0)

Protected Member Functions

CubitBoolean ray_tri_test (const double start[3], const double dir[3], const double tri1[3], const double tri2[3], const double tri3[3], double &t, double &alpha, double &beta)
CubitBoolean skew_line_test (const double start1[3], const double end1[3], const double start2[3], const double end2[3], double &t, double &u)
void tolerance (const double &tol)
double tolerance (void) const

Protected Attributes

double mTolerance
double mToleranceSquared

Detailed Description

Definition at line 14 of file IntersectionTool.hpp.


Constructor & Destructor Documentation

IntersectionTool::IntersectionTool ( const double &  tol = 0.0001) [inline]

Definition at line 107 of file IntersectionTool.hpp.

    : mTolerance(tol)
{
  mToleranceSquared = tol * tol;
}
virtual IntersectionTool::~IntersectionTool ( ) [inline, virtual]

Definition at line 18 of file IntersectionTool.hpp.

{}

Member Function Documentation

CubitStatus IntersectionTool::closest_points_on_segments ( CubitVector p0,
CubitVector p1,
CubitVector p2,
CubitVector p3,
CubitVector point_1,
CubitVector point_2,
double &  sc,
double &  tc 
) [virtual]

Definition at line 311 of file IntersectionTool.cpp.

{
  CubitVector   u = p1 - p0;
  CubitVector   v = p3 - p2;
  CubitVector   w = p0 - p2;
  double    a = u%u;     //|u|  always >= 0
  double    b = u%v;
  double    c = v%v;     //|v| always >= 0
  double    d = u%w;
  double    e = v%w;
  double    D = a*c - b*b;       // always >= 0
  double    sN, sD = D;      // sc = sN / sD, default sD = D >= 0
  double    tN, tD = D;      // tc = tN / tD, default tD = D >= 0

    // compute the line parameters of the two closest points
  if (D < GEOMETRY_RESABS) { // the lines are almost parallel
    sN = 0.0;
    tN = e;
    tD = c;
  }
  else {                // get the closest points on the infinite lines
    sN = (b*e - c*d);
    tN = (a*e - b*d);
    if (sN < 0) {       // sc < 0 => the s=0 edge is visible
      sN = 0.0;
      tN = e;
      tD = c;
    }
    else if (sN > sD) {  // sc > 1 => the s=1 edge is visible
      sN = sD;
      tN = e + b;
      tD = c;
    }
  }
  
  if (tN < 0) {           // tc < 0 => the t=0 edge is visible
    tN = 0.0;
      // recompute sc for this edge
    if (-d < 0)
      sN = 0.0;
    else if (-d > a)
      sN = sD;
    else {
      sN = -d;
      sD = a;
    }
  }
  else if (tN > tD) {      // tc > 1 => the t=1 edge is visible
    tN = tD;
      // recompute sc for this edge
    if ((-d + b) < 0)
      sN = 0;
    else if ((-d + b) > a)
      sN = sD;
    else {
      sN = (-d + b);
      sD = a;
    }
  }
  sc = CUBIT_DBL_MAX;
  tc = CUBIT_DBL_MAX;
    //If these are going to be zero then do it...
  if ( sN < CUBIT_RESABS && sN > -CUBIT_RESABS )
    sc = 0.0;
  if ( tN < CUBIT_RESABS && tN > -CUBIT_RESABS )
    tc = 0.0;

    // finally do the division to get sc and tc
  if ( sD < CUBIT_RESABS && sD > -CUBIT_RESABS && sc != 0.0 )
  {
    PRINT_ERROR("About to divide by zero in closest_points_on_segments.\n");
    return CUBIT_FAILURE;
  }
  if ( tD < CUBIT_RESABS && tD > -CUBIT_RESABS && tc != 0.0 )
  {
    PRINT_ERROR("About to divide by zero in closest_points_on_segments.\n");
    return CUBIT_FAILURE;
  }
  if ( sc != 0.0 )
    sc = sN / sD;
  if ( tc != 0.0 )
    tc = tN / tD;
  
  point_1 = p0 + sc*u;
  point_2 = p2 + tc*v;
  return CUBIT_SUCCESS;
}
double IntersectionTool::distance_point_line ( const double  point[3],
const double  start[3],
const double  end[3],
double &  t 
)

Definition at line 145 of file IntersectionTool.cpp.

{
  double dist_sq;
  int i;
  double p12[3];
  for (i = 0; i < 3; i++)
    p12[i] = pt2[i] - pt1[i];
  
  t = parametric_position(node, pt1, pt2);
  if ( t == CUBIT_DBL_MAX )
    return -1.;
  //if ( t== 0.0 || t == 1.0)
  //  return 0.0;
    // is t on vector p12 or its infinite extension
  if (t < 0.0 || t > 1.0)
    return -1.0;
    // calculate point on p12
  double p[3];
  for (i = 0; i < 3; i++)
    p[i] = pt1[i] + t * p12[i];
    
    // return distance from node to point on p12
  dist_sq = 0.0;
  for (i = 0; i < 3; i++)
    dist_sq += (p[i] - node[i]) * (p[i] - node[i]);

  return sqrt(dist_sq);
}
virtual CubitStatus IntersectionTool::initialize ( ) [inline, virtual]

Returns the parametric position of the node on the line segement between the points pt1 and pt2. This value is between 0 and 1. If the node is closest to pt1 it will return 0, if it is closest to pt2, it will return 1. If the node is off the line, it returns the closest parametric value. If there is an error, like pt1 and pt2 are equal, then the function returns CUBIT_DBL_MAX.

Definition at line 51 of file IntersectionTool.hpp.

{return CUBIT_SUCCESS;}
int IntersectionTool::intersect_point_with_ray ( CubitVector ray_origin,
CubitVector ray_direction,
const CubitVector point,
double &  distance,
double  tol = 0.0 
) [static]

Definition at line 560 of file IntersectionTool.cpp.

{
    if (tol == 0.0)
        tol = GEOMETRY_RESABS;

    //Does the ray pass through the Point?
    // Calc distance from ray origin to Point.
    // Then compute coord's of point along ray that distance.
    // Calc distance between Point and this ray-point. If less than tolerance, a hit.

    CubitVector pointB;
    double dist1 = point->distance_between(ray_origin);
    ray_origin.next_point(ray_direction, dist1, pointB);

    if ( pointB.distance_between_squared(*point) <= (tol*tol) )
    {
        distance = dist1;
        return 1;
    }
    
    return 0;
}
int IntersectionTool::intersect_segment_with_ray ( CubitVector ray_origin,
CubitVector ray_direction,
const CubitVector p0,
const CubitVector p1,
CubitVector point,
double &  distance,
int &  point_hit,
double  tol = 0.0 
) [static]

Definition at line 493 of file IntersectionTool.cpp.

{
    // This algorithm can be found at http://geometryalgorithms.com/

    if (tol == 0.0)
        tol = GEOMETRY_RESABS;

    CubitVector u = CubitVector(*p0, *p1);
    CubitVector v = ray_direction;
    v.normalize();

    CubitVector w = CubitVector(ray_origin, *p0);

    double sc, tc;         // sc is fraction along facet edge, tc is distance along ray
    
    double a = u%u;        // always >= 0
    double b = u%v;
    double c = v%v;        // always >= 0
    double d = u%w;
    double e = v%w;
    double D = a*c - b*b;  // always >= 0

    // compute the line parameters of the two closest points
    if (D < tol)
    {
        // the lines are almost parallel
        sc = 0.0;
        tc = (b>c ? d/b : e/c);   // use the largest denominator
    }
    else
    {
        sc = (b*e - c*d) / D;
        tc = (a*e - b*d) / D;
    }

    // get the difference of the two closest points
    CubitVector dP = CubitVector(w + (sc * u) - (tc * v));  // = <0 0 0> if intersection

    double distance = sqrt(dP % dP); // return the closest distance (0 if intersection)

    point->set(*p0 + (sc * u));
    hit_distance = tc; //distance from origin to intersection point

    if (distance < tol)
    {
        //check if parallel (infinite intersection)
        if (D < tol)
            return 2;
        //check if on edge
        if (sc <= 1.0 && sc >= 0.0)
        {
            if (sc==0)
                point_hit = 1; //hit point p0
            if (sc==1)
                point_hit = 2; //hit point p1

            return 1;
        }
        else
            return 0;
    }

    return 0;
}
int IntersectionTool::intersect_triangle_with_ray ( CubitVector ray_origin,
CubitVector ray_direction,
const CubitVector p0,
const CubitVector p1,
const CubitVector p2,
CubitVector point,
double &  distance,
int &  edge_hit 
) [static]

Definition at line 405 of file IntersectionTool.cpp.

{
    // This algorithm can be found at http://geometryalgorithms.com/

    CubitVector n;           // triangle vectors
    CubitVector w0, w;       // ray vectors
    double a, b;             // params to calc ray-plane intersect

    double tol = GEOMETRY_RESABS;

    // get triangle edge vectors and plane normal
    CubitVector u(  p1->x() - p0->x(),
                    p1->y() - p0->y(),
                    p1->z() - p0->z()); //(*p1-*p0);
    CubitVector v(  p2->x() - p0->x(),
                    p2->y() - p0->y(),
                    p2->z() - p0->z()); // = (*p2-*p0);

    n = u * v; // cross product to get normal

    if (n.length_squared() == 0)   // triangle is degenerate
        return -1;                 // do not deal with this case

    //dir = R.P1 - R.P0;             // ray direction vector
    //w0 = R.P0 - T.V0;
    w0 = CubitVector(ray_origin.x() - p0->x(),
        ray_origin.y() - p0->y(),
        ray_origin.z() - p0->z());

    a = -(n%w0);
    b = (n%ray_direction);
    if (fabs(b) < tol) {     // ray is parallel to triangle plane
        if (a == 0)                // ray lies in triangle plane
            return 2;
        else return 0;             // ray disjoint from plane
    }

    // get intersect point of ray with triangle plane
    distance = a / b;
    if (distance < 0.0)                   // ray goes away from triangle
        return 0;                  // => no intersect
    // for a segment, also test if (r > 1.0) => no intersect

    point->set(ray_origin + distance * ray_direction);           // intersect point of ray and plane

    // set distance to be absolute distance (if ray_direction was a unit vector)
    distance = distance * ray_direction.length();

    // is point inside facet?
    double uu, uv, vv, wu, wv, D;
    uu = u%u;
    uv = u%v;
    vv = v%v;
    //w = *I - T.V0;
    w = CubitVector(point->x() - p0->x(),
                    point->y() - p0->y(),
                    point->z() - p0->z());
    wu = w%u;
    wv = w%v;
    D = uv * uv - uu * vv;

    // get and test parametric coords
    double s, t;
    s = (uv * wv - vv * wu) / D;
    if (s < 0.0 || s > 1.0)        // point is outside facet
        return 0;
    t = (uv * wu - uu * wv) / D;
    if (t < 0.0 || (s + t) > 1.0)  // point is outside facet
        return 0;

    if (s==0)
        edge_hit = 2; //lies along v, edge #2
    if (t==0)
        edge_hit = 1; //lies along u, edge #1
    if (s+t==1)
        edge_hit = 3; //lies along edge #3

    // note:
    // if s and t are both 0, hit the point p0
    // if s=1 and t=0, hit point p1
    // if s=0 and t=1, hit point p2

    return 1; // point is in facet

}
double IntersectionTool::parametric_position ( const double  node[3],
const double  pt1[3],
const double  pt2[3] 
)

Definition at line 56 of file IntersectionTool.cpp.

{
  int i;
  double dist_sq, t;
  
    // check for end-points
  double p13[3];
  for (i = 0; i < 3; i++)
    p13[i] = node[i] - pt1[i];
  dist_sq = p13[0] * p13[0] +  p13[1] * p13[1] +  p13[2] * p13[2];
  if (dist_sq < mToleranceSquared) {
    t = 0.0;
    return t;
  }

  double p23[3];
  for (i = 0; i < 3; i++)
    p23[i] = node[i] - pt2[i];
  dist_sq = p23[0] * p23[0] +  p23[1] * p23[1] +  p23[2] * p23[2];
  if (dist_sq < mToleranceSquared) {
    t = 1.0;
    return t;
  }
  
    // t is parametric distance along vector p12
  double p12[3];
  for (i = 0; i < 3; i++)
    p12[i] = pt2[i] - pt1[i];
  
    // point1 and point2 are coincident if dot1 is zero
  double dot1 = p12[0] * p12[0] + p12[1] * p12[1] + p12[2] * p12[2];
  if (dot1 > -mToleranceSquared && dot1 < mToleranceSquared)
    return CUBIT_DBL_MAX;
  t = (p13[0] * p12[0] + p13[1] * p12[1] + p13[2] * p12[2]) / dot1;
  if (t > -mTolerance && t <  mTolerance)
    t = 0.0;
  else if ((t - 1.0) > -mTolerance &&
           (t - 1.0) <  mTolerance)
    t = 1.0;
  return t;
}
int IntersectionTool::point_on_polyline ( CubitVector pt,
DLIList< CubitVector * > &  pt_list,
double *  tol_in = NULL 
)

Definition at line 100 of file IntersectionTool.cpp.

{
  int i, ret;
  double t, distance;
  double pt_coords[3];
  double line_coords1[3];
  double line_coords2[3];
  double tol = GEOMETRY_RESABS;

  if(tol_in)
    tol = *tol_in;

  ret = 0;

  pt_coords[0] = pt.x();
  pt_coords[1] = pt.y();
  pt_coords[2] = pt.z();

  pt_list.reset();
  CubitVector *last_pt = pt_list.get_and_step();
  for(i=pt_list.size(); i>1; i--)
  {
    CubitVector *next_pt = pt_list.get_and_step();

    line_coords1[0] = last_pt->x();
    line_coords1[1] = last_pt->y();
    line_coords1[2] = last_pt->z();
    line_coords2[0] = next_pt->x();
    line_coords2[1] = next_pt->y();
    line_coords2[2] = next_pt->z();

    distance = distance_point_line(pt_coords, line_coords1, line_coords2, t);

    if(distance > -tol && distance < tol)
    {
      i = 1;
      ret = 1;
    }
    else
      last_pt = next_pt;
  }
  return ret;
}
CubitBoolean IntersectionTool::ray_tri_test ( const double  start[3],
const double  dir[3],
const double  tri1[3],
const double  tri2[3],
const double  tri3[3],
double &  t,
double &  alpha,
double &  beta 
) [protected]

Definition at line 177 of file IntersectionTool.cpp.

{
  int i;
  
    // find vectors for two edges sharing vert0
  double edge1[3];
  double edge2[3];
  for (i = 0; i < 3; i++) {
    edge1[i] = vert1[i] - vert0[i];
    edge2[i] = vert2[i] - vert0[i];
  }
  
    // calculate determinate
  double pvec[3];
  pvec[0] = dir[1] * edge2[2] - dir[2] * edge2[1];
  pvec[1] = dir[2] * edge2[0] - dir[0] * edge2[2];
  pvec[2] = dir[0] * edge2[1] - dir[1] * edge2[0];
  double det =
    edge1[0] * pvec[0] + edge1[1] * pvec[1] + edge1[2] * pvec[2];
  
    // if determinate is near zero, the ray is in plane of triangle
  if (det > -mTolerance && det < mTolerance) {
    return CUBIT_FALSE;
  }
  
    // calculate distance from vert0 to ray origin
  double tvec[3];
  for (i = 0; i < 3; i++)
    tvec[i] = start[i] - vert0[i];
  
    // calculate U parameter and test bounds
  double inv_det = 1.0/det;
  u = (tvec[0] * pvec[0] + tvec[1] * pvec[1] + tvec[2] * pvec[2]) * inv_det;
  if (u > -mTolerance && u < mTolerance) u = 0.0;
  else if ((u - 1.0) > -mTolerance &&
           (u - 1.0) <  mTolerance) u = 1.0;
  if (u < 0.0 || u > 1.0) {
    return CUBIT_FALSE;
  }

    // calculate V parameter and test bounds
  double qvec[3];
  qvec[0] = tvec[1] * edge1[2] - tvec[2] * edge1[1];
  qvec[1] = tvec[2] * edge1[0] - tvec[0] * edge1[2];
  qvec[2] = tvec[0] * edge1[1] - tvec[1] * edge1[0];
  v = (dir[0] * qvec[0] + dir[1] * qvec[1] + dir[2] * qvec[2]) * inv_det;
  if (v > -mTolerance && v < mTolerance) v = 0.0;
  else if ((v - 1.0) > -mTolerance &&
           (v - 1.0) <  mTolerance) v = 1.0;
  if (v < 0.0 || (u + v - 1.0) > mTolerance) {    
    return CUBIT_FALSE;
  }

    // calculate T, ray intersects triangle
  t = (edge2[0] * qvec[0] + edge2[1] * qvec[1] + 
       edge2[2] * qvec[2]) * inv_det;
  if (t > -mTolerance && t < mTolerance) t = 0.0;
  else if ((t - 1.0) > -mTolerance &&
           (t - 1.0) <  mTolerance) t = 1.0;

  return CUBIT_TRUE;
}
CubitBoolean IntersectionTool::skew_line_test ( const double  start1[3],
const double  end1[3],
const double  start2[3],
const double  end2[3],
double &  t,
double &  u 
) [protected]

Definition at line 246 of file IntersectionTool.cpp.

{
  t = -1.0;
  u = -1.0;
  
  int i;
  double p13[3], p43[3];
  for (i = 0; i < 3; i++) {
    p13[i] = start1[i] - start2[i];
    p43[i] = end2[i]   - start2[i];
  }
  double len_sq1 = p43[0] * p43[0] + p43[1] * p43[1] + p43[2] * p43[2];
  if (len_sq1 < mToleranceSquared)
    return CUBIT_FALSE;

  double p21[3];
  for (i = 0; i < 3; i++) {
    p21[i] = end1[i] - start1[i];
  }
  double len_sq2 = p21[0] * p21[0] + p21[1] * p21[1] + p21[2] * p21[2];
  if (len_sq2 < mToleranceSquared)
    return CUBIT_FALSE;

  double fact;
  if (len_sq2 < len_sq1) fact = 10.0/sqrt(len_sq1);
  else                   fact = 10.0/sqrt(len_sq2);
  for (i = 0; i < 3; i++) {
    p13[i] *= fact;
    p43[i] *= fact;
    p21[i] *= fact;
  }

  double d1343, d4321, d1321, d4343, d2121;
  d1343 = p13[0] * p43[0] + p13[1] * p43[1] + p13[2] * p43[2];
  d4321 = p43[0] * p21[0] + p43[1] * p21[1] + p43[2] * p21[2];
  d1321 = p13[0] * p21[0] + p13[1] * p21[1] + p13[2] * p21[2];
  d4343 = p43[0] * p43[0] + p43[1] * p43[1] + p43[2] * p43[2];
  d2121 = p21[0] * p21[0] + p21[1] * p21[1] + p21[2] * p21[2];

  double denom = d2121 * d4343 - d4321 * d4321;
  if (denom > -mTolerance && denom < mTolerance)
    return CUBIT_FALSE;
  double numer = d1343 * d4321 - d1321 * d4343;

  t = numer / denom;
  if (t > -mTolerance && t < mTolerance) t = 0.0;
  else if ((t - 1.0) > -mTolerance &&
           (t - 1.0) <  mTolerance) t = 1.0;
  if (t < 0.0 || t > 1.0)
    return CUBIT_FALSE;
   
  u = (d1343 + d4321 * t) / d4343;
  if (u > -mTolerance && u < mTolerance) u = 0.0;
  else if ((u - 1.0) > -mTolerance &&
           (u - 1.0) <  mTolerance) u = 1.0;
  if (u < 0.0 || u > 1.0)
    return CUBIT_FALSE;

  return CUBIT_TRUE;
}
void IntersectionTool::tolerance ( const double &  tol) [protected]
double IntersectionTool::tolerance ( void  ) const [protected]

Member Data Documentation

double IntersectionTool::mTolerance [protected]

Definition at line 89 of file IntersectionTool.hpp.

Definition at line 90 of file IntersectionTool.hpp.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines