/// <summary> /// Попадает ли точка внутрь полилинии. /// Предполагается, что полилиния имеет замкнутый контур. /// Подходит для полилиний с дуговыми сегментами. /// Работает медленнее чем IsPointInsidePolygon(), примерно в 10 раз. /// </summary> /// <param name="pt"></param> /// <param name="onIsInside">Если исходная точка лежит на полилинии, то считать, что она внутри или нет: True - внутри, False - снаружи.</param> /// <param name="pl"></param> /// <exception cref="Exceptions.ErrorException">Не удалось определить за несколько попыток.</exception> public static bool IsPointInsidePolyline([NotNull] this Polyline pl, Point3d pt, bool onIsInside = false) { using (var ray = new Ray()) { ray.BasePoint = pt; var vec = new Vector3d(0, 1, pt.Z); ray.SecondPoint = pt + vec; using (var ptsIntersects = new Point3dCollection()) { bool isContinue; var isPtOnPolyline = false; var countWhile = 0; do { using (var plane = new Plane()) { pl.IntersectWith(ray, Intersect.OnBothOperands, plane, ptsIntersects, IntPtr.Zero, IntPtr.Zero); } isContinue = ptsIntersects.Cast <Point3d>().Any(p => { if (pt.IsEqualTo(p)) { isPtOnPolyline = true; return(true); } var param = pl.GetParameterAtPointTry(p); return(Math.Abs(param % 1) < 0.0001); }); if (isPtOnPolyline) { return(onIsInside); } if (isContinue) { vec = vec.RotateBy(0.01, Vector3d.ZAxis); ray.SecondPoint = pt + vec; ptsIntersects.Clear(); countWhile++; if (countWhile > 3) { throw new ErrorException(new Errors.Error( "Не определено попадает ли точка внутрь полилинии.", pt.GetRectangleFromCenter(3), Matrix3d.Identity, System.Drawing.SystemIcons.Error)); } } } while (isContinue); return(NetLib.MathExt.IsOdd(ptsIntersects.Count)); } } }