2012-03-09 92 views
1

内部我想知道如果在一个平面段的点,其在[0,1] [0,1]相对于段坐标。 e.g 0,0左下角,1,1右上角,0.5,0.5中心检查点是平面段

这些是我已经知道的东西:

- 点是在同一平面的平面段。 - 坐标平面段的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#实现,但逻辑是到处都是一样的:(我试图使用你的草图输入)

// 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秒内发生超过100万次而没有任何问题。希望这有帮助,祝你好运!

+0

什么Vector3.Transform办?我只有矩阵*矢量功能 ,我猜测是不一样的 – mikbal 2012-03-09 19:42:13

+0

我遇到的一个问题是,飞机段的点不是有序的。所以我不能说这是左上角左右。我有4点是飞机角落。在一个侧面节点上,我也有飞机的法线和距离原点。如; ax + by + cz + d。 x,y,z,d是已知的。如果有帮助。 – mikbal 2012-03-09 20:09:46

+0

Vector3变换只是将矩阵与矢量相乘,因此它们是相同的。 – 2012-03-09 20:10:51

0

我已经找到一种方法来找到我想要的东西。在这里,它是:(代码为C++ /食人魔)

// 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; 

这算什么,我们希望只有2正常化的功能和2分的产品。

+0

是的,但你说你也需要相对坐标...在我看来,问这个更复杂的问题并不公平,因为你有一个更简单的问题的解决方案... – 2012-03-11 08:36:59

+0

你是一个更慢,但一个完整的答案。无论如何,我已决定使用物理光线投射。它快得多并且适用于每个网格。至少我学到了一些数学:) – mikbal 2012-03-11 18:05:23