[QUESTION] Curve-ray or Curve-infinite_line intersection

Is there any way of gettingt a Curve-Ray3d or Curve-Infinite_line intersection using Rhinocommon? I saw RayShoot method but it applies only to BREPS.

Right now I’m hardcoding a CurveCurve intersectiong using a very long LineCurve for calculating the intersection…but it is not the perfect option…

Thanks in advance.

but it is not the perfect option…

Can you explain why not?

Also, could you maybe use curve-plane intersections?

1 Like

Because the workaround to calculate that distance is a little bit…let’s say “not very stylish”…and I don’t understand why other objects have the ray intersection implemented and curves lack it. I mean, the Intersection class methods looks a little bit random talking about what intersections have been implemented…

I tried the plane thing and it requires to calculate (using a vector cross product for instance) a vector normal to my “ray” direction that is another workaround not needed to use the same kind of intersection with other kind of geometry :stuck_out_tongue: At the end, it is equally complicated to code the “very-long-line” and the plane approach.

I think the curves lack the ray intersection because this only makes sense if the curves are planar and the ray is in the plane, and curves are usually not planar.

Other objects, like surfaces and meshes, have more “use cases” for ray intersection, and they cannot benefit from the long-line or plane approaches to the problem.

1 Like

Grasshopper has a curve-line intersection component (as far as I recall). Maybe @DavidRutten can elaborate on the method it uses?

I’m already using curve-line intersection my question was about the lack of
curvr-ray intersection that, as @menno said, it only has sense for 2d
problems (like the one that I’m solving).

Thanks for adding David to the conversation @AndersDeleuran.

El vie., 20 de noviembre de 2015 20:59, AndersDeleuran steve@mcneel.com
escribió:

The reason you don’t find curve-ray or curve-infinite line intersection functions in RhinoCommon is that here isn’t anything in Rhino that has needed them in the past.

Both RhinoScript and Grasshopper have some form of a curve-infinite line intersection method/component. These basically do what you are already doing, which is to extend a line thru the curve and then perform a standard curve-curve intersection.

If it makes your work easier, we are happy to wrap all this into an easy-to-use function. I’ve added it to the wish list.

http://mcneel.myjetbrains.com/youtrack/issue/RH-32045

In the mean time, if you need help implement such a function, let me know.

I haven’t tested this. But it should work…

/// <summary>
/// Intersects a curve and an infinite line.
/// </summary>
/// <param name="curve">Curve to intersect.</param>
/// <param name="line">Infinite line to intesect.</param>
/// <param name="tolerance">If the distance from a point on curve to line
/// is &lt;= tolerance, then the point will be part of an intersection
/// event. If the tolerance &lt;= 0.0, then 0.001 is used.</param>
/// <param name="overlapTolerance">If t1 and t2 are parameters of curve's
/// intersection events and the distance from curve(t) to line is &lt;= 
/// overlapTolerance for every t1 &lt;= t &lt;= t2, then the event will 
/// be returened as an overlap event. If overlapTolerance &lt;= 0.0, 
/// then tolerance * 2.0 is used.</param>
/// <returns>A collection of intersection events.</returns>
public static Rhino.Geometry.Intersect.CurveIntersections IntersectCurveLine(
  Rhino.Geometry.Curve curve, 
  Rhino.Geometry.Line line, 
  double tolerance, 
  double overlapTolerance
  )
{
  if (!curve.IsValid || !line.IsValid || line.Length < Rhino.RhinoMath.SqrtEpsilon)
    return null;

  // Extend the line through the curve's bounding box
  var bbox = curve.GetBoundingBox(false);
  if (!bbox.IsValid)
    return null;

  var dir = line.Direction;
  dir.Unitize();

  var points = bbox.GetCorners();
  var plane = new Rhino.Geometry.Plane(line.From, dir);

  double max_dist;
  var min_dist = max_dist = plane.DistanceTo(points[0]);
  for (var i = 1; i < points.Length; i++)
  {
    var dist = plane.DistanceTo(points[i]);
    if (dist < min_dist)
      min_dist = dist;
    if (dist > max_dist)
      max_dist = dist;
  }

  // +- 1.0 makes the line a little bigger than the bounding box
  line.From = line.From + dir * (min_dist - 1.0);
  line.To = line.From + dir * (max_dist + 1.0);

  // Calculate curve-curve intersection
  var line_curve = new Rhino.Geometry.LineCurve(line);
  return Rhino.Geometry.Intersect.Intersection.CurveCurve(curve, line_curve, tolerance, overlapTolerance);
}

I get the curve boundingbox, then extend the line through the boundingbox, turn it into a LineCurve and perform a Curve|Curve intersection, very similar to the approach Dale put up.

1 Like

Ok, I did a most the same but using the curve centroid. But I’m sure that
the Bbox approach is less computational intense. Thanks for the tips
@DavidRutten & @dale! I’m going to check your code :slight_smile: