mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-30 09:00:20 -05:00
Improves geometry tools robustness and accuracy
* Replace asserts with alternatives * Refactors GeometryTools for improved robustness
This commit is contained in:
1 parent
fd5bdc96d2
commit
597cfd4d30
6 files changed
+402
-225
No files matched your search
@@ -239,30 +239,20 @@ GeometryTools::IntersectionStatus inPlaneLineIntersect( double x1,
|
||||
double y4,
|
||||
double l1NormalizedTolerance,
|
||||
double l2NormalizedTolerance,
|
||||
double* x,
|
||||
double* y,
|
||||
double* fractionAlongLine1,
|
||||
double* fractionAlongLine2 )
|
||||
double& x,
|
||||
double& y,
|
||||
double& fractionAlongLine1,
|
||||
double& fractionAlongLine2 )
|
||||
{
|
||||
double mua, mub;
|
||||
double denom, numera, numerb;
|
||||
|
||||
denom = ( y4 - y3 ) * ( x2 - x1 ) - ( x4 - x3 ) * ( y2 - y1 );
|
||||
numera = ( x4 - x3 ) * ( y1 - y3 ) - ( y4 - y3 ) * ( x1 - x3 );
|
||||
numerb = ( x2 - x1 ) * ( y1 - y3 ) - ( y2 - y1 ) * ( x1 - x3 );
|
||||
auto denom = ( y4 - y3 ) * ( x2 - x1 ) - ( x4 - x3 ) * ( y2 - y1 );
|
||||
auto numera = ( x4 - x3 ) * ( y1 - y3 ) - ( y4 - y3 ) * ( x1 - x3 );
|
||||
auto numerb = ( x2 - x1 ) * ( y1 - y3 ) - ( y2 - y1 ) * ( x1 - x3 );
|
||||
|
||||
double EPS = 1e-40;
|
||||
|
||||
// Are the line coincident?
|
||||
if ( fabs( numera ) < EPS && fabs( numerb ) < EPS && fabs( denom ) < EPS )
|
||||
{
|
||||
#if 0
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
*fractionAlongLine1 = 0;
|
||||
*fractionAlongLine2 = 0;
|
||||
return GeometryTools::LINES_OVERLAP;
|
||||
#else
|
||||
cvf::Vec3d p12( x2 - x1, y2 - y1, 0 );
|
||||
cvf::Vec3d p13( x3 - x1, y3 - y1, 0 );
|
||||
cvf::Vec3d p34( x4 - x3, y4 - y3, 0 );
|
||||
@@ -274,10 +264,10 @@ GeometryTools::IntersectionStatus inPlaneLineIntersect( double x1,
|
||||
|
||||
if ( length12 < EPS )
|
||||
{
|
||||
*x = x1;
|
||||
*y = y1;
|
||||
*fractionAlongLine1 = 1;
|
||||
*fractionAlongLine2 = p13.length() / p34.length();
|
||||
x = x1;
|
||||
y = y1;
|
||||
fractionAlongLine1 = 1;
|
||||
fractionAlongLine2 = p13.length() / p34.length();
|
||||
return GeometryTools::LINES_OVERLAP;
|
||||
}
|
||||
|
||||
@@ -292,10 +282,10 @@ GeometryTools::IntersectionStatus inPlaneLineIntersect( double x1,
|
||||
if ( ( normDist13 < 0 - l1NormalizedTolerance && normDist14 < 0 - l1NormalizedTolerance ) ||
|
||||
( normDist13 > 1 + l1NormalizedTolerance && normDist14 > 1 + l1NormalizedTolerance ) )
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
*fractionAlongLine1 = 0;
|
||||
*fractionAlongLine2 = 0;
|
||||
x = 0;
|
||||
y = 0;
|
||||
fractionAlongLine1 = 0;
|
||||
fractionAlongLine2 = 0;
|
||||
return GeometryTools::NO_INTERSECTION;
|
||||
}
|
||||
|
||||
@@ -311,68 +301,67 @@ GeometryTools::IntersectionStatus inPlaneLineIntersect( double x1,
|
||||
|
||||
if ( pt3IsInside && !pt4IsInside )
|
||||
{
|
||||
*fractionAlongLine1 = normDist13;
|
||||
*fractionAlongLine2 = 0.0;
|
||||
*x = x3;
|
||||
*y = y3;
|
||||
fractionAlongLine1 = normDist13;
|
||||
fractionAlongLine2 = 0.0;
|
||||
x = x3;
|
||||
y = y3;
|
||||
}
|
||||
else if ( pt4IsInside && !pt3IsInside )
|
||||
{
|
||||
*fractionAlongLine1 = normDist14;
|
||||
*fractionAlongLine2 = 1.0;
|
||||
*x = x4;
|
||||
*y = y4;
|
||||
fractionAlongLine1 = normDist14;
|
||||
fractionAlongLine2 = 1.0;
|
||||
x = x4;
|
||||
y = y4;
|
||||
}
|
||||
else if ( pt3IsInside && pt4IsInside )
|
||||
{
|
||||
// Return edge 2 vertex furthest along edge 1
|
||||
if ( normDist13 <= normDist14 )
|
||||
{
|
||||
*fractionAlongLine1 = normDist14;
|
||||
*fractionAlongLine2 = 1.0;
|
||||
*x = x4;
|
||||
*y = y4;
|
||||
fractionAlongLine1 = normDist14;
|
||||
fractionAlongLine2 = 1.0;
|
||||
x = x4;
|
||||
y = y4;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fractionAlongLine1 = normDist13;
|
||||
*fractionAlongLine2 = 0.0;
|
||||
*x = x3;
|
||||
*y = y3;
|
||||
fractionAlongLine1 = normDist13;
|
||||
fractionAlongLine2 = 0.0;
|
||||
x = x3;
|
||||
y = y3;
|
||||
}
|
||||
}
|
||||
else // both outside on each side
|
||||
{
|
||||
// Return End of edge 1
|
||||
*fractionAlongLine1 = 1.0;
|
||||
*fractionAlongLine2 = normDist32;
|
||||
*x = x2;
|
||||
*y = y2;
|
||||
fractionAlongLine1 = 1.0;
|
||||
fractionAlongLine2 = normDist32;
|
||||
x = x2;
|
||||
y = y2;
|
||||
}
|
||||
|
||||
return GeometryTools::LINES_OVERLAP;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Are the line parallel */
|
||||
if ( fabs( denom ) < EPS )
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
*fractionAlongLine1 = 0;
|
||||
*fractionAlongLine2 = 0;
|
||||
x = 0;
|
||||
y = 0;
|
||||
fractionAlongLine1 = 0;
|
||||
fractionAlongLine2 = 0;
|
||||
|
||||
return GeometryTools::NO_INTERSECTION;
|
||||
}
|
||||
|
||||
/* Is the intersection along the the segments */
|
||||
mua = numera / denom;
|
||||
mub = numerb / denom;
|
||||
auto mua = numera / denom;
|
||||
auto mub = numerb / denom;
|
||||
|
||||
*x = x1 + mua * ( x2 - x1 );
|
||||
*y = y1 + mua * ( y2 - y1 );
|
||||
*fractionAlongLine1 = mua;
|
||||
*fractionAlongLine2 = mub;
|
||||
x = x1 + mua * ( x2 - x1 );
|
||||
y = y1 + mua * ( y2 - y1 );
|
||||
fractionAlongLine1 = mua;
|
||||
fractionAlongLine2 = mub;
|
||||
|
||||
if ( mua < 0 - l1NormalizedTolerance || 1 + l1NormalizedTolerance < mua || mub < 0 - l2NormalizedTolerance ||
|
||||
1 + l2NormalizedTolerance < mub )
|
||||
@@ -382,10 +371,10 @@ GeometryTools::IntersectionStatus inPlaneLineIntersect( double x1,
|
||||
else if ( fabs( mua ) < l1NormalizedTolerance || fabs( 1 - mua ) < l1NormalizedTolerance || fabs( mub ) < l2NormalizedTolerance ||
|
||||
fabs( 1 - mub ) < l2NormalizedTolerance )
|
||||
{
|
||||
if ( fabs( mua ) < l1NormalizedTolerance ) *fractionAlongLine1 = 0;
|
||||
if ( fabs( 1 - mua ) < l1NormalizedTolerance ) *fractionAlongLine1 = 1;
|
||||
if ( fabs( mub ) < l2NormalizedTolerance ) *fractionAlongLine2 = 0;
|
||||
if ( fabs( 1 - mub ) < l2NormalizedTolerance ) *fractionAlongLine2 = 1;
|
||||
if ( fabs( mua ) < l1NormalizedTolerance ) fractionAlongLine1 = 0;
|
||||
if ( fabs( 1 - mua ) < l1NormalizedTolerance ) fractionAlongLine1 = 1;
|
||||
if ( fabs( mub ) < l2NormalizedTolerance ) fractionAlongLine2 = 0;
|
||||
if ( fabs( 1 - mub ) < l2NormalizedTolerance ) fractionAlongLine2 = 1;
|
||||
return GeometryTools::LINES_TOUCH;
|
||||
}
|
||||
else
|
||||
@@ -403,13 +392,11 @@ GeometryTools::IntersectionStatus GeometryTools::inPlaneLineIntersect3D( const c
|
||||
const cvf::Vec3d& p2,
|
||||
const cvf::Vec3d& p3,
|
||||
const cvf::Vec3d& p4,
|
||||
cvf::Vec3d* intersectionPoint,
|
||||
double* fractionAlongLine1,
|
||||
double* fractionAlongLine2,
|
||||
cvf::Vec3d& intersectionPoint,
|
||||
double& fractionAlongLine1,
|
||||
double& fractionAlongLine2,
|
||||
double tolerance )
|
||||
{
|
||||
CVF_ASSERT( intersectionPoint != nullptr );
|
||||
|
||||
int Z = findClosestAxis( planeNormal );
|
||||
int X = ( Z + 1 ) % 3;
|
||||
int Y = ( Z + 2 ) % 3;
|
||||
@@ -420,16 +407,16 @@ GeometryTools::IntersectionStatus GeometryTools::inPlaneLineIntersect3D( const c
|
||||
double l2NormTol = tolerance / ( p4 - p3 ).length();
|
||||
|
||||
IntersectionStatus intersectionStatus =
|
||||
inPlaneLineIntersect( p1[X], p1[Y], p2[X], p2[Y], p3[X], p3[Y], p4[X], p4[Y], l1NormTol, l2NormTol, &x, &y, fractionAlongLine1, fractionAlongLine2 );
|
||||
inPlaneLineIntersect( p1[X], p1[Y], p2[X], p2[Y], p3[X], p3[Y], p4[X], p4[Y], l1NormTol, l2NormTol, x, y, fractionAlongLine1, fractionAlongLine2 );
|
||||
|
||||
// Check if we have a valid intersection point
|
||||
if ( intersectionStatus == NO_INTERSECTION || intersectionStatus == LINES_OVERLAP )
|
||||
{
|
||||
intersectionPoint->setZero();
|
||||
intersectionPoint.setZero();
|
||||
}
|
||||
else
|
||||
{
|
||||
*intersectionPoint = p1 + ( *fractionAlongLine1 ) * ( p2 - p1 );
|
||||
intersectionPoint = p1 + ( fractionAlongLine1 ) * ( p2 - p1 );
|
||||
}
|
||||
|
||||
return intersectionStatus;
|
||||
|
||||
Reference in new issue
Block a user