将K共面点旋转到与x,y平面平行的平面

时间:2017-03-07 16:33:57

标签: php algorithm matrix 3d geometry

我在PHP中使用3D几何体(不是最好的选择,我知道......)。 我有K个共面3D点,也有x,y,z值。它们一起形成一个多边形。我需要对这个多边形进行三角测量。我已经有一个工作delaunay traingulation功能,适用于2D多边形。 所以我想旋转给定的点,使它们位于平行于x,y平面的平面上。之后,我可以使用x,y值对其进行三角测量。以下伪代码将描述我希望如何实现这一目标。

我建立了以下代码并参考了这一点(我使用了OP中接受的答案):https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d,但它没有按照我的预期工作。为了知道它是否有效,每个映射点应具有相同的“z”值。 这是一个问题,我如何获得正确的旋转矩阵?或者我犯了一个概念上的错误?

function matrixRotationMapping(Point $p, Point $q, Point $r)
        {
            $normalPolygon =calculatePlaneNormal($p, $q, $r);
            $v = crossProduct($normalPolygon, new Point(0, 0, 1));
            $c = dotProduct($normalPolygon, new Point(0, 0, 1));
            $matrix = buildRotationMatrix($v, $c);    
            return $matrix;
        }    

function buildRotationMatrix($v, $c)
        {
            $R2 = new Matrix(array(array(1, -$v->z, $v->y), array($v->z, 1, -$v->x), array(-$v->y, $v->x, 1)));
            $costant = 1/(1+$c);
            $R3 = multiplyMatrices($R2, $R2);
            $R3 = multiplyMatricesWithFactor($R3, $costant);
            $finalMatrix = sumMatrices($R2, $R3);
            return $finalMatrix;
        }

function calc2DMapping($points)
        {
             $rotationMatrix = matrixRotationMapping($points[0], $points[1], $points[2]);
             foreach($points as $point)
                {
                    $mappedPoint = $rotationMatrix->multiplyWithPoint($point);              
                    $mappedPoints[] = new MappedPoint($mappedPoint);
                }       
        }

我找到了另一个有用的问题描述,但我无法实现它:Mapping coordinates from plane given by normal vector to XY plane

提前感谢您的关注。

1 个答案:

答案 0 :(得分:0)

首先需要基础向量X,Y,Z。因此,首先从数据集中取A点和两个远点B,C(不是单行)。 X,Y应该在平面上,Z应该是正常的,所以:

X = B-A     // any non zero vector inside plane
X = X / |X| // unit in size

Y = C-A     // any non zero vector inside plane
(X.Y) != 0  // but not parallel to X !!!
Y = Y / |Y| // unit in size

计算您的点所在平面的法线并校正Y轴。

Z = X x Y   // cross product gives you perpendicular vector
Y = Z x X   // now all vectors are perpendicular and unit

因此,请将这3个向量提供给transform matrix的旋转部分,并将原点设置为A。但是,当您需要从数据集转到平面局部坐标时,您需要逆矩阵(或使用基于转置的伪逆)

无论如何,现在使用基矢量,您可以参数化地映射您的平面:

P(u,v) = A + u*X + v*Y

u,v = <-inf,+inf>表面距离在X,Y方向上形成A的位置。这有时会变得很方便。如果您需要从u,v计算P,请使用点积:

u = ((P-A).X) = dot(P-A,X)
v = ((P-A).Y) = dot(P-A,Y)

也可以用来转换为2D而不是使用矩阵......