找出点是否位于矩形内

时间:2010-08-14 18:05:57

标签: c++ math geometry

如何找到一个点位于给定4个点的2D矩形内?

6 个答案:

答案 0 :(得分:8)

将点转换为与矩形对齐的坐标系,然后问题变得轴对齐且无关紧要。

如果矩形由以下4个点组成:

a  b
c  d

然后得到矩形的“x轴”和“y轴”:

x = Normalize(d-c)
y = Normalize(a-c)

然后使用x和y作为列构建旋转矩阵:

r = [ x | y ]

如果你使用三维坐标,我们需要一个z轴:

z = CrossProduct(x, y)
r = [ x | y | z ]

从世界坐标到矩形轴对齐坐标的变换矩阵变为:

T = [ r^T | -r^T * c ]
    [ 0^T |     1    ]

这里我们选择了左下角c作为本地原点。 “r ^ T”被转置。 “0 ^ T”是用零填充的2-d或3-d行向量。 1只是一个。请注意,这只是简单的矩形到世界变换的反转,即

T^-1 = [ r   | c ]
       [ 0^T | 1 ]

我们可以使用T将点转换为轴对齐坐标。请记住用尾随1填充p,因为T是一个齐次矩阵。

tp = T * p;  // Don't forget to pad p with a trailing 1 before multiplying.

// Checks that p isn't below or to the left of the rectangle.
for ( int d = 0; d < num_dimensions; ++d ) {
  if ( tp[d] < 0.0 ) {
    return false;
  }
}

// Checks that p isn't to the right of the rectangle
double width = Length(d-c);
if ( tp[0] > width ) {
  return false;
}

// Checks that p isn't above the rectangle.
double height = Length(a-c);
if ( tp[1] > height ) {
  return false;
}

// p must be inside or on the rectangle.
return true

如果您正在使用3d坐标,请注意上面忽略了转换点tp的局部z值。即使p在矩形的平面之外,上面的行为就好像它被投影到矩形表面一样。如果要检查共面性,请事先执行以下操作:

if ( fabs(tp[2]) > some_small_positive_number ) {
   return false;  // point is out of the rectangle's plane.
}

答案 1 :(得分:2)

I think this might answer your question

  • 完全披露 - 我去了Drexel获得我的研究生学位

答案 2 :(得分:0)

使OpenGl具体化:

我想你的2D矩形在屏幕坐标中!

首先:

 gluProject (bli, bla, blorp, ...);

从3d到屏幕坐标。

然后:诺亚的建议。

如果您的观点已经是2D,请仅拍摄自己;)

答案 3 :(得分:0)

对于非轴对齐的矩形,使用与一般多边形相同的算法:多边形点测试:

想象一下从测试点向右指向的光线。测试多边形中的每条线是否穿过光线。如果偶数行穿过光线,则该点位于多边形外部。如果奇数行与光线相交,则该点位于多边形内部。

在矩形的情况下,零线和两条线之间将穿过光线。

如果一条线接触光线但没有穿过它,结果就不明确了。因此,在你的计算中,想象一下光线是一个无限小的量,高于它的y坐标,因此一条线在不穿过光线的情况下不可能

给定测试点(x,y)和线(x1,y1,x2,y2),测试线是否穿过光线非常简单。在不失一般性的情况下,假设y1 <1。 Y2。然后

if y < y2 and y >= y1:
    let x0 = x1 + (y-y1)/(y2-y1) * (x2-x1) // crossing point (x0,y)
    if x0 > x:
        crossing_detected++

http://en.wikipedia.org/wiki/Point_in_polygon

答案 4 :(得分:0)

测试点是否位于三角形中很容易,因此您可以将矩形分成两个三角形并测试它们。参见例如http://www.blackpawn.com/texts/pointinpoly/default.html

答案 5 :(得分:0)

四边形点的通用测试就足够了。四边形被定义为一系列有序的点。顺时针和逆时针缠绕:

typedef struct {float x; float y} vec2;
bool pointIsInQuad(const vec2 point, const vec2 quad[4])
{
    bool sides[4];
    for (int i = 0; i < 4; i++) {
        sides[i] = ((point.x - quad[i].x)*(quad[(i + 1)%4].y - quad[i].y) - (point.y - quad[i].y)*(quad[(i + 1)%4].x - quad[i].x)) > 0.0f;
    }
    return ((sides[0] == sides[1]) && (sides[0] == sides[2]) && (sides[0] == sides[3]));
}