计算平面上二条线段的相交点

在GDI+时,需要用到的一些图片算法片段,网上关于这些计算的比较难找到.因此特放到网上,便于大家参考.

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DrawLibrary
{
    public enum EndPoint : short
    {
        Start = 0,
        End = 1
    }
    public class Line    {
        Point _BeginPoint;
        Point _EndPoint;

        public Line(Point BeginPoint, Point EndPoint)
        {
            _BeginPoint = BeginPoint;
            _EndPoint = EndPoint;
        }

        public Point BeginPoint
        {
            get { return _BeginPoint; }
        }
        public Point EndPoint
        {
            get { return _EndPoint; }
            set
            {
                _EndPoint = value;
            }
        }

      }
    public class Utils
    {
         public static PointF PointToF(Point p)
        {
            return new PointF(p.X, p.Y);
        }

         public static Point PointFromF(PointF p)
        {
            return new Point((int)p.X, (int)p.Y);
        }

               public static EndPoint OtherEndpoint(EndPoint which)
        {
            return (which == EndPoint.Start) ? EndPoint.End : EndPoint.Start;
        }

             public static float Distance(Point p1, Point p2)
        {
            return (float)Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
        }


        public static int Area(Rectangle rect)
        {
            return rect.Width * rect.Height;
        }

          public static Point CenterOfRectangle(Rectangle rect)
        {
            return new Point(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2));
        }

      //计算一条线段与一个矩形的相交点
        public static Point CalculateIntersection(Line line, Rectangle rect)
        {
            if (rect.IsEmpty)
                throw new ArgumentException("不能与空区域进行计算.");

            // corners
            Point topLeft = new Point(rect.Left, rect.Top);
            Point topRight = new Point(rect.Right, rect.Top);
            Point bottomLeft = new Point(rect.Left, rect.Bottom);
            Point bottomRight = new Point(rect.Right, rect.Bottom);

            // boundaries
            Line top = new Line(topLeft, topRight);
            Line left = new Line(topLeft, bottomLeft);
            Line right = new Line(topRight, bottomRight);
            Line bottom = new Line(bottomLeft, bottomRight);

            // calculate intersection between line and any boundary
            Point intersection = new Point();
            if (intersection.IsEmpty) intersection = CalculateIntersection(line, top);
            if (intersection.IsEmpty) intersection = CalculateIntersection(line, left);
            if (intersection.IsEmpty) intersection = CalculateIntersection(line, right);
            if (intersection.IsEmpty) intersection = CalculateIntersection(line, bottom);
            return intersection;
        }

//计算二条线段的相交点
        public static Point CalculateIntersection(Line line1, Line line2)
        {
            Point p1, p2, p3, p4;
            p1 = NormalizeBeginPoint(line1.BeginPoint, line1.EndPoint);
            p2 = NormalizeEndPoint(line1.BeginPoint, line1.EndPoint);
            p3 = NormalizeBeginPoint(line2.BeginPoint, line2.EndPoint);
            p4 = NormalizeEndPoint(line2.BeginPoint, line2.EndPoint);

            int ua_num = (p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X);
            int ub_num = (p2.X - p1.X) * (p1.Y - p3.Y) - (p2.Y - p1.Y) * (p1.X - p3.X);
            int denom = (p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y);

            if (denom == 0)
            {
                if (ua_num == 0 && ub_num == 0)
                {
                    Point begin1 = NormalizeBeginPoint(line1.BeginPoint, line1.EndPoint);
                    Point begin2 = NormalizeBeginPoint(line2.BeginPoint, line2.EndPoint);
                    return NormalizeEndPoint(begin1, begin2);
                }
                else
                {
                    return Point.Empty;
                }
            }

           
            double ua = ua_num / (double)denom;
            double ub = ub_num / (double)denom;
            if (0 <= ua && ua <= 1 && // does line segment line1 contain intersecting pt?
                0 <= ub && ub <= 1)   // does line segment line2 contain intersecting pt?
            {
                // line segments intersect
                Point intersection = new Point();
                intersection.X = (int)(p1.X + ua * (p2.X - p1.X));
                intersection.Y = (int)(p1.Y + ua * (p2.Y - p1.Y));
                return intersection;
            }
            else
            {
                   return Point.Empty;
            }
        }

        public static double CalculateAngleInRadians(Line line)
        {
            if (line.BeginPoint.IsEmpty || line.EndPoint.IsEmpty) throw new ArgumentException("Invalid line end points");

            double hyp = Utils.Distance(line.BeginPoint, line.EndPoint);
            if (hyp == 0) throw new ArgumentException("Can't calculate angle for zero-length line");

            double theta = (float)Math.Asin((line.EndPoint.Y - line.BeginPoint.Y) / hyp);
            if (line.EndPoint.X < line.BeginPoint.X) theta = Math.PI - theta;
            return theta;
        }

        public static double DegreesToRadians(double degrees)
        {
            return (degrees / 360) * (2 * Math.PI);
        }

        public static double RadiansToDegrees(double radians)
        {
            return 360 * (radians / (2 * Math.PI));
        }


        private static Line NormalizeLine(Line line)
        {
            return new Line(
                NormalizeBeginPoint(line.BeginPoint, line.EndPoint),
                NormalizeEndPoint(line.BeginPoint, line.EndPoint)
            );
        }

        private static Point NormalizeBeginPoint(Point p1, Point p2)
        {
            if (p1.X < p2.X) return p1;
            if (p1.X > p2.X) return p2;
            if (p1.Y < p2.Y) return p1;
            if (p1.Y > p2.Y) return p2;
            return p1; // p1 == p2
        }

        private static Point NormalizeEndPoint(Point p1, Point p2)
        {
            if (p1.X < p2.X) return p2;
            if (p1.X > p2.X) return p1;
            if (p1.Y < p2.Y) return p2;
            if (p1.Y > p2.Y) return p1;
            return p2; // p1 == p2
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值