方法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