最近项目开发一个地图的服务端程序,需要 计算点,线,面与矩形是否有相交,
起初遇到这个问题脑袋里很混乱不知如何下手,静下心来仔细考虑,其实问题也不复杂.分三个步骤可以解决此问题
1.判断组成点,线,面的点元素是否在矩形内
  假设矩形的近点:P1 远点:P2,要判断一个新的坐标点Px是否在矩形内,只要判断Px的坐标和P1,P2的大小就可以了代码如下

点是否在矩形内
        /// <summary>
        /// 点是否与矩形有相交
        /// </summary>
        /// <param name="cPoint">当前点</param>
        /// <param name="p1">矩形近点</param>
        /// <param name="p3">矩形远点</param>
        /// <returns></returns>
        public static bool PointCheck(MapPoint cPoint, MapPoint p1, MapPoint p3)
        {
            bool blResult = (cPoint.X >= p1.X && cPoint.X <= p3.X) && (cPoint.Y >= p1.Y && cPoint.Y <= p3.Y);
            return blResult;
        }

2.如果是线段还需要在判断线段与矩形的四条边是否有相交
  需要判断做成多段线,多边形 的线段 与组成矩形的四条线段是否相交(几何原理:如果两条线段相交,那么一条线段的两个端点必定在另一条线段的两侧)

线段与矩形的四条边是否有相交
        /// <summary>
        /// 检查线段与矩形的四条边是否有相交
        /// </summary>
        /// <param name="points"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="p4"></param>
        /// <returns></returns>
        protected bool Check4Line(List<MapPoint> points, MapPoint p1, MapPoint p2, MapPoint p3, MapPoint p4)
        {
            bool blResult = false;
            if (points == null | (points != null && points.Count < 2))
            {
                return false;
            }
            for (int i = 0; i < points.Count - 1; i++)
            {
                var ptCurr = points[i];
                var ptNext = points[i + 1];
                blResult = CommMeth.Intersect(ptCurr, ptNext, p1, p2);//与矩形的第1条线段相比较
                if (blResult) break;
                blResult = CommMeth.Intersect(ptCurr, ptNext, p2, p3);//与矩形的第2条线段相比较
                if (blResult) break;
                blResult = CommMeth.Intersect(ptCurr, ptNext, p3, p4);//与矩形的第3条线段相比较
                if (blResult) break;
                blResult = CommMeth.Intersect(ptCurr, ptNext, p4, p1);//与矩形的第3条线段相比较
                if (blResult) break;
            }
            return blResult;
        }
两条线段是否相交
        /// <summary>
        /// 两条线段是否相交
        /// </summary>
        /// <param name="p1">第1条线段起点</param>
        /// <param name="p2">第1条线段终点</param>
        /// <param name="p3">第2条线段起点</param>
        /// <param name="p4">第2条线段终点点</param>
        /// <returns></returns>
        public static bool Intersect(MapPoint p1, MapPoint p2, MapPoint p3, MapPoint p4)
        {
            double x1 = p1.X;
            double y1 = p1.Y;
            double x2 = p2.X;
            double y2 = p2.Y;
            double x3 = p3.X;
            double y3 = p3.Y;
            double x4 = p4.X;
            double y4 = p4.Y;
            //依据:两条线段不相交,必定是存在其中一条线段的两端点在在另一条线段所在直线的同側.所以要分别考虑两种情况.
            if (DirectionV3(x1, y1, x2, y2, x3, y3) * DirectionV3(x1, y1, x2, y2, x4, y4) > 0)//一条线段的两点全在另一条线段的同一側
                return false;
            if (DirectionV3(x3, y3, x4, y4, x1, y1) * DirectionV3(x3, y3, x4, y4, x2, y2) > 0)//
                return false;
            return true;
        }
        private static double DirectionV3(double x1, double y1, double x2, double y2, double x3, double y3)
        {
            //判断点在直线的上或下及左或右側.具体是采用点斜式求出一条线段所在直线的方程,然后将点代如求值进行判断 参照网站:计算几何算法概览
            return x1 * y3 + x2 * y1 + x3 * y2 - x1 * y2 - x2 * y3 - x3 * y1;
        }

3.最后如果是面(多边形)还需要判断多边形是否全包括了矩形(即矩形的四个点,需要在多边形内)
在经过1,2两个步骤后,其实只需要判断矩形的其中一个点是否在多边形内即可(不用判断矩形的四个点)

点是否在多边形内
public static bool PointInPolygon(MapPoint point, MapPoint[] _vertices)
        {
            var j = _vertices.Length - 1;
            var oddNodes = false;
            for (var i = 0; i < _vertices.Length; i++)
            {
                if (_vertices[i].Y < point.Y && _vertices[j].Y >= point.Y ||
                    _vertices[j].Y < point.Y && _vertices[i].Y >= point.Y)
                {
                    if (_vertices[i].X +
                        (point.Y - _vertices[i].Y) / (_vertices[j].Y - _vertices[i].Y) * (_vertices[j].X - _vertices[i].X) < point.X)
                    {
                        oddNodes = !oddNodes;
                    }
                }
                j = i;
            }
            return oddNodes;
        }

 

posted on 2012-12-25 21:21  Jasoncheng  阅读(2403)  评论(0编辑  收藏  举报