Curve.ClosestPoint difference between Rhinocommon and Grasshopper

Hi All I am try to find the equivalent in C# for
image
Curve.ClosestPoint is giving me a different result to the node, when using the same points to test from.
image
Green (Node), Ref (Code)

Have I misunderstood the ClosestPoint method?

Thanks

Brent

Hello
strange, can you post an example ? I use a lot this method and I don’t remember to have problems.

double t;
curve.ClosestPoint(point, out t);
A = curve.PointAt(t);

No problem here
test cuve cloest point.gh (12.0 KB)

Hi again - please see code below and I have attached GH and 3DM file
Perp Frames.gh (10.3 KB)
string points.3dm (31.0 KB)

   public class PerpFramesTwoCurves : GH_Component
        {
        /// <summary>
        /// Initializes a new instance of the PerpFramesTwoCurves class.
        /// </summary>
        public PerpFramesTwoCurves()
          : base("PerpFramesTwoCurves", "PF2C", "Description", "WSP", "Curves")
            {
            }

        /// <summary>
        /// Registers all the input parameters for this component.
        /// </summary>
        protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
            {
            pManager.AddCurveParameter("Control String", "C", "Control String", GH_ParamAccess.item);
            pManager.AddCurveParameter("Edge String", "E", "Edge String", GH_ParamAccess.item);
            pManager.AddIntegerParameter("Spacing", "S", "Spacing", GH_ParamAccess.item);
            pManager.AddBooleanParameter("Is Spacing", "I", "Is Spacing", GH_ParamAccess.item);
            }

        /// <summary>
        /// Registers all the output parameters for this component.
        /// </summary>
        protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
            {
            pManager.AddPointParameter("Control String Points", "CSP", "Control String Points", GH_ParamAccess.list);
            pManager.AddPointParameter("Edge String Points", "ESP", "Edge String Points", GH_ParamAccess.list);
            pManager.AddPlaneParameter("Control String Planes", "CSPL", "Control String Planes", GH_ParamAccess.list);
            pManager.AddPlaneParameter("Edge String Planes", "ESPL", "Edge String Planes", GH_ParamAccess.list);
            }

        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
            {
            Curve cs = null;
            Curve es = null;
            int val = 1;
            bool isSpacing = false;

            if (!DA.GetData(0, ref cs)) { return; }
            if (!DA.GetData(1, ref es)) { return; }
            if (!DA.GetData(2, ref val)) { return; }
            if (!DA.GetData(3, ref isSpacing)) { return; }

            //Get points on control string
            List<Point3d> controlStringPoints = new List<Point3d>();

            if (isSpacing)
                {
                double inc = 0;
                do
                    {
                    controlStringPoints.Add(cs.PointAt(inc));
                    inc += val;
                    }
                while (inc < cs.GetLength());
                controlStringPoints.Add(cs.PointAtEnd);
                }
            else
                {
                double[] d = cs.DivideByCount(val, true);
                foreach (double dd in d)
                    {
                    controlStringPoints.Add(cs.PointAt(dd));
                    }
                }
            List<Point3d> edgeStringPoints = new List<Point3d>();
            foreach (Point3d p in controlStringPoints)
                {
                bool test = es.ClosestPoint(p, out double d);
             

                if (test)
                    {
                    edgeStringPoints.Add(es.PointAtLength(d));
                    }
                }

            List<Line> lines = new List<Line>();
            List<Plane> csPlanes = new List<Plane>();
            List<Plane> esPlanes = new List<Plane>();

            if (controlStringPoints.Count == edgeStringPoints.Count)
                {
                for (int i = 0; i < controlStringPoints.Count; i++)
                    {
                    Line l = new Line(controlStringPoints[i], edgeStringPoints[i]);
                    lines.Add(l);

                    Plane pl = new Plane(controlStringPoints[i], l.Direction, Vector3d.ZAxis);
                    csPlanes.Add(pl);

                    Plane esp = new Plane(edgeStringPoints[i], pl.XAxis, pl.YAxis);
                    esPlanes.Add(esp);
                    }
                }

            DA.SetDataList(0, controlStringPoints);
            DA.SetDataList(1, edgeStringPoints);
            DA.SetDataList(2, csPlanes);
            DA.SetDataList(3, esPlanes);




           



                }

        /// <summary>
        /// Provides an Icon for the component.
        /// </summary>
        protected override System.Drawing.Bitmap Icon
            {
            get
                {
                //You can add image files to your project resources and access them like this:
                // return Resources.IconForThisComponent;
                return null;
                }
            }

        /// <summary>
        /// Gets the unique ID for this component. Do not change this ID after release.
        /// </summary>
        public override Guid ComponentGuid
            {
            get { return new Guid("6e4b1bf4-ec99-44df-9ce5-bab5a884c982"); }
            }
        }

Any info/tips is greatly appreciated.

Thanks

It is not pointatlenght but pointat!!
The first need a length and the second a parameter. Both double but not the same

1 Like

Thanks so much for that!!!