2012-02-24 51 views
0

我使用Python 2.7和Pygame,但任何語言的答案都可以。如何在矩形的周長找到一個點?

我正試圖在矩形的周長中沿矢量找到給定的點。我知道矢量以及矩形的中心,寬度和高度,但爲了簡單起見,中心可以是(0, 0)

因此,例如,我想要在矩形的周長中找到點大致爲(0.7, 0.7)的矩形,寬2乘6高。

我現在正在工作做的工作;但有一個更好,更優雅的方式:我將矩形的高度和寬度之間的較寬值的長度,並使用介於0和0之間的每個數字,然後針對矩形,看看它是否在它。

這是我的具體使用我的遊戲代碼,而不是全身都:http://pastebin.com/8Ai1iQeL

+0

http://stackoverflow.com/search?q=line+intersection+rectangle – 2012-02-24 03:51:31

+0

感謝您的鏈接,我沒有使用這些條款,它似乎像你的發現更好的結果,幾乎使我的問題變得多餘。再次感謝。 – TankorSmash 2012-02-29 20:55:53

回答

1

我會去了解這個通過比較你的載體,這也是平行向量的直線的斜率的成分的比例,以相同的數量從矩形的中心,其角指向向量。這會告訴你矢量是水平還是垂直。之後,您可以使用簡單的比例來找到相交點。

假設你的向量是(x,y),並且現在假定兩個座標都是正的。使用其中矩形的中心位於(0,0)的座標系,斜率爲y/x,矩形的等效數量爲h/w。現在,如果y/x > h/w,你的交叉點將在頂部邊緣,所以你知道它的高度是h/2。然後,您可以計算座標爲(0.5*h*x/y,0.5*h)。如果y/x < h/w,交點位於右邊緣,座標爲(0.5*w,0.5*w*y/x)

要在實踐中使用這個,你需要實際做y*wx*h之間的比較,以避免零除以及避免相對昂貴的除法運算符的問題(這不是真的有很大區別)。此外,只需使用xy的符號,即可找到交叉點組件的正確標誌。所以在代碼中,它看起來像這樣:

def intersect_perimeter(x, y, w, h): 
    if abs(y*w) > abs(x*h): 
     return (0.5*h*x/abs(y), 0.5*h*sign(y)) 
    else: 
     return (0.5*w*sign(x), 0.5*w*y/abs(x)) 

(未經測試)。如果x爲零並且yw爲零,但是在這種情況下,您有零向量(問題未定義)或零寬度矩形(問題未定義),則此操作將失敗。所以我不會爲這種情況下的錯誤檢查而煩惱。

如果您的矩形以(0,0)以外的點爲中心,則只需將表示矩形中心的位置矢量添加到該函數的結果中即可。

+0

如果你指的是我使用[sign function](http://en.wikipedia.org/wiki/Sign_function),不,這不是一個錯字。 – 2012-02-29 22:40:14

+0

我的錯誤,我認爲這是我嘗試了幾件事後的拼寫錯誤; math.sign(),math.sgn(),sig()和sign()。做了一個快速搜索,並找到了一個很好的解釋你的意思的網頁:http://thingspython.wordpress.com/2011/03/12/snippet-sgn-function/ – TankorSmash 2012-02-29 23:56:15

1

我會在右上象限做到這一點的載體,但它不應該是很難一概而論這其他。你知道矩形的矢量角和邊長。所以

1)確定向量是否會撞到矩形的右側或頂部。通過構造直角三角形的斜邊是矩形的對角線,即從原點到上角的直線來做到這一點。如果矢量的角度A大於這個角度,它會頂到頂部;否則會撞到一邊。

2)假設它碰到一邊(如果它碰到頂部,解決方案將是類似的)。如果三角形的寬度是w,則可以構造一個直角三角形,其頂點是原點,點(w/2,0)和點(w/2,y),其中(w/2,y )是你想找的點。然後只需使用law of sines即可獲得y。

書面該方案涉及到一些分支(4×2),以涵蓋所有的可能性,但我敢打賭,如果你通過它的工作,你可以找到辦法來消除代碼重複。例如,一開始您可以將每個矢量旋轉到右上象限,然後在求解後使用旋轉來重建點的正確位置。