【问题标题】:Rotate K coplanar points to a plane parallel to x,y plane将 K 共面点旋转到平行于 x,y 平面的平面
【发布时间】:2017-07-27 23:13:12
【问题描述】:

我正在使用 3D 几何图形使用 php(我知道这不是最佳选择...)。 我有 K 个共面 3D 点,也有 x、y、z 值。它们一起形成一个多边形。我需要对这个多边形进行三角测量。我已经有一个适用于 2D 多边形的工作 delaunay 训练函数。 所以我想旋转给定的点,使它们位于平行于 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

提前感谢您的关注。

【问题讨论】:

    标签: php algorithm matrix 3d geometry


    【解决方案1】:

    您首先需要基向量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> 是从 A 在X,Y 方向上的表面距离。这有时会派上用场。如果您需要从P 计算u,v,则利用点积:

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

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

    【讨论】:

    • 您好,很抱歉,我没有完全得到您的解决方案。我已经知道所有的点都在同一个平面上,我可以很容易地找出平面的法线和方程。我想要做的是将所有点旋转/映射到一个平行于标准 X,Y 平面的平面,也是由 (0,0,1) Vector 定义的平面。
    • @Swisx 最后一个方程给你u,v 你可以用它作为x,y 旋转点的坐标P ... z=0 什么不清楚? (你不懂向量数学?或者具体是什么?)
    • 感谢第二个解释,是的,在最后一部分我不太清楚你的意思。但知道我明白了,我可以实施它。当点位于与 x,y 平面正交的平面上时,它看起来甚至可以在边缘情况下工作。非常感谢。
    • @Swisx 很高兴为您提供帮助。
    猜你喜欢
    • 2022-01-12
    • 2017-01-14
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 2014-10-27
    • 2018-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多