2012-03-09 4 views
1

평면 세그먼트의 한 점과 세그먼트에 대한 [0,1] [0,1]의 좌표를 알고 싶습니다. 예컨대 0,0 왼쪽 하단 모서리, 1,1- 오른쪽 상단 모서리, 0.5,0.5 센터점이 평면 세그먼트 안에 있는지 확인하십시오.

이 내가 이미 알고있는 것입니다

N'- 포인트는 평면 세그먼트와 같은 비행기에 있습니다. - 평면 세그먼트의 4 포인트의 좌표입니다. 그러나 시계와 같은 명령이나 내가 아는 명령이 아닙니다. - 평면의 정상 거리와 원점과의 거리. 같은; ax + by + cz + d. x, y, z, d는 알려져있다.

여기에 스케치가 있습니다. plane http://s17.postimage.org/564cjyjy7/plane.png A, B, C 점은 평면 세그먼트와 같은 평면에 있습니다. P1, P2, P3, P4 좌표는 알려져 있지만 의미있는 순서로 정렬되지는 않습니다.

감사합니다.

편집 : 나는이

하나의 아이디어가

  • 정렬 포인트

  • 2 점

  • 점에서 벡터를 생성하는 각 점 사이의 벡터를 만들 그들 제품 정도가 0에서 90 사이 인 경우

  • , 그것은

것이 작품 안에입니까? 좋은 실시간 성능이 필요합니다. CPU에서 느린 점은 없습니까? 상대 좌표를 어떻게 찾을 수 있습니까?

답변

1

제 생각에는 이것을 확인하는 가장 좋은 방법은 전체 평면과 점을 좌표계의 원점으로 변환하는 것입니다. 모든 점을 변환하여 왼쪽 하단 점이 좌표계의 중심에 있도록 모든 점을 회전 시키십시오. 법선 벡터는 축 중 하나와 평행을 향하게됩니다. 이것은 모든 포인트에 대해 행렬 곱셈을 의미하지만, 이후에 어떤 포인트가 사각형에 있는지 쉽게 확인할 수 있습니다. 이것은 XNA C#을 구현하지만, 논리는 어디에서나 동일합니다 (I는 입력에 대해 스케치를 사용하려고)

// Inputs - Right handed coordinate system 
Vector3 p1 = new Vector3(-1.0f, 1.0f, 1.0f); // left top 
Vector3 p2 = new Vector3(1.0f, -1.0f, 0.0f); // right bottom 
Vector3 p3 = new Vector3(1.0f, 1.0f, 1.0f); // right top, redundant if this is a rectangle 
Vector3 p4 = new Vector3(-1.0f, -1.0f, 0.0f); // left bottom 

Vector3 a = new Vector3(-0.5f, 0.0f, 0.5f); 

// Calculating transformation matrix 
Vector3 right = Vector3.Normalize(p2 - p4); 
Vector3 forward = Vector3.Normalize(p1 - p4); 
Vector3 up = Vector3.Cross(right, forward); 

Matrix transform = new Matrix(); 
transform.M11 = right.X; 
transform.M12 = right.Y; 
transform.M13 = right.Z; 
transform.M14 = 0.0f; 
transform.M21 = forward.X; 
transform.M22 = forward.Y; 
transform.M23 = forward.Z; 
transform.M24 = 0.0f; 
transform.M31 = up.X; 
transform.M32 = up.Y; 
transform.M33 = up.Z; 
transform.M34 = 0.0f; 
transform.M41 = p4.X; 
transform.M42 = p4.Y; 
transform.M43 = p4.Z; 
transform.M44 = 1.0f; 

transform = Matrix.Invert(transform); 

// Transforming 
Vector3 tp1 = Vector3.Transform(p1, transform); 
Vector3 tp2 = Vector3.Transform(p2, transform); 
Vector3 tp3 = Vector3.Transform(p3, transform); 
Vector3 tp4 = Vector3.Transform(p4, transform); 
Vector3 ta = Vector3.Transform(a, transform); 

ta.X /= tp2.X; // divide with rectangle width 
ta.Y /= tp1.Y; // divide with rectangle height 

// Now everything is on the XY plane 
// P1: {X:0 Y:2.236068 Z:0} 
// P2: {X:2 Y:0  Z:0} 
// P3: {X:2 Y:2.236068 Z:0} 
// P4: {X:0 Y:0  Z:0} 
// A: {X:0.25 Y:0.5  Z:0} 

이 어떤 네 점에서 작동합니다.

가장 빠른 솔루션은 아니지만 매트릭스 변환을 알고 있다면 가장 간단하고 간단하다고 확신합니다. 더 빠르고 단순한 해결책을 찾으면 나도 관심이 있지만 성능상의 문제는 없을 것입니다. 내 인텔 2.4GHz 프로세서에서이 계산은 아무런 문제없이 1 초 미만으로 1 백만 번 이상 발생합니다. 희망이 도움이 행운을 빕니다!

+0

Vector3.Transform은 무엇을합니까?난 단지 벡터 함수를 가지고있다. 나는 같지 않다. – mikbal

+0

이것과 관련된 한 가지 문제는 평면 세그먼트의 점들이 정렬되어 있지 않다는 것이다. 그래서 나는 이것이 좌상 정도라고 말한다. 나는 비행기 모퉁이 4 포인트 있습니다. 측면 노드에서, 나는 또한 비행기의 정상과 원점까지의 거리를가집니다. 같은; ax + by + cz + d. x, y, z, d는 알려져있다. 도움이된다면. – mikbal

+0

벡터 3 변환은 행렬에 벡터를 곱하면되므로 동일합니다. –

0

내가 원하는 것을 찾는 방법을 찾았습니다. 여기있다 : 이것은 우리가 단지 2 정규화 기능과 2 개의 제품을 원하는 계산

// top or bottom vector of rectangle 
Ogre::Vector3 right = Ogre::Vector3(vertices[3] - vertices[2]); 
right.normalise(); 
    // vector opposite of the top vector 
Ogre::Vector3 left = Ogre::Vector3(vertices[0] - vertices[1]); 
left.normalise(); 


    // you may store above values if rectangle doesnt move much. this would reduce amount of operations 


    // vector from top vertex to position we are checking 
Ogre::Vector3 p2ToPos = Ogre::Vector3(pos - vertices[2]); 
p2ToPos.normalise(); 

    // vector from bot vertex to position we are checking 
Ogre::Vector3 p1ToPos = Ogre::Vector3(pos - vertices[1]); 
p1ToPos.normalise(); 

    // angle between our vectors 
Ogre::Real dot1 = p2ToPos.dotProduct(right); 
Ogre::Real dot2 = p1ToPos.dotProduct(left); 

    // is both dot products (which gives cos) are positive point is between our rectangle 
if(dot1 > 0 && dot2 > 0) 
    return true; 

(코드는 C++/오우거이다).

+0

네,하지만 당신도 상대 좌표가 필요하다고 했어요. 제 의견으로는 더 복잡한 문제를 묻는 것이 공평하지 않아서 더 쉬운 문제에 대한 해답을 얻었 기 때문에 정답을 표시하지 마십시오 ... –

+0

당신은 더 느리고, 그러나 완전한 대답. 어쨌든, 나는 physx raycasting에 가기로 결정했다. 훨씬 빨라지고 모든 메쉬에서 작동합니다. 적어도 나는 약간의 수학을 배웠다 :) – mikbal

관련 문제