Grasshopper

algorithmic modeling for Rhino

Using Surface.ClosestPoint to determine whether a point is on/inside a surface

Hi all,

I am trying to write a scripting component that determines whether a point is on a surface or outside. It works quite well using standard GH components, but I would like to pack it into a single scripting component.

The weird thing is: the Surface.ClosestPoint method seems to think any point inside the u,v domain is on  the surface, so if a point is outside the surface, but inside the surface's u,v domain, the closest point is equal to the original point.

Grasshopper's "Surface CP" component seems to work quite well...

Does anyone have an idea what I am missing here?

My source code is:

private void RunScript(Point3d P, Surface S, double t, ref object PI, ref object PO, ref object ii)
  {
    double u;
    double v;

    if (S.ClosestPoint(P, out u, out v))
    {
      Point3d tP = S.PointAt(u, v);
      double d = P.DistanceTo(tP);

      if (d <= t)
      {
        // distance is within tolerance
        PI = P;
        ii = true;
      }
      else
      {
        // distance is larger than tolerance
        PO = P;
        ii = false;
      }
    }
  }

this is the GH defnition

and this is the Rhino output:

(there is an old discussion on the forum that seems to end without a real result..., see http://www.grasshopper3d.com/forum/topics/surface-closest-point-and...)

Views: 5223

Attachments:

Replies to This Discussion

What Grasshopper calls a "trimmed surface" is actually a Brep with one face, not a "Surface" data type. Surfaces (in RhinoCommon) are always untrimmed, which would explain your result. Try Brep.ClosestPoint()

Andrew is absolutely right. The Surface Datatype doesn't store trimm curves. Brep which means boundary representation does...it's a Surface with specified boundary also known as a trimmed Surface.

This means for your script, that in RhinoCommon all trimmed Surfaces should be casted as Brep type. See the difference in the pic below:

also the script works a little bit different, cause you have to run trough all faces of the brep...in your case obviously there is just one.

Cheers

FF

Attachments:

hi,

could you explain the line code

double tolerance = (t == 0) ? doc.ModelAbsoluteTolerance : t;

it's shorthand for if-then-else,

see http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.100%29.aspx

written out, it would be something like

double tolerance;
if (t==0)
  tolerance=doc.ModelAbsoluteTolerance;
else
  tolerance=t;

nice,

thanks

Excellent!
Thanks a lot.

 

Just for clarification: I was wondering a bit why you used BrepFace.DuplicateFace.

My a assumption is that you did this so you can use the Brep.ClosestPoint method. Is that right? Or is there something else behind it?

 

Best regards

Stefan

 

-------------------------------------------------------------

Here is the code including comments to illustrate what I mean:

 

private void RunScript(Brep B, Point3d P, double t, ref object Pi, ref object Po)
  {
    double d = double.MaxValue;
    double tolerance = (t == 0) ? doc.ModelAbsoluteTolerance : t;

    foreach(BrepFace f in B.Faces)
    {
      // short version:
      double dist = f.DuplicateFace(false).ClosestPoint(P).DistanceTo(P);

      /*
      // long version fo the uninitiated:

      // cast BrepFace to Brep because BrepFace has only a method
      //   public bool ClosestPoint(Point3d testPoint, out double u, out double v)
      // which is somewhat cumbersome to use
      Brep currentFaceAsBrep = f.DuplicateFace(false);

      // with a Brep we can directly use a method
      //   public Point3d ClosestPoint(Point3d testPoint)
      Point3d clPoint = currentFaceAsBrep.ClosestPoint(P);

      // now compute the distance
      double dist = clPoint.DistanceTo(P);
      */

      if(dist < d)
        d = dist;
    }

    if(d <= tolerance)
      Pi = P;
    else
      Po = P;
  }

Hi Stefan, actually i didn't have to DuplicateFace...just realized right now. The BrepFace had the same method...this is because i wrote it quickly an didn't take a look at the sdk...happens sometime ;-)

The comments are all right...you got every step of the script.

Have a nice day

FF

RSS

About

Translate

Search

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service