matsukawa
(Matsukawa)
August 4, 2020, 2:31am
1
ON_Line lineA({ -2.0, 0.0, 0.0 }, { 2.0, 0.0, 0.0 });
ON_Line lineB({ 0.0, 1.0, 0.0 }, { 1.0, 2.0, 0.0 });
double a, b;
double tolerance = 0.0;
bool bIntersectSegments = true;
ON_IntersectLineLine(lineA, lineB, &a, &b, tolerance, bIntersectSegments);
The results should be a=0.5, b=0.0, but it returns a=0.25,b=0.0.
dale
(Dale Fugier)
August 4, 2020, 3:50pm
2
Hi @matsukawa ,
This seems to work here:
ON_3dPoint p0(-2.0, 0.0, 0.0);
ON_3dPoint p1(2.0, 0.0, 0.0);
ON_3dPoint p2(0.0, 1.0, 0.0);
ON_3dPoint p3(1.0, 2.0, 0.0);
ON_Line lineA(p0, p1);
ON_Line lineB(p2, p3);
double a = ON_UNSET_VALUE;
double b = ON_UNSET_VALUE;
bool rc = ON_IntersectLineLine(lineA, lineB, &a, &b, 0.0, false);
if (rc)
{
ON_3dPoint point_on_lineA = lineA.PointAt(a);
ON_3dPoint point_on_lineB = lineB.PointAt(b);
// TODO...
}
– Dale
matsukawa
(Matsukawa)
August 4, 2020, 11:55pm
3
bIntersectSegments = false returns correct results.
bIntersectSegments = true returns wrong results.
bIntersectSegments = false
Expected Results : a = 0.25, b = -1.0.
Returned Results : a = 0.25, b = -1.0.
bIntersectSegments = true
Expected Results : a = 0.5, b = 0.0.
Returned Results : a = 0.25, b = 0.0.
In the function of ON_IntersectLineLine(), if bIntersectSegments is true, a and b are simply clamped to 0.0~1.0.
But we need to check a closest point between the terminal point and another line.
matsukawa
(Matsukawa)
August 5, 2020, 1:09am
4
I have fixed the code and it seems to work well.
bool ON_IntersectLineLine(
const ON_Line& lineA,
const ON_Line& lineB,
double* a,
double* b,
double tolerance,
bool bIntersectSegments
)
{
bool rc = ON_Intersect(lineA,lineB,a,b) ? true : false;
if (rc)
{
if ( bIntersectSegments )
{
#if 0
if ( *a < 0.0 )
*a = 0.0;
else if ( *a > 1.0 )
*a = 1.0;
if ( *b < 0.0 )
*b = 0.0;
else if ( *b > 1.0 )
*b = 1.0;
#else
bool a0 = (*a < 0.0);
bool a1 = (*a > 1.0);
bool b0 = (*b < 0.0);
bool b1 = (*b > 1.0);
if (a0)
lineB.ClosestPointTo(lineA.from, b);
else if (a1)
lineB.ClosestPointTo(lineA.to, b);
else
*b = std::clamp(*b, 0.0, 1.0);
if (b0)
lineA.ClosestPointTo(lineB.from, a);
else if (b1)
lineA.ClosestPointTo(lineB.to, a);
else
*a = std::clamp(*a, 0.0, 1.0);
#endif
}
if ( tolerance > 0.0 )
{
rc = (lineA.PointAt(*a).DistanceTo(lineB.PointAt(*b)) <= tolerance);
}
}
return rc;
}