McNeel Wiki
Calculating Curve Intersections
edit · print · help · all topics
Main Pages

AccuRender

Bongo

Brazil r/s

Developer

Flamingo

Penguin

Rhino Blogs

Rhino

Search

Languages

Česky

Deutsch

English

Español

Français

Italiano

Polish

日本語

한국어

中文(繁體)

 
.
DeveloperC++, .NET

Question

How can I calculate the intersection of two curves and obtain their 3-D intersection points?

Answer

Use ON_Curve::IntersectCurve. For details in this function, see opennurbs_curve.h.

The following example code demonstrates how to calculate the intersection of two curves.

C++

  CRhinoCommand::result CCommandTest::RunCommand( 
        const CRhinoCommandContext& context 
        )
  {
    // Select two curves to intersect
    CRhinoGetObject go;
    go.SetCommandPrompt( L"Select two curves" );
    go.SetGeometryFilter( ON::curve_object );
    go.GetObjects( 2, 2 );
    if( go.CommandResult() != CRhinoCommand::success )
      return go.CommandResult();


    // Validate input
    const ON_Curve* curveA = go.Object(0).Curve();
    const ON_Curve* curveB = go.Object(1).Curve();
    if( 0 == curveA || 0 == curveB )
      return CRhinoCommand::failure;


    // Calculate the intersection
    double intersection_tolerance = 0.001;
    double overlap_tolerance = 0.0;
    ON_SimpleArray<ON_X_EVENT> events;
    int count = curveA->IntersectCurve(
          curveB, 
          events, 
          intersection_tolerance, 
          overlap_tolerance
          );


    // Process the results
    if( count > 0 )
    {
      int i;
      for( i = 0; i < events.Count(); i++ )
      {
        const ON_X_EVENT& e = events[i];
        context.m_doc.AddPointObject( e.m_A[0] );
        if( e.m_A[0].DistanceTo(e.m_B[0]) > ON_EPSILON )
        {
          context.m_doc.AddPointObject( e.m_B[0] );
          context.m_doc.AddCurveObject( ON_Line(e.m_A[0], e.m_B[0]) );
        }
      }
      context.m_doc.Redraw();
    }


    return CRhinoCommand::success;
  }

C# (Rhino 4)

  public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
  {
    // Select two curves to intersect
    MRhinoGetObject go = new MRhinoGetObject();
    go.SetCommandPrompt( "Select two curves" );
    go.SetGeometryFilter( IRhinoGetObject.GEOMETRY_TYPE_FILTER.curve_object );
    go.GetObjects( 2, 2 );
    if( go.CommandResult() != IRhinoCommand.result.success )
      return go.CommandResult();


    // Validate input
    IOnCurve curveA = go.Object(0).Curve();
    IOnCurve curveB = go.Object(1).Curve();
    if( curveA == null || curveB == null )
      return IRhinoCommand.result.failure;


    // Calculate the intersection
    double intersection_tolerance = 0.001;
    double overlap_tolerance = 0.0;
    ArrayOnX_EVENT xEvents = new ArrayOnX_EVENT();
    int count = curveA.IntersectCurve( curveB, ref xEvents, intersection_tolerance, overlap_tolerance );


    // ON_EPSILON will be added to future builds of the SDK
    // For now just use a hard coded value
    double epsilon = 2.2204460492503131e-16;


    // Process the results
    if( count > 0 )
    {
      OnLine line = new OnLine();
      for( int i = 0; i < xEvents.Count(); i++ )
      {
        IOnX_EVENT e = xEvents[i];
        On3dPoint ptA = new On3dPoint(e.get_m_pointA(0));
        On3dPoint ptB = new On3dPoint(e.get_m_pointB(0));
        context.m_doc.AddPointObject(ptA);
        double distance = ptA.DistanceTo(ptB);
        if (distance > epsilon)
        {
          context.m_doc.AddPointObject( ptB );
          line.from = ptA;
          line.to = ptB;
          context.m_doc.AddCurveObject( line );
        }
      }
      context.m_doc.Redraw();
    }


    return IRhinoCommand.result.success;
  }

VB.NET (Rhino 4)

  Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) _
    As RMA.Rhino.IRhinoCommand.result
    ' Select two curves to intersect
    Dim go As New MRhinoGetObject()
    go.SetCommandPrompt("Select two curves")
    go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.curve_object)
    go.GetObjects(2, 2)
    If (go.CommandResult() <> IRhinoCommand.result.success) Then
      Return go.CommandResult()
    End If


    ' Validate input
    Dim curveA As IOnCurve = go.Object(0).Curve()
    Dim curveB As IOnCurve = go.Object(1).Curve()
    If (curveA Is Nothing Or curveB Is Nothing) Then
      Return IRhinoCommand.result.failure
    End If


    ' Calculate the intersection
    Dim intersection_tolerance As Double = 0.001
    Dim overlap_tolerance As Double = 0.0
    Dim xEvents As New ArrayOnX_EVENT()
    Dim count As Integer = curveA.IntersectCurve(curveB, xEvents, intersection_tolerance, _
                                                 overlap_tolerance)


    ' ON_EPSILON will be added to future builds of the SDK
    ' For now just use a hard coded value
    Dim epsilon As Double = 0.00000000000000022204460492503131


    ' Process the results
    If (count > 0) Then
      Dim line As New OnLine()
      For i As Integer = 0 To xEvents.Count() - 1
        Dim e As IOnX_EVENT = xEvents(i)
        Dim ptA As New On3dPoint(e.m_pointA(0))
        Dim ptB As New On3dPoint(e.m_pointB(0))
        context.m_doc.AddPointObject(ptA)
        Dim distance As Double = ptA.DistanceTo(ptB)
        If (distance > epsilon) Then
          context.m_doc.AddPointObject(ptB)
          line.from = ptA
          line.to = ptB
          context.m_doc.AddCurveObject(line)
        End If
      Next
      context.m_doc.Redraw()
    End If


    Return IRhinoCommand.result.success
  End Function
rename · changes · history · subscriptions · lost and found · references · file upload