Beispiel #1
0
        /// <summary>
        /// 计算矩形外某个点与矩形中点的连线,与矩形的相交点。
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="outerPoint"></param>
        /// <returns></returns>
        public static Point CalcCrossPoint(Rect rect, Point outerPoint)
        {
            //单元测试:
            //var res = CalcCrossPoint(new Point(300, 150), new Rect(0, 0, 200, 100));
            //if (res != new Point(200, 100)) throw new NotSupportedException();

            //res = CalcCrossPoint(new Point(100, 200), new Rect(0, 0, 200, 100));
            //if (res != new Point(100, 100)) throw new NotSupportedException();

            //res = CalcCrossPoint(new Point(100, -100), new Rect(0, 0, 200, 100));
            //if (res != new Point(100, 0)) throw new NotSupportedException();

            var area = GetRectArea(rect, outerPoint);

            Line line1 = new Line { A = rect.GetCenterPoint(), B = outerPoint };
            Line line2 = new Line();

            switch (area)
            {
                case RectLineDirection.Left:
                    line2.A = rect.TopLeft;
                    line2.B = rect.BottomLeft;
                    break;
                case RectLineDirection.Top:
                    line2.A = rect.TopLeft;
                    line2.B = rect.TopRight;
                    break;
                case RectLineDirection.Right:
                    line2.A = rect.TopRight;
                    line2.B = rect.BottomRight;
                    break;
                case RectLineDirection.Bottom:
                    line2.A = rect.BottomRight;
                    line2.B = rect.BottomLeft;
                    break;
                default:
                    break;
            }

            Point point = CalcCrossPoint(line1, line2);
            point.X = Round(point.X);
            point.Y = Round(point.Y);
            return point;
        }
Beispiel #2
0
        /// <summary>
        /// 返回矩形中心点与指定点的向量,与矩形相交的点。
        /// 简单地认为,这个点即是矩形边上最靠近指定点的点。
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static Point NearestPointOnLine(Rect rect, Point point)
        {
            Point res = point;

            if (rect.Contains(res))
            {
                var center = rect.GetCenterPoint();

                //没有斜率
                if (res.Y == center.Y)
                {
                    if (res.X < center.X)
                    {
                        res = RectAlgorithm.GetRectAbsolute(rect, new Point(0, 0.5));
                    }
                    else
                    {
                        res = RectAlgorithm.GetRectAbsolute(rect, new Point(1, 0.5));
                    }
                    return res;
                }
                else
                {
                    //使用向量继续向该方向延长。
                    Vector v = new Vector(res.X - center.X, res.Y - center.Y);
                    v *= 10000;
                    while (true)
                    {
                        res += v;
                        if (!rect.Contains(res)) break;
                    }
                }
            }

            res = CalcCrossPoint(rect, point);

            return res;
        }
Beispiel #3
0
        /// <summary>
        /// 按照中心点与四个角的连线,把空间分为四个区域。
        /// 返回点所在的区域。
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static RectLineDirection GetRectArea(Rect rect, Point point)
        {
            var c = rect.GetCenterPoint();
            var fromAngle = AngleFromCenter(c, point);

            var tl = AngleFromCenter(c, rect.TopLeft);
            var tr = AngleFromCenter(c, rect.TopRight);
            var br = AngleFromCenter(c, rect.BottomRight);
            var bl = AngleFromCenter(c, rect.BottomLeft);

            if (fromAngle > tl && fromAngle <= tr)
            {
                return RectLineDirection.Top;
            }
            else if (fromAngle > tr && fromAngle <= br)
            {
                return RectLineDirection.Right;
            }
            else if (fromAngle > br && fromAngle <= bl)
            {
                return RectLineDirection.Bottom;
            }
            else
            {
                return RectLineDirection.Left;
            }
        }