|
cgma
|
#include <IntersectionTool.hpp>
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 |
Definition at line 14 of file IntersectionTool.hpp.
| 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.
{}
| 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] |
double IntersectionTool::mTolerance [protected] |
Definition at line 89 of file IntersectionTool.hpp.
double IntersectionTool::mToleranceSquared [protected] |
Definition at line 90 of file IntersectionTool.hpp.