检查一个点是否在平面段内

时间:2012-03-09 17:03:19

标签: 3d point plane

我想知道平面线段中的一个点,以及它在[0,1] [0,1]中相对于线段的坐标。例如0,0左下角,1,1右上角,0.5,0.5中心

这些是我已经知道的事情:

-point与平面段位于同一平面上。 - 平面段的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之间,则在

这会有用吗?我需要良好的实时性能,是不是dot产品在CPU上很慢? 我怎样才能找到点的相对坐标?

2 个答案:

答案 0 :(得分: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万次而没有任何问题。希望这有帮助,祝你好运!

答案 1 :(得分:0)

我找到了一种方法来找到我想要的东西。这是:(代码是C ++ / Ogre)

    // 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个点积来计算我们想要的东西。