2010-02-08 109 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 
相关问题