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

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

问题描述

我正在使用三维几何形状的php(不是最好的选择,我知道......)。
我有K个共面3D点,也有x,y,z值。他们一起形成一个多边形。我需要对这个多边形进行三角测量。我已经有一个适用于2D多边形的工作delaunay traingulation函数。
所以我想旋转给定的点,使它们躺在平行于x,y平面的平面上。之后,我可以使用x,y值对它进行三角化。下面的伪代码应该描述我想如何实现这个目标。



我在这里引用了下面的代码(我正在接受从OP): https: //math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d ,但它没有按我的预期工作。为了知道它是否工作,每个映射点应该具有相同的'z'值。
这里是一个问题,我如何得到正确的旋转矩阵?或者我犯了一个概念错误?

pre $ 函数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);
返回$ matrix;


函数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);
返回$ finalMatrix;


函数calc2DMapping($ points)
{
$ rotationMatrix = matrixRotationMapping($ points [0],$ points [1],$ points [2] );
foreach($ points为$ point)
{
$ mappedPoint = $ rotationMatrix-> multiplyWithPoint($ point);
$ mappedPoints [] =新的MappedPoint($ mappedPoint);
}
}

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



感谢您的关注。 >解决方案

首先需要基向量 X,Y,Z 。因此,让我们从中点 A 和距离您的中点 B,C (不在单线上)数据集首先。 X,Y 应该位于飞机上, Z 应该正常。

  X = BA //平面内的任何非零向量
X = X / | X | //单位大小

Y = C-A //平面内任意非零向量
(X.Y)!= 0 //但不平行于X!
Y = Y / | Y | //单位大小

计算您的点位于的平面的法线并校正Y轴。

  Z = X x Y // cross product给出垂直向量
Y = Z x X //现在全部向量是垂直的,并且单元

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

无论如何,现在使用基本矢量可以像这样以参数方式映射你的飞机:
$ b $ pre $ code> P(u,v)= A + u * X + v * Y

其中 u,v =< -inf,+ inf> 是在 X,Y 方向上的表面距离。有时候这可以得到方便。如果您需要从 P 计算 u,v ,那么利用点积:
$ (PA).X)=点(PA,X)
v =((PA).Y)=点(PA,Y)b $ b

  

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


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.

I build up the following code with reference on this (I'm usign the the 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);
                }       
        }

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

Thanks in advance for your attention.

解决方案

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

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

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

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)

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

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

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