我在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
提前感谢您的关注。
答案 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而不是使用矩阵......