点是否在矩形中判断

 

 

 

方法1,

只要判断该点的横坐标和纵坐标是否夹在矩形的左右边和上下边之间。

例如:矩形四个顶点P1,P2,P3,P4,判断P是否包含在矩形中,

只需要判断:|P2P|×|P1P2|*|P3P|×|P3P4|<=0 And |P1P|×|P1P4|*|P2P|×|P2P3|<=0

 
public bool isContain(MPoint mp1,MPoint mp2,MPoint mp3,MPoint mp4,MPoint mp)
        {
            if (Multiply(mp, mp1, mp2) * Multiply(mp,mp4, mp3) <= 0

                && Multiply(mp, mp4, mp1) * Multiply(mp, mp3, mp2) <= 0)
                return true;

            return false;
        }
        // 计算叉乘 |P0P1| × |P0P2|
        private double Multiply(MPoint p1, MPoint p2, MPoint p0)
        {
            return ((p1.X - p0.X) * (p2.Y - p0.Y) - (p2.X - p0.X) * (p1.Y - p0.Y));
        }

 

方法2,采用点是否包含在多边形中判断

 

  以该点为顶点,做一条射线,使得矩形四个顶点中任意一点都不在射线上  
  若该射线与矩形有且仅有一个交点,则在矩形内,若有零个或两个焦点,则在矩形外   
   
  至于射线,可以通过选择肯定在矩形外的一点和已知点练成线段来构成  
  这个只要点坐标不在矩形的left-right,bottom-top范围内即可  

 

           Test t = new Test();
            MPoint mp = new MPoint();
            mp.X =101;
            mp.Y = l01;
            if(t.InPolygon(mp))
                MessageBox.Show("包含点!");
            else
                MessageBox.Show("不包含点!");

 

 public class Test
    {
        const double INFINITY = 1e10;
        const double ESP = 1e-5;

        MPolygon mpolygon = new MPolygon();
        public Test()
        {
            MPoint mpoint = new MPoint();
            mpoint.X = 100;
            mpoint.Y = 100;
            mpolygon.Points.Add(mpoint);
            mpoint = new MPoint();
            mpoint.X = 100;
            mpoint.Y = 200;
            mpolygon.Points.Add(mpoint);
            mpoint = new MPoint();
            mpoint.X = 200;
            mpoint.Y = 210;
            mpolygon.Points.Add(mpoint);
            mpoint = new MPoint();
            mpoint.X = 150;
            mpoint.Y = 120;
            mpolygon.Points.Add(mpoint);
            mpoint = new MPoint();
            mpoint.X = 120;
            mpoint.Y = 100;
            mpolygon.Points.Add(mpoint);
        }
        // 计算叉乘 |P0P1| × |P0P2|
        private double Multiply(MPoint p1, MPoint p2, MPoint p0)
        {
            return ((p1.X - p0.X) * (p2.Y - p0.Y) - (p2.X - p0.X) * (p1.Y - p0.Y));
        }
        // 判断线段是否包含点point
        // 断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0 且 Q 在以 P1,P2为对角顶点的矩形内
        private bool IsOnline(MPoint point, MLine line)
        {
            return ((Math.Abs(Multiply(line.P1, line.P2, point)) < ESP) &&
            ((point.X - line.P1.X) * (point.X - line.P2.X) <= 0) &&
            ((point.Y - line.P1.Y) * (point.Y - line.P2.Y) <= 0));
        }
        // 判断线段相交
        // 设以线段 P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如果R和T不相交,显然两线段不会相交
        // 判断P1P2跨立Q1Q2的依据是:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0
        // 判断Q1Q2跨立P1P2的依据是:( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1 ) × ( Q2 - P1 ) >= 0
        private bool Intersect(MLine L1, MLine L2)
        {
            return((Math.Max(L1.P1.X, L1.P2.X) >= Math.Min(L2.P1.X, L2.P2.X)) && (Math.Max(L2.P1.X, L2.P2.X) >= Math.Min(L1.P1.X, L1.P2.X)) &&
            (Math.Max(L1.P1.Y, L1.P2.Y) >= Math.Min(L2.P1.Y, L2.P2.Y)) && (Math.Max(L2.P1.Y, L2.P2.Y) >= Math.Min(L1.P1.Y, L1.P2.Y)) &&
            (Multiply(L2.P1, L1.P2, L1.P1) * Multiply(L1.P2, L2.P2, L1.P1) >= 0) && (Multiply(L1.P1, L2.P2, L2.P1) * Multiply(L2.P2, L1.P2, L2.P1) >= 0));
        }
        // 判断点在多边形内

        public bool InPolygon(MPoint point)
        {
            int n = mpolygon.Points.Count;
            int count = 0;
            MLine line = new MLine();
            line.P1 = point;
            line.P2.Y = point.Y;
            line.P2.X = - INFINITY; 
            for( int i = 0; i < n; i++ ) {
                // 得到多边形的一条边
                MLine side = new MLine();
                side.P1 = mpolygon.Points[i];
                side.P2 = mpolygon.Points[(i + 1) % n];
                if( IsOnline(point, side) ) {
                    return true ;
                }
                // 如果side平行x轴则不作考虑
                if( Math.Abs(side.P1.Y - side.P2.Y) < ESP )
                {
                    continue;
                }
                if( IsOnline(side.P1, line) )
                {
                    if( side.P1.Y > side.P2.Y ) count++;
                } else if( IsOnline(side.P2, line) )
                {
                    if( side.P2.Y > side.P1.Y ) count++;
                } else if( Intersect(line, side) )
                {
                    count++;
                }
            }
            if ( count % 2 == 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    public class MPoint
    {
        public MPoint()
        { }
        public MPoint(double x,double y)
        {
            X = x;
            Y = y;
        }
        public double X;
        public double Y;
    }
    public class MLine
    {
        public MLine()
        {
            P1 = new MPoint();
            P2 = new MPoint();
        }
        public MPoint P1;
        public MPoint P2;
    }
    public class MPolygon
    {
        public List<MPoint> Points = new List<MPoint>();
    } 

 

代码参考http://mniwjb.blog.sohu.com/58905924.html

 

几何教程http://dev.gameres.com/Program/Abstract/Geometry.htm

 

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值