Project points on a polyline or featureline

Greetings,
I would like to project points in a normal direction on polyline or featureline beside it.
as shown in figure

For Feature Lines, I’m pretty sure there is a node to get the location of a point with station/offset. So once you have the station, then get a point on the Feature Line at that distance. I’m not at my PC so I can’t remember the exact node name, but it’s something like FeatureLine.PointAtDistance or something. Or you might need to get a coordinate system instead, but then you just use CoordinateSystem.Origin to get a point.

Use Geomotry.ClosestPointTo node. It will find naturally a point at perpendicular from input.
Then you can find the Vector from the line or Vector.ByTwoPoints

hi
1- if featureline: (As @mzjensen wrote) you can get the station of this point then used the node to get the point at frature line at this station, it work in condtion “the feature line and base line is paralle”. if not it will not be work.
2- if polycurve: (As @Hyunu_Kim wrote) use ClosestPointTo node, but fist get the projection of the polycurve to xy plane then use ClosestPointTo node.


image

3- i have Zerotouch node created by C# to get the ptojection of the node to the polycurve
image

  [MultiReturn(new[] { "point_AT_PloyCurve", "Angle", "Plane" })] // DesignScript.Runtime   
    public static Dictionary<string, object> Get_point_AT_PolyCurve(PolyCurve polyCurve, Point point)

    {

        Point point_AT_PloyCurve= CoordinateSystem.ByOrigin(point).Origin;
        List<double> rot = new List<double>();
        double c1;
        double c2;
        double c3;
        double c4;
        double c5;
        c1 = Get_Angle(polyCurve, point, 0, 180, 30);
        c2 = Get_Angle(polyCurve, point, c1 - 15, c1 + 15, 1);
        c3 = Get_Angle(polyCurve, point, c2 - 0.5, c2 + 0.5, 0.01); 
        c4 = Get_Angle(polyCurve, point, c3 - 0.005, c3 + 0.005, 0.001);
        c5 = Get_Angle(polyCurve, point, c3 - 0.0005, c3 + 0.0005, 0.0001);
   
        CoordinateSystem Cs = CoordinateSystem.ByOrigin(point).Rotate(point, Vector.ZAxis(), c5);



        Plane YZPlane = Cs.YZPlane;
     
        foreach (Geometry geometry in polyCurve.Intersect((Geometry)YZPlane))
        {
            if (geometry is Point)
            {
                point_AT_PloyCurve = geometry as Point;
              
            }
        }
        return new Dictionary<string, object>
                                {

                                { "point_AT_PloyCurve", point_AT_PloyCurve },
                                { "Angle", c5 },
                                {"Plane",YZPlane },
                                };     
    }

   
    public static double Get_Angle (PolyCurve polyCurve, Point point, double S, double E,double SStep)

    {

        List<CoordinateSystem> Css = new List<CoordinateSystem>();
        List<double> Sita = new List<double>();
        List<Plane> ListPlane = new List<Plane>();
        CoordinateSystem.ByOrigin(point);
        List<double> Parameters = new List<double>();
        List<double> rot = new List<double>();
        List<Point> ListPoint = new List<Point>();
        List<Point> Pointt = new List<Point>();
        List<double > length = new List<double>();
        Plane Minplan ;

        for (double i = S; i < E; i = i + SStep)
        {
            Sita.Add(i);
        }

        int kk = 0;
        foreach (Curve Cur in polyCurve.Curves())
        {
            kk++;
            if (kk == 1)
            {
                Pointt.Add(Cur.PullOntoPlane(Plane.XY()).StartPoint);
            }

            Pointt.Add(Cur.PullOntoPlane(Plane.XY()).EndPoint);           
        }

        PolyCurve PolycurvePlane = PolyCurve.ByPoints(Pointt);

        foreach (double item in Sita)
        {
           CoordinateSystem Cs = CoordinateSystem.ByOrigin(point).Rotate(point, Vector.ZAxis(), item);
            Plane YZPlane = Cs.YZPlane;
               
            foreach (Geometry geometry in PolycurvePlane.Intersect((Geometry)YZPlane))
            {
                if (geometry is Point)
                {
                    Point point2 = geometry as Point;

                    Parameters.Add(PolycurvePlane.ParameterAtPoint(point2));
                    ListPoint.Add(point2);
                    ListPlane.Add(YZPlane);
                }
            }
        }

        Dictionary<string, object> s = Get_Point_CoordinateSystem_PolyCurve(PolycurvePlane as PolyCurve, Parameters);

        foreach (KeyValuePair<string, object> x in s)
        {
            if (x.Key == "Vertical_CS")
            {
                Css = (List<CoordinateSystem>)x.Value;
            }
        }

        foreach (Point  p1 in ListPoint)
        {
            length.Add( Line.ByStartPointEndPoint(point, p1).Length);
        }
        int Indexx = length.IndexOf(length.Min());

       Minplan = ListPlane[Indexx];
       Vector X=  Minplan.ToCoordinateSystem().XAxis ;
       double Angle = Vector.YAxis().AngleAboutAxis(X,Vector.ZAxis());

        return Angle;
    }

I’m not sure that this statement is correct. The station value will be taken where the point is perpendicular to the baseline, which is @War10ck’s intent. The geometry of the offset curve does not matter, and in fact the original post did not mention an offset curve, only points. In the screenshot below, the blue line is the Feature Line and the yellow circles are the offset points. Getting the station value of the points and then creating corresponding points along the Feature Line produces the desired result.

2 Likes

Here’s an example:

2 Likes

you are right (featureline.getdistanceoffsetelevationbypoint) node can do that. Brilliant

This is what I did: