簡體   English   中英

找出點是否位於矩形內

[英]Find if point lies within a rectangle

如何找到一個點位於給定4個點的2D矩形內?

將點轉換為與矩形對齊的坐標框,然后問題變得軸對齊且無關緊要。

如果矩形包含以下4點:

a  b
c  d

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

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

然后使用x和y作為列構造旋轉矩陣:

r = [ x | y ]

如果你使用三維坐標,我們需要az軸:

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.
}

我想這可能會回答你的問題

  • 完全披露 - 我去了Drexel為我的畢業生

為了使OpenGl具體化:

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

第一:

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

從3d到屏幕坐標。

然后:諾亞的建議。

如果您的問題已經是2D,請僅拍攝自己;)

對於非軸對齊的矩形,使用與一般多邊形相同的算法:多邊形點測試:

想象一下從測試點向右指向的光線。 測試多邊形中的每條線是否穿過光線。 如果偶數行穿過光線,則該點位於多邊形外部。 如果奇數行與光線相交,則該點在多邊形內。

在矩形的情況下,零和兩條線之間將穿過光線。

如果一條線接觸光線但沒有穿過它,結果就不明確了。 因此,在你的計算中,想象一下光線的數量是無限小的ɛ,高於它的y坐標,這樣一條線就不可能在不穿過光線的情況下觸摸光線。

給定測試點(x,y)和線(x1,y1,x2,y2),測試線是否穿過光線非常簡單。 假設,在不失一般性的情況下,y1 <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

如果一個點位於三角形中,則很容易測試,因此您可以將矩形分成兩個三角形並進行測試。 參見例如http://www.blackpawn.com/texts/pointinpoly/default.html

四邊形點的通用測試就足夠了。 四邊形被定義為一系列有序的點。 順時針和逆時針纏繞:

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]));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM