mcneel / rhinocommon

RhinoCommon is the .NET SDK for Rhino5 / Grasshopper
http://wiki.mcneel.com/developer/rhinocommon
244 stars 93 forks source link

Bug in Intersection.LineLine() method #177

Closed VahidYousefzadeh closed 7 years ago

VahidYousefzadeh commented 7 years ago

Hi,

I just came across a very odd result when using the Intersection.LineLine() method.

         const double q = 100000d;

         Point3d p0 = new Point3d(5d, q, 0d);
         Point3d p1 = new Point3d(5d, -q, 0d);

         Point3d p2 = new Point3d(-q, 5d, 0d);
         Point3d p3 = new Point3d(q, 5d, 0d);

         Line l1 = new Line(p0, p1);
         Line l2 = new Line(p2, p3);

         double a;
         double b;
         bool res = Rhino.Geometry.Intersect.Intersection.LineLine(l1, l2, out a, out b, Rhino.RhinoMath.ZeroTolerance, true);

It is obvious that these lines intersect, but the result returns FALSE.

When I use a smaller value for q, for example 10000 it returns TRUE! To me it seems a tolerance problem.

Also if you keep the q = 100000d and use 0d instead of 5d for both points, it will return TRUE this time!

Am I missing something?

Kind Regards Vahid

dalefugier commented 7 years ago

Hi @vahidce,

You are probably running into a floating point rounding issue. In the case of 100,000, rather than using a tolerance of 1e-012, try something more reasonable like 0.01.

-- Dale

VahidYousefzadeh commented 7 years ago

Thanks Dale, but shouldn't it work without setting this tolerance? I used the following code to fix this:

double a; double b; RhI.Intersection.LineLine(first.RhinoValue, second.RhinoValue, out a, out b); if (a + RhinoMath.ZeroTolerance < 0 || a - RhinoMath.ZeroTolerance > 1 || b + RhinoMath.ZeroTolerance < 0 || b - RhinoMath.ZeroTolerance > 1) { // imaginary intersection } else { // real intersection } Vahid

dalefugier commented 7 years ago

The version of Intersection.LineLine, that does not require a tolerance, works:

const double q = 100000;
var p0 = new Point3d(5.0, q, 0.0);
var p1 = new Point3d(5.0, -q, 0.0);
var p2 = new Point3d(-q, 5.0, 0.0);
var p3 = new Point3d(q, 5.0, 0.0);

var l0 = new Line(p0, p1);
var l1 = new Line(p2, p3);

var a = RhinoMath.UnsetValue;
var b = RhinoMath.UnsetValue;
var rc = Rhino.Geometry.Intersect.Intersection.LineLine(l0, l1, out a, out b);

Is this sufficient?