我想绘制一个由方程式给出的平面:ax+by+cz+d = 0。我首先试图通过设置X,Y将他绘制,然后从方程式中获取Z。这不正常,因为有一些平面,例如0x+0y+Z+0 = 0和等...

我当前的解决方案是: - 通过提供4个坐标,将平面绘制在ZY平面上。 - 找出应进行旋转,以使给定平面的正常(a,b,c)放在z轴上。 - 找到应该为该平面放在X轴上的平面。 - 对那些旋转的完全相反的转换以及对此翻译的转换,因此我将获得
飞机代替他。

好的

这是一件很棒的事情,但是我可以用点产品等进行适当的数学计算(尝试很多次...)。

有人可以帮助我理解应完成的确切方式,或者给我一些我要放置ABCD并进行正确转换的公式?

有帮助吗?

解决方案

这是你在问什么吗?

将像XY平面这样的简单平面转换为飞机非常简单:

您的飞机是ax+by+cz+d = 0

XY平面简单地z = 0。 IE A = B = D = 0,而C =无论您想要什么。为了简单起见,我们会说1。

当您以这种形式的平面时,平面的法线将由向量定义(a,b,c)

因此,您需要轮换,将您从(0,0,1)带到(a,b,c)**

*请注意,仅当{a,b,c}是统一时才起作用。因此,您可能必须将AB和C除以SQRT(A^2+B^2+C^2)。

仅绕两个轴旋转可以使您从任何方向转向任何其他方向,因此我们会选择X和Y。

这是旋转旋转矩阵的旋转矩阵,该旋转大约是X轴,而B大约在Y轴上。

rx:= {{1,0,0},{0,cos [a],sin [a]},{0,-sin [a],cos [a]}}

ry:= {{cos [b],0,-sin [b]},{0,1,0},{sin [b],0,cos [b]}}

如果我们进行大约x的旋转,然后进行旋转,大约是y的y,xy平面正常(0,0,1),我们得到:

ry.rx. {0,0,1} = {-cos [a] sin [b],sin [a],cos [a] cos [b]}

哪个是您的ABC值。

IE

a = -cos [a] sin [b

b = sin [a

c = cos [a] cos [b

从这里开始,这很简单。

a = asin [b

所以现在a = -cos [asin [b]] sin [b

cos [asin [x]] = sqrt(1-x^2)so:

a = -sqrt [1 -b^2] * sin [b

b = asin [-a/sqrt [1-b^2]

a = asin [b](围绕x轴旋转)

b = asin [-a/sqrt [1-b^2]](围绕y轴旋转)

因此,我们现在拥有有关X和Y轴的角度,需要旋转。

此后,您只需要向上或向下移动飞机,直到与已经拥有的飞机匹配。

您目前拥有的平面(这两个旋转之后)将为AX+By+Cz = 0。

您想要的平面是AX+BX+CZ+D = 0。为了找出D,我们将看到Z轴在哪里越过您的飞机。

IE CZ+D = 0-> Z = -D/C

因此,我们将您的z在ax+by+cz = 0中通过-d/c转换为:

ax+by+c(z+d/c)= ax+by+cz+d = 0。哦,你会看的!

事实证明,一旦有了旋转的角度,就不必做任何额外的数学!

这两个角度将为您提供A,B和C。为了让D您只需从所拥有的东西中复制它即可。

希望这有所帮助,我不确定您打算如何实际绘制飞机...

编辑以修复一些可怕的格式。希望现在更好。

其他提示

您将需要以下转换矩阵:

    [ x0_x y0_x z0_x o_x ]
M = [ x0_y y0_y z0_y o_y ]
    [ x0_z y0_z z0_z o_z ]
    [    0    0    0   1 ]

在这里,Z0是平面的正常,O是平面的原点,X0和Y0是平面与Z0正交的两个向量,定义了投影的旋转和偏斜。

然后,您的xy平面上的任何点(x,y)都可以投影到一个点(p_x,p_y,p_z),您的新平面以下:

(p_x, p_y, p_z, w) = M * (x, y, 0, 1)

现在,转换矩阵中的Z0很容易,这是您飞机的正常 n = normalize(a,b,c).

但是,在选择其余部分时,您拥有更多的自由。对于原点,您可以指出平面相交Z轴,除非平面平行于Z轴,在这种情况下,您需要其他东西。

所以

if (c != 0) { //plane intersects Z axis
  o_x = 0;
  o_y = 0;
  o_z = -d/c;
}
else if (b != 0) { // plane intersects Y axis
  o_x = 0;
  o_y = -d/b;
  o_z = 0;
}
else { // plane must intersect the X axis
  o_x = -d/a;
  o_y = 0;
  o_z = 0;
}

实际上,您可能希望与 (c != 0), ,因为有了该测试,它甚至会成功的是C非常小,但与零不同,导致您的起源是说话的, x=0, y=0, z=10e100 这可能是不可取的。所以一些测试 (abs(c) > threshold) 可能是最好的。但是,您当然可以在飞机上完全不同的一点来放置原点,也许是最接近原始坐标系的原点,这将是:

o = n * (d / sqrt(a^2 + b^2 + c^2))

最后,我们需要找出X0和Y0。这可能是与Z0正交的任何两个线性独立的向量。

因此,首先,让我们在XY平面中为我们的X0矢量选择一个向量:

x0 = normalize(z0_y, -z0_x, 0)

现在,如果您的Z0恰好是表格(0、0,Z0_Z),则会失败,因此我们需要一个特殊情况:

if (z0_x == 0 && z0_y == 0) {
  x0 = (1, 0, 0)
}
else {
  x0 = normalize(z0_y, -z0_x, 0)
}

最后,假设我们不希望偏斜,选择y0与x0和y0都是正交的,然后使用交叉产品

y0 = normalize(x0_y*y0_z-x0_z*y0_y, x0_z*y0_x-x0_z*y0_z, x0_x*y0_y-x0_y*y0_x)

现在,您可以填写转换矩阵。

免责声明:在使用浮点数表示您的数字时应采取适当的注意,在这种情况下,简单(FOO == 0)测试不足。在开始实施内容之前,请阅读浮点数学。

编辑:为了清晰而更名一些变量

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top