将法线向量给定的平面的坐标映射到 XY 平面

发布于 2024-12-25 11:26:11 字数 225 浏览 2 评论 0原文

所以,我有这个算法来计算 3D 形状的横截面,其中平面给定为法向量。

然而,我当前的问题是,横截面是一组 3D 点(全部位于给定平面上),为了显示它,我需要将此坐标映射到 XY 平面。

如果平面法线类似于 (0,0,c),则此方法非常有效 - 我只需复制 x 和 y 坐标并丢弃 z。

这是我的问题:由于我不知道如何转换任何其他普通格式,任何人都可以给我任何提示,告诉我现在应该做什么吗?

So, I have this algorithm to calculate cross-section of 3D shape with plane given with normal vector.

However, my current problem is, that the cross-section is set of 3D points (all lying on that given plane) and to display it I need to map this coordinates to XY plane.

This works perfect if the plane normal is something like (0,0,c) - I just copy x and y coordinates discarding z.

And here is my question: Since I have no idea how to convert any other plain could anybody give me any hint as to what should I do now?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你没皮卡萌 2025-01-01 11:26:11

您的窗格由法线向量定义

n=(xn,yn,zn)

对于协调变换,我们需要窗格的 2 个基向量和一个零点

基向量

我们选择那些“自然”适合 x/y 窗格的向量(请参阅后面的边缘) case):

b1=(1,0,zb1)
b2=(0,1,zb2)

我们希望

b1 x b2 = n*c (c const 标量)

确保这两个确实是基数

现在解决这个问题:

b1 x b2= (0*zb2-zb1*1,zb1*0-1*zb2,1*1-0*0) = (zb1,zb2,1)
zb1*c=xn
zb2*c=yn
1*c=zn

c=zn,
zb2=yn/c=yn/zn
zb1=xn/c=xn/zn

b1=(1,0,yn/zn)
b2=(0,1,xn/zn)

并将其归一化

bv1=(1,0,yn/zn)*sqrt(1+(yn/zn*yn/zn))
bv2=(0,1,yn/zn)*sqrt(1+(xn/zn*xn/zn))

边缘情况是,当 zn=0 时:在这种情况下,法向量平行于x/y 窗格并且不存在自然基向量,在这种情况下,您必须通过审美 POV 选择基 b1 和 b2 向量,并经历相同的求解过程,或者只选择 bv1 和 bv2。

零点

您提到 OQ 中的窗格没有锚点,但有必要将您的窗格与无限的平行窗格系列区分开来。

如果您的锚点是 (0,0,0),这是坐标转换的完美锚点,并且您的窗格具有

x*xn+y*yn+z*zn=0,
(y0,y0,z0)=(0,0,0)

如果不是,我假设您的锚点为 (xa,ya,za) 并且您的窗格具有

x*xn+y*yn+z*zn=d

d常量标量。一个自然的拟合将是窗格的点,它是由原始零点到窗格上的法线投影定义的:

P0=(x0,y0,z0)

通过

(x0, y0, z0) = c * (xn,yn,zn)

解决这个问题

x*xn+y*yn+z*zn=d

c*xn*xn+c*yn*yn+c*zn*zn=d

从而

c=d/(xn*xn+yn*yn+zn*zn)

找到

P0=(x0,y0,z0)=c*(xn,yn,zn)

最终转换

是通过将窗格中的每个点(即您想要显示的点)表示为

P0+x'*bv1+y'*bv2

x' 和 y' 为新坐标来实现的。因为我们知道 P0、bv1 和 bv2,所以这是非常简单的。如果我们不处于边缘情况,则 bv1.y 和 bv2.x 中的值为零,进一步减少问题。

x' 和 y' 是您想要的新坐标。

Your pane is defined by a normal vector

n=(xn,yn,zn)

For coordination transformation we need 2 base vectors and a zero point for the pane

Base vectors

We chose those "naturally" fitting to the x/y pane (see later for edge case):

b1=(1,0,zb1)
b2=(0,1,zb2)

And we want

b1 x b2 = n*c (c const scalar)

to make sure these two are really bases

Now solve this:

b1 x b2= (0*zb2-zb1*1,zb1*0-1*zb2,1*1-0*0) = (zb1,zb2,1)
zb1*c=xn
zb2*c=yn
1*c=zn

c=zn,
zb2=yn/c=yn/zn
zb1=xn/c=xn/zn

b1=(1,0,yn/zn)
b2=(0,1,xn/zn)

and normalize it

bv1=(1,0,yn/zn)*sqrt(1+(yn/zn*yn/zn))
bv2=(0,1,yn/zn)*sqrt(1+(xn/zn*xn/zn))

An edge case is, when zn=0: In this case the normal vector is parallel to the x/y pane and no natural base vectors exist, ind this case you have to chose base b1 and b2 vectors by an esthetic POV and go through the same solution process or just chose bv1 and bv2.

Zero point

you spoke of no anchor point for your pane in the OQ, but it is necessary to differentiate your pane from the infinite family of parallel panes.

If your anchor point is (0,0,0) this is a perfect anchor point for the coordinate transformation and your pane has

x*xn+y*yn+z*zn=0,
(y0,y0,z0)=(0,0,0)

If not, I assume you have an anchor point of (xa,ya,za) and your pane has

x*xn+y*yn+z*zn=d

with d const scalar. A natural fit would be the point of the pane, that is defined by normal projection of the original zero point onto the pane:

