Пример #1
0
        public static Point3d?GetOrthoNormalPoint(this Polyline pline, Point3d point, Plane plane, bool nullForOutOfRange = true)
        {
            point = point.OrthoProject(pline.GetPlane());

            List <Point3d> res      = new List <Point3d>();
            var            segments = pline.GetSegments();
            int            i        = 0;

            foreach (var s in segments)
            {
                if (point.IsEqualTo(s.StartPoint, Tolerance.Global))
                {
                    return(point);
                }

                Vector3d vector     = point - s.StartPoint;
                Vector3d segmVector = s.EndPoint - s.StartPoint;
                double   cos        = segmVector.GetCos2d(vector);

                double length = s.GetLength(s.GetParameterOf(s.StartPoint),
                                            s.GetParameterOf(s.EndPoint), Tolerance.Global.EqualPoint);

                ///////////////////////////////////////////////
                if (!nullForOutOfRange)
                {
                    if (i == 0 && cos < 0d)
                    {
                        return(s.StartPoint);
                    }
                    if (i == segments.Count() - 1 && cos > 0 && cos * vector.Length > segmVector.Length)
                    {
                        return(s.EndPoint);
                    }
                    i++;
                }
                ///////////////////////////////////////////////

                if (cos >= 0d && cos * vector.Length <= segmVector.Length)
                {
                    if (s is CircularArc3d)
                    {
                        CircularArc3d arc3d       = (CircularArc3d)s;
                        Arc           arc         = arc3d.ConvertToArc();
                        Point3d?      normalPoint = arc.GetOrthoNormalPoint(point, nullForOutOfRange);
                        if (normalPoint.HasValue)
                        {
                            res.Add(normalPoint.Value);
                        }
                    }
                    else if (s is LineSegment3d)
                    {
                        LineSegment3d line3d      = (LineSegment3d)s;
                        Line          line        = line3d.ConvertToLine();
                        Point3d?      normalPoint = line.GetOrthoNormalPoint(point, plane, nullForOutOfRange);
                        if (normalPoint.HasValue)
                        {
                            res.Add(normalPoint.Value);
                        }
                    }
                }
            }
            if (res.Count == 0)
            {
                return(null);
            }
            else
            {
                res.Sort((p1, p2) => Comparer <double> .Default.Compare((point - p1).Length, (point - p2).Length));
                return(res[0]);
            }
        }