2010-02-08 108 views
8

嘿,那裏的人,我正在學習processing.js,並且遇到了一個數學問題,我無法用我有限的幾何和三角知識或者通過維基百科的幫助來解決這個問題。知道一個矩形的兩個點,我怎麼能找出其他兩個?

我需要繪製一個矩形。要繪製這個矩形,我需要知道每個角的座標點。我所知道的是盒子頂部和底部中點的x和y以及所有四條邊的長度。

箱子的方向不能保證。

任何幫助?這似乎應該很容易,但它真的讓我感到困惑。

+0

我把我的答案回..這是可以解決的! – Dolph 2010-02-08 01:19:20

+0

我認爲這可以在任何角度旋轉,你不知道角度? – Casey 2010-02-08 01:22:01

+0

@Casey,正確。 – icco 2010-02-08 01:28:17

回答

8

如果這個四邊形是一個矩形(所有四個角度都是90度),那麼它可以解決。 (如果它可能是任何四邊形,那麼它是不可解的)

如果點是(x1,y1)和(x2,y2),並且如果這兩個點不是完美垂直的(x1 = x2)或水平(Y1 = Y2),則該矩形的一個邊緣的斜率是

m1 = (y2-y1)/(x2-x1) 

和另一邊緣的斜率爲:

m2 = - 1/m1 

如果知道邊的長度,並兩個相對側的中點,那麼通過將dx,dy添加到中點可以容易地確定更正點:(如果L是長度如果點的垂直或水平排列的,這種技術將無法正常工作,但對於那些退化情況下,顯而易見的解決方案是:邊的中點上)

dx = Sqrt(L^2/(1 + m2^2))/2 

dy = m2 * dx 

注簡單得多。

+0

太棒了。這正是我所需要的。謝謝。 – icco 2010-02-08 01:57:31

+0

使用這種方法,您需要確保爲「x1 == x2」或「y1 == y2」添加特殊情況,否則最終會被零除。用矢量而不是斜率計算可以避免這種情況(儘管你仍然需要檢查你的兩點不完全相同)。 – Dave 2010-02-08 02:27:10

+0

@Dave,正確,先生,我編輯了我的答案來解決這個問題。 – 2010-02-08 03:47:40

0

這絕對是一個矩形?然後你知道短邊的方向(它們平行於你的點之間的線),並因此知道長邊的方向。

你知道長邊的方向和長度,並且你知道他們的中點,所以直接從那裏找到角。

實現留給練習讀者。

+0

長邊與我知道的一條線是平行的。我也知道短邊的長度和它們的斜率,因爲我知道垂直於它們的一條線的斜率。我仍然不知道如何得到這四點。也許這對你來說很簡單,但我的數學背景很少。 – icco 2010-02-08 01:27:11

+0

你知道中點,以及它的中點的長度。這意味着角落距離該點的距離是「長度/ 2」。所以你知道方向,而且你知道距離......你還需要知道什麼? – 2010-02-08 01:28:31

0

這意味着將有兩條線與兩點之間的線平行。通過平移垂直於您所在線的每個方向上的頂部邊長度的一半來獲得角點。

0

如果你知道頂點的中點和頂點的長度,那麼你知道y對於兩個頂角都保持相同,並且x將是中點加/減矩形的寬度。底部也是如此。

一旦你有了四個角落,就不用擔心邊長了,因爲它們的點與頂部和底部所用的點相同。

      midpoint 
    x,10     10,10     x,10 
     *--------------------------------------------* 
         width = 30 

    mx = midpoint x. 
    top left corner = (w/2) - mx or 15 - 10 
    top left corner coords = -5,10 

    mx = midpoint x. 
    top right corner = (w/2) + mx or 15 + 10 
    top left corner coords = 25,10 
+0

這個盒子是在一個未知的角度,我怎麼能假設y會保持不變? – icco 2010-02-08 01:29:07

0

「四邊形」和「矩形」之間有區別。

如果您有頂部和底部的中點以及邊長,其餘部分很簡單。

鑑於:

(x1, y1) -- (top_middle_x, top_middle_y) -- (x2, y1) 

(x1, y2) -- (btm_middle_x, btm_middle_y) -- (x2, y2) 

和頂部/底部長度與左/右長度沿。

x1 = top_middle_x - top/bottom_length/2; x2 = x1 + top/bottom_length;

Y1 = top_middle_y Y2 = bottom_middle_y

顯然,這是最簡單的情況和假定的(TMX,TMY)(BMX,BMY)的線是僅沿Y軸。

我們將該行稱爲「中線」。

下一個技巧是取中線,並計算它的離Y軸的旋轉偏移量。

現在,我的觸發器非常生鏽。

dx = tmx - bmx,dy = tmy - bmy。

所以,角度的正切值是dy/dx。反正切(dy/dx)是線的角度。

從那裏你可以得到你的方向。

(頭腦,有一些遊戲與象限,和標誌,和東西得到這個權利 - 但這是它的精神。)

