McNeel Wiki
Determine the Deviation between two Curves
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
SummaryDemonstrates how to determine the deviation between two curves using the RhinoGetOverlapDistance() SDK function.

C++

  CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context )
  {
    CRhinoGetObject go;
    go.SetCommandPrompt( L"Select curves to test" );
    go.SetGeometryFilter( ON::curve_object );
    go.EnableSubObjectSelect( true );
    go.AcceptNothing();
    go.GetObjects( 2, 2 );
    if( go.CommandResult() != success )
      return go.CommandResult();
    if( go.ObjectCount() != 2 )
      return failure;


    const ON_Curve* crv_a = go.Object(0).Curve();
    if( !crv_a )
      return failure;


    const ON_Curve* crv_b = go.Object(1).Curve();
    if( !crv_b )
      return failure;


    double tol = context.m_doc.AbsoluteTolerance();
    int count = 0;
    double int_a[3][2];
    double int_b[3][2];
    double max_a, max_b, max_d;
    double min_a, min_b, min_d;


    bool rc = RhinoGetOverlapDistance( 
          crv_a,  // curve A
          0,      // optional domain for curve A
          crv_b,  // curve B
          0,      // optional domain for curve B
          tol,    // tolerance for common normal detection
          0.0,    // limits acceptable overlap distance
          &count, // overlap interval count (0 to 3)
          int_a,  // curve A interval(s)
          int_b,  // curve B interval(s)
          &max_a, // curve B parameter at maximum overlap distance point
          &max_b, // curve B parameter at maximum overlap distance point
          &max_d, // maximum overlap distance
          &min_a, // curve A parameter at minimum distance point
          &min_b, // curve B parameter at minimum distance point
          &min_d  // minimum distance between curves
          );


    if( min_d <= ON_ZERO_TOLERANCE )
      min_d = 0.0;


    if( rc )
    {
      if( count == 0 )
      {
        RhinoApp().Print( L"Curves do not overlap.\n" );
      }
      else
      {
        context.m_doc.AddPointObject( crv_a->PointAt(max_a) );
        context.m_doc.AddPointObject( crv_b->PointAt(max_b) );
        context.m_doc.AddPointObject( crv_a->PointAt(min_a) );
        context.m_doc.AddPointObject( crv_b->PointAt(min_b) );
        context.m_doc.Redraw();


        int i;
        for( i = 0; i < count; i++ )
        {
          ON_3dPoint sp_a = crv_a->PointAt( int_a[i][0] );
          ON_3dPoint sp_b = crv_b->PointAt( int_b[i][0] );
          double sd = sp_a.DistanceTo( sp_b );


          ON_3dPoint ep_a = crv_a->PointAt( int_a[i][1] );
          ON_3dPoint ep_b = crv_b->PointAt( int_b[i][1] );
          double ed = ep_a.DistanceTo( ep_b );


          RhinoApp().Print( L"Overlap interval %d of %d:\n", i+1, count );
          RhinoApp().Print( L"          start: distance = %g\n", sd );
          RhinoApp().Print( L"                 crvA(%10g) = (%g, %g, %g)\n", 
                            int_a[i][0], sp_a.x, sp_a.y, sp_a.z );
          RhinoApp().Print( L"                 crvB(%10g) = (%g, %g, %g)\n", 
                            int_b[i][0], sp_b.x, sp_b.y, sp_b.z );
          RhinoApp().Print( L"            end: distance = %g\n", ed );
          RhinoApp().Print( L"                 crvA(%10g) = (%g, %g, %g)\n", 
                            int_a[i][1], ep_a.x, ep_a.y, ep_a.z );
          RhinoApp().Print( L"                 crvB(%10g) = (%g, %g, %g)\n", 
                            int_b[i][1], ep_b.x, ep_b.y, ep_b.z );
        }


        RhinoApp().Print( L"Minimum deviation = %g\n", min_d );
        RhinoApp().Print( L"Maximum deviation = %g\n", max_d );
      }
    }
    else
    {
      RhinoApp().Print( L"Unable to find overlap intervals.\n" );
    }


    return success;
  }

