|
@@ -1813,14 +1813,98 @@ namespace SAGA.RevitUtils.Extends
|
|
/// </returns>
|
|
/// </returns>
|
|
public static int PointInPolygonByRay(this XYZ inputPoint, List<XYZ> points)
|
|
public static int PointInPolygonByRay(this XYZ inputPoint, List<XYZ> points)
|
|
{
|
|
{
|
|
- List<Line> lines = new List<Line>();
|
|
|
|
- for (int i = 0; i < points.Count; i++)
|
|
|
|
|
|
+ #region 老方法
|
|
|
|
+ //List<Line> lines = new List<Line>();
|
|
|
|
+ //for (int i = 0; i < points.Count; i++)
|
|
|
|
+ //{
|
|
|
|
+ // var start = points[i];
|
|
|
|
+ // var end = points[(i + 1) % points.Count];
|
|
|
|
+ // lines.Add(Line.CreateBound(start, end));
|
|
|
|
+ //}
|
|
|
|
+ //return PointInPolygonByRay(inputPoint, lines);
|
|
|
|
+ #endregion
|
|
|
|
+ bool isEven = true;
|
|
|
|
+ double baseX = inputPoint.X;
|
|
|
|
+ double baseY = inputPoint.Y;
|
|
|
|
+ var total = points.Count;
|
|
|
|
+ for (int i = 0; i < total; i++)
|
|
{
|
|
{
|
|
|
|
+ var endIndex = (i + 1) % total;
|
|
var start = points[i];
|
|
var start = points[i];
|
|
- var end = points[(i + 1) % points.Count];
|
|
|
|
- lines.Add(Line.CreateBound(start, end));
|
|
|
|
|
|
+ var end = points[endIndex];
|
|
|
|
+ if (start.IsEqual2(inputPoint) || end.IsEqual2(inputPoint))
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ bool isEndIntersection = false;//判断交点是否是end
|
|
|
|
+ //判断给定线的端点是否在射线两侧,利用水平线的性质
|
|
|
|
+ if ((start.Y.IsLessEq(baseY) && baseY.IsLessEq(end.Y)) || (end.Y.IsLessEq(baseY) && baseY.IsLessEq(start.Y)))
|
|
|
|
+ {
|
|
|
|
+ double minX = Math.Min(start.X, end.X);
|
|
|
|
+ double maxX = Math.Min(start.X, end.X);
|
|
|
|
+ if (start.Y.IsEqual(end.Y))
|
|
|
|
+ {
|
|
|
|
+ #region 与给定射线共线处理
|
|
|
|
+ //给定线段与射线平行
|
|
|
|
+ if (minX.IsLessEq(baseX) && baseX.IsLessEq(maxX))
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if (baseX.IsLess(minX))
|
|
|
|
+ {
|
|
|
|
+ isEndIntersection = true;
|
|
|
|
+ }
|
|
|
|
+ #endregion
|
|
|
|
+ }
|
|
|
|
+ else if (baseX.IsLessEq(maxX))
|
|
|
|
+ {
|
|
|
|
+ double c = (baseY - start.Y) / (end.Y - start.Y);
|
|
|
|
+ double useX = start.X + c * (end.X - start.X);
|
|
|
|
+ if (useX.IsEqual(baseX))
|
|
|
|
+ {
|
|
|
|
+ //给定点,在线上
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ if (baseX.IsLessEq(useX))
|
|
|
|
+ {
|
|
|
|
+ //这种情况下肯定相交
|
|
|
|
+ var intersectionPoint = new XYZ(useX, baseY,0);
|
|
|
|
+ if (end.IsEqual2(intersectionPoint))
|
|
|
|
+ {
|
|
|
|
+ //开始点不处理
|
|
|
|
+ isEndIntersection = true;
|
|
|
|
+ }
|
|
|
|
+ else if (start.IsEqual2(intersectionPoint))
|
|
|
|
+ {
|
|
|
|
+ isEndIntersection = false;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ isEven = !isEven;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (isEndIntersection)
|
|
|
|
+ {
|
|
|
|
+ var end2 = points[(endIndex + 1) % total];
|
|
|
|
+ if (!baseY.IsEqual(end2.Y))
|
|
|
|
+ {
|
|
|
|
+ var point = points.GetFirstElement(endIndex, p => !p.Y.IsEqual(baseY), false);
|
|
|
|
+ if (end2.Y.IsLess(baseY) == point.Y.IsThan(baseY))
|
|
|
|
+ {
|
|
|
|
+ //排除同时相等的情况
|
|
|
|
+ if (!end2.Y.IsEqual(baseY) && !point.Y.IsEqual(baseY))
|
|
|
|
+ {
|
|
|
|
+ isEven = !isEven;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- return PointInPolygonByRay(inputPoint, lines);
|
|
|
|
|
|
+ return isEven ? -1 : 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|