一旦你的方位,你可以在「旋轉」行回到Y軸。查找數學的2D圖形,它很簡單。

這會讓你成爲你的正常方向。然後用這種新的標準形式計算矩形點,最後將它們旋轉回來。

中提琴。長方形。

您可以做的其他事情是「旋轉」一條線,該線是「頂部」線長度的一半,位於中線90度處。所以,假設你有一個45度的中線。你可以在tmx,tmy開始這條線,然後將這條線旋轉135度(90 + 45)。那點將是你的「左上角」。旋轉它-45(45 - 90)以獲得「右上角」點。然後做一些類似的低點。

0

使用應用於它們之間的向量的反正切函數來計算連接兩個中點的直線的角度。

減去從這個角度90度,以獲得頂部邊緣

從頂部中心點開始的方向,相對移動(1/2頂部寬×SIN(角度),1/2頂部寬x cos(角度)) - 得到右上角的點。

使用的罪過與角度和寬度適當

作爲測試的COS周圍的矩形繼續:檢查你做它回到起點

5

如果你知道你的四邊形是矩形,那麼你可以使用一些簡單的矢量數學來找到角落的座標。所述的已知,有:

  • (x1,y1) - 頂端的長度和底部線
  • - 中點的在底行
  • l1座標 - 中點的上一行
  • (x2,y2)座標
  • l2 - 另外兩個線的長度

首先,我們發現兩個已知點之間的矢量。這個載體是平行於側線:

(vx, vy) = (x2 - x1, y2 - y1)

我們需要正常化這一載體(即使其長度爲1),所以我們以後可以使用它作爲一個基礎來找到我們的座標。

vlen = sqrt(vx*vx + vy*vy)

(v1x, v1y) = (vx/vlen, vy/vlen)

接下來,我們旋轉90度這個矢量逆時針。旋轉的矢量將平行於頂部和底部線。 90度的旋轉結果只是交換座標並且否定其中的一個。你可以通過在紙上試試看到這一點。或者看看equations for 2D rotations並以90度代替。

(u1x, u1y) = (-v1y, v1x)

現在我們有足夠的信息來找到「左上角的」角落。我們只是在開始我們的觀點(x1, y1)和邊長度的一半移動沿側回:

(p1x, p1y) = (x1 - u1x * l1/2, y1 - u1y * l1/2)

從這裏我們可以找到剩餘點剛剛加入我們的基向量的相應倍數。當實現這一點,你可以明顯加快它由一個單一的時間僅計算每一個獨特的乘法:

(p2x, p2y) = (p1x + u1x * l1, p1y + u1y * l1)

(p3x, p3y) = (p1x + v1x * l2, p1y + v1y * l2)

(p4x, p4y) = (p3x + u1x * l1, p3y + u1y * l1)

0
/* rcx = center x rectangle, rcy = center y rectangle, rw = width rectangle, rh = height rectangle, rr = rotation in radian from the rectangle (around it's center point) */ 

function toRectObjectFromCenter(rcx, rcy, rw, rh, rr){ 
    var a = { 
     x: rcx+(Math.sin((rr-degToRad(90))+Math.asin(rh/(Math.sqrt(rh*rh+rw*rw)))) * (Math.sqrt(rh*rh+rw*rw)/2)), 
     y: rcy-(Math.cos((rr-degToRad(90))+Math.asin(rh/(Math.sqrt(rh*rh+rw*rw)))) * (Math.sqrt(rh*rh+rw*rw)/2)) 
    }; 
    var b = { 
     x: a.x+Math.cos(rr)*rw, 
     y: a.y+Math.sin(rr)*rw 
    }; 
    var c = { 
     x: b.x+Math.cos(degToRad(radToDeg(rr)+90))*rh, 
     y: b.y+Math.sin(degToRad(radToDeg(rr)+90))*rh 
    }; 
    var d = { 
     x: a.x+Math.cos(degToRad(radToDeg(rr)+90))*rh, 
     y: a.y+Math.sin(degToRad(radToDeg(rr)+90))*rh 
    }; 
    return {a:a,b:b,c:c,d:d}; 
} 
2
function getFirstPoint(x1,y1,x2,y2,l1,l2) 
    distanceV = {x2 - x1, y2 - y1} 
    vlen = math.sqrt(distanceV[1]^2 + distanceV[2]^2) 
    normalized = {distanceV[1]/vlen, distanceV[2]/vlen} 
    rotated = {-normalized[2], normalized[1]} 
    p1 = {x1 - rotated[1] * l1/2, y1 - rotated[2] * l1/2} 
    p2 = {p1[1] + rotated[1] * l1, p1[2] + rotated[2] * l1} 
    p3 = {p1[1] + normalized[1] * l2, p1[2] + normalized[2] * l2} 
    p4 = {p3[1] + rotated[1] * l1, p3[2] + rotated[2] * l1} 
    points = { p1 , p2 , p3 , p4} 
    return p1 
end 
相關問題