2010-02-08 3 views
8

얘들 아, 나는 processing.js를 배우고 있는데, 나는 제한된 기하학 및 삼각법 지식으로 또는 Wikipedia의 도움으로 해결할 수없는 수학적 문제를 발견했습니다.직사각형의 두 점을 알면 어떻게 다른 두 점을 알아낼 수 있습니까?

직사각형을 그릴 필요가 있습니다. 이 직사각형을 그리려면 각 모서리의 좌표 점을 알아야합니다. 내가 아는 것은 박스의 위아래의 중간 점과 네 변의 길이를 나타내는 x와 y입니다.

상자의 방향에 대한 보장은 없습니다.

어떤 도움이 필요합니까? 이것은 쉬워야하는 것처럼 보입니다. 그러나 그것은 정말로 나를 곤란하게합니다.

+0

난 다시 내 대답을 ... 이것은 해결할 수 있습니다! – Dolph

+0

나는 어떤 각도로도 회전 할 수 있으며 각도를 모른다는 것을 알고 있습니까? – Casey

+0

@Casey, correct. – icco

답변

8

이 사변형이 직사각형 (4 개의 모든 각도가 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

+0

이 방법을 사용하면'x1 == x2' 또는'y1 == y2'의 특별한 경우를 추가해야합니다. 그렇지 않으면 0으로 나눠집니다.슬로프 대신 벡터를 사용하여 계산하면 (두 포인트가 정확히 같지 않은지 확인해야하지만) 이것을 피할 수 있습니다. – Dave

+0

@Dave, correct, sir,이 사건을 해결하기 위해 내 대답을 편집했습니다. –

0

확실히 사각형입니까? 그렇다면 짧은면의 방향 (점 사이의 선과 평행 함)과 긴 변의 방향을 알 수 있습니다.

길이가 긴면의 방향과 길이를 알고 있고 그 중간 점을 알고 있기 때문에 거기에서 모서리를 찾는 것이 간단합니다.

구현은 독자에게 연습 문제로 남겨 둡니다.

+0

긴면이 한 줄과 평행하다는 것은 알고 있습니다. 짧은면의 길이와 기울기도 알고 있습니다. 왜냐하면 그면에 수직 인 한 선의 기울기를 알고 있기 때문입니다. 나는 아직도 그 4 점을 얻는 방법을 모른다. 어쩌면 이것은 당신에게 단순한 것처럼 보이지만, 나는 수학적 배경이 거의 없습니다. – icco

+0

중간 점과 측면의 길이가 중간 점임을 알고 있습니다. 그것은 코너가 그 지점으로부터'길이/2 '떨어져 있음을 의미합니다. 그래서 당신은 방향을 알고, 당신은 거리를 알고 있습니다. 그 밖의 무엇을 알아야합니까? –

0

이것은 두 지점 사이에 선과 평행 한 두 개의 선이 있다는 것을 의미합니다. 자신이 가지고있는 선에 수직 인 각 방향의 윗면 길이의 1/2을 가진 선을 번역하여 모서리를 가져옵니다.

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

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 = Y2 = top_middle_y bottom_middle_y

물론, 그 가장 간단한 경우이고 (TMX, TMY) (묘기, BMY)의 라인만으로 Y 축을 따라라고 가정.

"중간 선"이라고합니다.

다음 트릭은 중간 선을 가져 와서 Y 축에서 회전 오프셋을 계산하는 것입니다.

이제 제 삼각은 녹슬지 않습니다.

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

따라서 각도의 탄젠트는 dy/dx입니다. 아크 탄젠트 (arctangent, dy/dx)는 선의 각도입니다.

오리엔테이션을받을 수 있습니다.

(마음은, 몇 가지 사분면과 게임, 표지판,이 권리를 얻을 수있는 물건이 -하지만이 그것의 요점입니다.)

당신이 방향을 갖게되면, 당신이 할 수있는 "회전"라인 다시 Y 축으로 수학을위한 2D 그래픽을 보아라.

정상적인 방향으로 안내합니다. 그런 다음이 새로운 표준 형식으로 직사각형 점을 계산하고 마지막으로 다시 회전시킵니다.

비올라. 구형.

"할 수있는 일은"위쪽 "선의 길이의 절반 인 선을 중간 선의 90 도가있는 곳으로"회전 "시키는 것입니다. 그래서 45도 중간 선이 있다고 가정 해보십시오. tmx, tmy에서이 줄을 시작하고이 줄을 135도 (90 + 45) 회전시킵니다. 그 점이 당신의 "좌상"구석이 될 것입니다. "오른쪽 상단"지점을 얻으려면 -45 (45 - 90)를 돌려주십시오. 그런 다음 더 낮은 지점과 비슷한 것을하십시오.

0

두 중간 점을 연결하는 선의 각도를 계산합니다. 두 직선 사이의 벡터에 적용되는 호 접선 함수를 사용합니다.

빼기 그 각도에서 90도 상단 중앙 지점에서 시작하여 상부 에지

방향을 얻기 위해, 상대적으로 (1/2 상단 너비 x 죄 (각도), 1/2 상부 폭 X 이동 cos (angle)) - 오른쪽 상단 점을 얻습니다. 당신이 당신의 사각형은 직사각형 알고 있다면 당신은 시작점

5

로 다시 만든 확인 :

은 죄와 시험으로

적절한 각도와 폭의 COS를 사용하여 사각형의 주위에 계속 몇 가지 간단한 벡터 수학을 사용하여 코너의 좌표를 찾을 수 있습니다.과학적 이해는 다음과 같습니다

  • (x1,y1) - 상단의 길이와 수익성
  • - (가) 결론
  • l1에 중간 점의 좌표 - (가) 외형
  • (x2,y2)에 중간 점의 좌표
  • l2 - 다른 두 줄의 길이

먼저 두 지점 사이의 벡터를 찾습니다. 이 벡터는 사이드 라인에 평행 :

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

우리는이 벡터를 정상화 할 필요가 (즉,이 길이는 1) 그래서 우리는 우리의 좌표를 찾기 위해 기반으로 나중에 사용할 수 있습니다.

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

다음

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

, 우리는 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