P0=(x0,y0,z0)

with

(x0, y0, z0) = c * (xn,yn,zn)

Solving this against

x*xn+y*yn+z*zn=d

gives

c*xn*xn+c*yn*yn+c*zn*zn=d

and

c=d/(xn*xn+yn*yn+zn*zn)

thus

P0=(x0,y0,z0)=c*(xn,yn,zn)

is found.

Final transformation

is achieved by representing every point of your pane (i.e. those points you want to show) as

P0+x'*bv1+y'*bv2

with x' and y' being the new coordinates. Since we know P0, bv1 and bv2 this is quite trivial. If we are not on the edge case, we have zeroes in bv1.y and bv2.x further reducing the problem.

x' and y' are the new coordinates you want.

因为看清所以看轻 2025-01-01 11:26:11

我想添加 Eugen 的答案,针对 zn=0 扩展的情况提出建议他的回答并提供了替代解决方案(类似)。

zn=0 的情况下,您实际上可以将所有平面视为围绕 z 轴的圆中的点,半径取决于平面的参数。
任何与半径正交的向量都应该平行于平面,而半径是平面的法线。

因此,在某种程度上,问题被简化为二维空间。
平面的法线为(xn, yn, 0)
通过使用一种技术来查找二维正交向量,我们得到基向量可以是(-yn, xn, 0)
第二个基向量是(0, 0, 1),它只是它们叉积的归一化向量。我们可以通过开发以下表达式来看到这一点:
corss_product((-yn, xn, 0), (xn, yn, 0)) =
(xn*0 - 0*yn, 0*xn - (-yn)*0, (-b)*b - a*a) =
(0, 0, -(xn^2 + yn^2))
标准化和求反后变为 (0, 0, 1)
从这里,我建议使用 b1=normalize(-yn, xn, 0)b2=(0, 0, 1)

现在,有一个使用这种方法的更通用的解决方案。
如果您要计算 (-yn, xn, 0)(xn, yn, zn) 的点积,您会发现它们对于任何zn(-yn, xn, 0) 也是相关平面的一部分(当 d=0 时)。因此,只要 xnyn 至少其中之一不为零,这实际上就有效(因为否则 (-yn, xn, 0) 是实际上只是(0, 0, 0))。
为了确保清楚,第二个基向量又是它们的叉积,即:b1=(-yn, xn, 0)b2=cross_product(b1, n)< /代码>。

那么,如果xnyn都为零呢?在这种情况下,该平面平行于 xy 平面。现在很简单,只需选择 b1=(1, 0, 0)b2=(0, 1, 0) 即可。
作为另一种方法,当 d 不为 0 时使用锚向量,完全按照此处的描述,无需更改。

摘要:2种不同的解决方案:

  • 使用Eugen的答案答案以及zn=0的情况,取:b1=(-yn, xn, 0) 和 b2=(0, 0, 1) 。
  • 另一种方法:如果 xnyn 都等于 0,则取 b1=(1, 0, 0)b2=( 0, 1, 0),否则取 b1=(-yn, xn, 0)b2=cross_product(b1, n)

在这两种解决方案中,都使用上述答案所述的锚向量 P0

I would like to add to Eugen's answer, a suggestion for the case where zn=0 extending his answer and also offer an alternative solution (which is similar).

In the case of zn=0, you can actually think of all the planes as points in a circle around the z-axis and the radius depends on the parameters of the plane.
Any vector orthogonal to the radius should be parallel to the plane, while the radius being the normal of the plane.

So in some way, the problem is reduced to a 2D-space.
The normal to the plane is (xn, yn, 0).
By using a technique to find orthogonal vectors in 2D, we get that a base vector could therefore be (-yn, xn, 0).
The second base vector is (0, 0, 1) which is just the normalized vector of their cross product. We can see that by developing the following expression:
corss_product((-yn, xn, 0), (xn, yn, 0)) =
(xn*0 - 0*yn, 0*xn - (-yn)*0, (-b)*b - a*a) =
(0, 0, -(xn^2 + yn^2)).
Which after normalizing and negating becomes (0, 0, 1).
From here, I suggest b1=normalize(-yn, xn, 0) and b2=(0, 0, 1).

Now, there's an even more general solution using this approach.
If you'll develop the dot product of (-yn, xn, 0) and (xn, yn, zn), you'll see that they are orthogonal for any zn while (-yn, xn, 0) also being part of the plane in question (when d=0). Thus, this actually works as long at least one of xn and yn is not zero (because otherwise (-yn, xn, 0) is actually just (0, 0, 0)).
Just to make sure it's clear, the second base vector is again their cross product, that is: b1=(-yn, xn, 0) and b2=cross_product(b1, n).

Well then, what about the case where both xn and yn are zero? In this case the plane is parallel to the xy plane. Now that's an easy one, just choose b1=(1, 0, 0) and b2=(0, 1, 0).
And as the other approach, use an anchor vector when d is not 0, exactly as it is described there, no changes needed.

Summary: 2 different solutions:

  • Use Eugen's answer answer and for the case of zn=0, take: b1=(-yn, xn, 0) and b2=(0, 0, 1).
  • A different approach: If both xn and yn equal 0, take b1=(1, 0, 0) and b2=(0, 1, 0), otherwise take b1=(-yn, xn, 0) and b2=cross_product(b1, n).

In both solutions, use an anchor vector P0 as described by the aforementioned answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文