将 K 个共面点旋转到平行于 x,y 平面的平面 [英] Rotate K coplanar points to a plane parallel to x,y plane

查看:21
本文介绍了将 K 个共面点旋转到平行于 x,y 平面的平面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 3D 几何图形的 php(这不是最佳选择,我知道...).我有 K 个共面 3D 点,也有 x、y、z 值.它们一起形成一个多边形.我需要对这个多边形进行三角测量.我已经有一个适用于 2D 多边形的工作 delaunay traingulation 函数.所以我想旋转给定的点,使它们位于平行于 x,y 平面的平面上.之后,我可以使用 x,y 值对其进行三角剖分.下面的伪代码将描述我想如何达到这个目标.

I'm working in php with 3D geometries(not the best choice,I know...). I have K coplanar 3D points, also with x,y,z value. Together they form a polygon. I need to triangulate this polygon. I have already a working delaunay traingulation function which works for 2D Polygons. So I want to rotate the given points, so that they lay on a plane parallel to the x,y plane. After that I can triangulated it using the x,y values. The following pseudocode shall describe how I want to get to this goal.

我参考此构建了以下代码(我使用了从 OP 接受的答案):https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d,但它不像我预期的那样工作.为了知道它是否有效,每个映射点都应具有相同的z"值.这是问题,我如何获得正确的旋转矩阵?还是我在概念上犯了一个错误?

I build up the following code with reference on this (I'm usign the answer accepted from the OP): https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d, but it doesn't work as I expected. In order to know if it worked, every mapped point shall then have the same 'z' value. Here is the question, how do I get the correct rotation matrix? Or did I made a conceptual mistake?

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);
                }       
        }

我发现了另一个有用的问题描述,但我无法实现它:将坐标从法向量给出的平面映射到 XY 平面

I found another helpful description of the problem, but I wasn't able to implement it: Mapping coordinates from plane given by normal vector to XY plane

预先感谢您的关注.

推荐答案

你首先需要基向量 X,Y,Z.因此,让我们首先从您的数据集中取中点 A 和两个远处的点 B,C(不是单行).X,Y 应该在平面上,Z 应该与平面垂直,所以:

You need basis vectors X,Y,Z first. So let take the mid point A and two distant points to it B,C (not on single line) from your data set first. The X,Y should lie in the plane and Z should be normal to it so:

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 轴.

Compute normal to the plane your points lie in and correct Y axis.

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

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

So feed these 3 vectors to rotation part of your transform matrix and set origin to A. But as you need to go from your data set to the plane local coordinate you need inverse matrix (or use pseudo inverse based on transposing)

无论如何,现在有了基向量,您可以像这样参数化地映射您的平面:

Anyway now with the basis vectors you can map your plane parametrically like this:

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

其中 u,v = <-inf,+inf> 是在 X,Y 方向上形成 A 的表面距离.这有时会派上用场.如果你需要从 P 计算 u,v 然后利用点积:

Where u,v = <-inf,+inf> are surface distances form A in X,Y directions. That can get handy sometimes. If you need to compute u,v from P then exploit dot product:

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

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

Which can be also used to transform to 2D instead of using matrix ...

这篇关于将 K 个共面点旋转到平行于 x,y 平面的平面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