判断点、线、面之间的关系

https://www.cnblogs.com/xiaozhi_5638/p/4165353.html

/// <summary>
    /// 与几何相关的辅助类
    /// </summary>
    public static class GeometryHelper
    {
        /// <summary>
        /// 判断线段与多边形的关系
        /// </summary>
        /// <param name="line"></param>
        /// <param name="polygon"></param>
        /// <returns></returns>
        public static Intersection IntersectionOf(Line line, Polygon polygon)
        {
            if (polygon.Length == 0)
            {
                return Intersection.None;
            }
            if (polygon.Length == 1)
            {
                return IntersectionOf(polygon[0], line);
            }
            bool tangent = false;
            for (int index = 0; index < polygon.Length; index++)
            {
                int index2 = (index + 1) % polygon.Length;
                Intersection intersection = IntersectionOf(line, new Line(polygon[index], polygon[index2]));
                if (intersection == Intersection.Intersection)
                {
                    return intersection;
                }
                if (intersection == Intersection.Tangent)
                {
                    tangent = true;
                }
            }
            return tangent ? Intersection.Tangent : IntersectionOf(line.P1, polygon);
        }
        /// <summary>
        /// 判断点与多边形的关系
        /// </summary>
        /// <param name="point"></param>
        /// <param name="polygon"></param>
        /// <returns></returns>
        public static Intersection IntersectionOf(PointF point, Polygon polygon)
        {
            switch (polygon.Length)
            {
                case 0:
                    return Intersection.None;
                case 1:
                    if (polygon[0].X == point.X && polygon[0].Y == point.Y)
                    {
                        return Intersection.Tangent;
                    }
                    else
                    {
                        return Intersection.None;
                    }
                case 2:
                    return IntersectionOf(point, new Line(polygon[0], polygon[1]));
            }

            int counter = 0;
            int i;
            PointF p1;
            int n = polygon.Length;
            p1 = polygon[0];
            if (point == p1)
            {
                return Intersection.Tangent;
            }

            for (i = 1; i <= n; i++)
            {
                PointF p2 = polygon[i % n];
                if (point == p2)
                {
                    return Intersection.Tangent;
                }
                if (point.Y > Math.Min(p1.Y, p2.Y))
                {
                    if (point.Y <= Math.Max(p1.Y, p2.Y))
                    {
                        if (point.X <= Math.Max(p1.X, p2.X))
                        {
                            if (p1.Y != p2.Y)
                            {
                                double xinters = (point.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X;
                                if (p1.X == p2.X || point.X <= xinters)
                                    counter++;
                            }
                        }
                    }
                }
                p1 = p2;
            }

            return (counter % 2 == 1) ? Intersection.Containment : Intersection.None;
        }
        /// <summary>
        /// 判断点与直线的关系
        /// </summary>
        /// <param name="point"></param>
        /// <param name="line"></param>
        /// <returns></returns>
        public static Intersection IntersectionOf(PointF point, Line line)
        {
            float bottomY = Math.Min(line.Y1, line.Y2);
            float topY = Math.Max(line.Y1, line.Y2);
            bool heightIsRight = point.Y >= bottomY &&
                                 point.Y <= topY;
            //Vertical line, slope is divideByZero error!
            if (line.X1 == line.X2)
            {
                if (point.X == line.X1 && heightIsRight)
                {
                    return Intersection.Tangent;
                }
                else
                {
                    return Intersection.None;
                }
            }
            float slope = (line.X2 - line.X1) / (line.Y2 - line.Y1);
            bool onLine = (line.Y1 - point.Y) == (slope * (line.X1 - point.X));
            if (onLine && heightIsRight)
            {
                return Intersection.Tangent;
            }
            else
            {
                return Intersection.None;
            }
        }
        /// <summary>
        /// 判断直线与直线的关系
        /// </summary>
        /// <param name="line1"></param>
        /// <param name="line2"></param>
        /// <returns></returns>
        public static Intersection IntersectionOf(Line line1, Line line2)
        {
            //  Fail if either line segment is zero-length.
            if (line1.X1 == line1.X2 && line1.Y1 == line1.Y2 || line2.X1 == line2.X2 && line2.Y1 == line2.Y2)
                return Intersection.None;

            if (line1.X1 == line2.X1 && line1.Y1 == line2.Y1 || line1.X2 == line2.X1 && line1.Y2 == line2.Y1)
                return Intersection.Intersection;
            if (line1.X1 == line2.X2 && line1.Y1 == line2.Y2 || line1.X2 == line2.X2 && line1.Y2 == line2.Y2)
                return Intersection.Intersection;

            //  (1) Translate the system so that point A is on the origin.
            line1.X2 -= line1.X1; line1.Y2 -= line1.Y1;
            line2.X1 -= line1.X1; line2.Y1 -= line1.Y1;
            line2.X2 -= line1.X1; line2.Y2 -= line1.Y1;

            //  Discover the length of segment A-B.
            double distAB = Math.Sqrt(line1.X2 * line1.X2 + line1.Y2 * line1.Y2);

            //  (2) Rotate the system so that point B is on the positive X axis.
            double theCos = line1.X2 / distAB;
            double theSin = line1.Y2 / distAB;
            double newX = line2.X1 * theCos + line2.Y1 * theSin;
            line2.Y1 = (float)(line2.Y1 * theCos - line2.X1 * theSin); line2.X1 = (float)newX;
            newX = line2.X2 * theCos + line2.Y2 * theSin;
            line2.Y2 = (float)(line2.Y2 * theCos - line2.X2 * theSin); line2.X2 = (float)newX;

            //  Fail if segment C-D doesn't cross line A-B.
            if (line2.Y1 < 0 && line2.Y2 < 0 || line2.Y1 >= 0 && line2.Y2 >= 0)
                return Intersection.None;

            //  (3) Discover the position of the intersection point along line A-B.
            double posAB = line2.X2 + (line2.X1 - line2.X2) * line2.Y2 / (line2.Y2 - line2.Y1);

            //  Fail if segment C-D crosses line A-B outside of segment A-B.
            if (posAB < 0 || posAB > distAB)
                return Intersection.None;

            //  (4) Apply the discovered position to line A-B in the original coordinate system.
            return Intersection.Intersection;
        }
    }
    /// <summary>
    /// 几何体之间的关系类型
    /// </summary>
    public enum Intersection
    {
        None,
        Tangent,
        Intersection,
        Containment
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值