C# (Rhino 4)

  public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
  {
    MRhinoGetObject go = new MRhinoGetObject();
    go.SetCommandPrompt( "Select curves to test" );
    go.SetGeometryFilter( IRhinoGetObject.GEOMETRY_TYPE_FILTER.curve_object );
    go.EnableSubObjectSelect( true );
    go.AcceptNothing();
    go.GetObjects( 2, 2 );
    if( go.CommandResult() != IRhinoCommand.result.success )
      return go.CommandResult();
    if( go.ObjectCount() != 2 )
      return IRhinoCommand.result.failure;


    IOnCurve crv_a = go.Object(0).Curve();
    if( crv_a == null )
      return IRhinoCommand.result.failure;


    IOnCurve crv_b = go.Object(1).Curve();
    if( crv_b == null )
      return IRhinoCommand.result.failure;


    double tol = context.m_doc.AbsoluteTolerance();
    int count = 0;


    double[,] int_a;
    double[,] int_b;
    double max_a, max_b, max_d;
    double min_a, min_b, min_d;


    bool rc = RhUtil.RhinoGetOverlapDistance(
                crv_a,      // curve A
                null,       // optional domain for curve A
                crv_b,      // curve B
                null,       // optional domain for curve B
                tol,        // tolerance for common normal detection
                0.0,        // limits acceptable overlap distance
                out count,  // overlap interval count (0 to 3)
                out int_a,  // curve A interval(s)
                out int_b,  // curve B interval(s)
                out max_a,  // curve B parameter at maximum overlap distance point
                out max_b,  // curve B parameter at maximum overlap distance point
                out max_d,  // maximum overlap distance
                out min_a,  // curve A parameter at minimum distance point
                out min_b,  // curve B parameter at minimum distance point
                out min_d ); // minimum distance between curves


    if( min_d <= OnUtil.On_ZERO_TOLERANCE )
      min_d = 0.0;


    if( rc == true )
    {
      if( count == 0 )
      {
        RhUtil.RhinoApp().Print( "Curves do not overlap.\n" );
      }
      else
      {
        context.m_doc.AddPointObject( crv_a.PointAt(max_a) );
        context.m_doc.AddPointObject( crv_b.PointAt(max_b) );
        context.m_doc.AddPointObject( crv_a.PointAt(min_a) );
        context.m_doc.AddPointObject( crv_b.PointAt(min_b) );
        context.m_doc.Redraw();


        MRhinoApp app = RhUtil.RhinoApp();
        for( int i = 0; i < count; i++ )
        {
          On3dPoint sp_a = crv_a.PointAt( int_a[i,0] );
          On3dPoint sp_b = crv_b.PointAt( int_b[i,0] );
          double sd = sp_a.DistanceTo( sp_b );


          On3dPoint ep_a = crv_a.PointAt( int_a[i,1] );
          On3dPoint ep_b = crv_b.PointAt( int_b[i,1] );
          double ed = ep_a.DistanceTo( ep_b );


          app.Print( string.Format("Overlap interval {0} of {1}:\n", i+1, count) );
          app.Print( string.Format("    start: distance = {0}\n", sd ) );
          app.Print( string.Format("           crvA({0}) = ({1})\n", int_a[i,0], sp_a) );
          app.Print( string.Format("           crvB({0}) = ({1})\n", int_b[i,0], sp_b) );
          app.Print( string.Format("      end: distance = {0}\n", ed ));
          app.Print( string.Format("           crvA({0}) = ({1})\n", int_a[i,1], ep_a) );
          app.Print( string.Format("           crvB({0}) = ({1})\n", int_b[i,1], ep_b) );
        }


        app.Print( string.Format("Minimum deviation = {0}\n", min_d) );
        app.Print( string.Format("Maximum deviation = {0}\n", max_d) );
      }
    }
    else
    {
      RhUtil.RhinoApp().Print( "Unable to find overlap intervals.\n" );
    }


    return IRhinoCommand.result.success;
  }

VB.NET (Rhino 4)

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


    Dim crv_a As IOnCurve = go.Object(0).Curve()
    Dim crv_b As IOnCurve = go.Object(1).Curve()
    If (crv_a Is Nothing Or crv_b Is Nothing) Then
      Return IRhinoCommand.result.failure
    End If


    Dim tol As Double = context.m_doc.AbsoluteTolerance()
    Dim count As Integer = 0


    Dim int_a As Double(,) = Nothing
    Dim int_b As Double(,) = Nothing
    Dim max_a As Double, max_b As Double, max_d As Double
    Dim min_a As Double, min_b As Double, min_d As Double


    Dim rc As Boolean = RhUtil.RhinoGetOverlapDistance( _
                  crv_a, Nothing, crv_b, Nothing, tol, 0.0, _
                  count, int_a, int_b, _
                  max_a, max_b, max_d, min_a, min_b, min_d)


    If (min_d <= OnUtil.On_ZERO_TOLERANCE) Then min_d = 0.0


    If (rc = True) Then
      If (count = 0) Then
        RhUtil.RhinoApp().Print("Curves do not overlap." + vbCrLf)
      Else
        context.m_doc.AddPointObject(crv_a.PointAt(max_a))
        context.m_doc.AddPointObject(crv_b.PointAt(max_b))
        context.m_doc.AddPointObject(crv_a.PointAt(min_a))
        context.m_doc.AddPointObject(crv_b.PointAt(min_b))
        context.m_doc.Redraw()


        Dim app As MRhinoApp = RhUtil.RhinoApp()
        For i As Integer = 0 To count - 1
          Dim sp_a As On3dPoint = crv_a.PointAt(int_a(i, 0))
          Dim sp_b As On3dPoint = crv_b.PointAt(int_b(i, 0))
          Dim sd As Double = sp_a.DistanceTo(sp_b)


          Dim ep_a As On3dPoint = crv_a.PointAt(int_a(i, 1))
          Dim ep_b As On3dPoint = crv_b.PointAt(int_b(i, 1))
          Dim ed As Double = ep_a.DistanceTo(ep_b)


          app.Print(String.Format("Overlap interval {0} of {1}:" + vbCrLf, i + 1, count))
          app.Print(String.Format("    start: distance = {0}" + vbCrLf, sd))
          app.Print(String.Format("           crvA({0}) = ({1})" + vbCrLf, int_a(i, 0), sp_a))
          app.Print(String.Format("           crvB({0}) = ({1})" + vbCrLf, int_b(i, 0), sp_b))
          app.Print(String.Format("      end: distance = {0}" + vbCrLf, ed))
          app.Print(String.Format("           crvA({0}) = ({1})" + vbCrLf, int_a(i, 1), ep_a))
          app.Print(String.Format("           crvB({0}) = ({1})" + vbCrLf, int_b(i, 1), ep_b))
        Next


        app.Print(String.Format("Minimum deviation = {0}" + vbCrLf, min_d))
        app.Print(String.Format("Maximum deviation = {0}" + vbCrLf, max_d))
      End If
    Else
      RhUtil.RhinoApp().Print("Unable to find overlap intervals." + vbCrLf)
    End If


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