質問
方程式で与えられる平面を描きたい:ax+by+cz+d = 0。私は最初にx、yを設定して、式からzを取得して彼を描画しようとしました。 0x+0y+z+0 = 0などの飛行機があるため、これは正常に機能しませんでした...
私の現在の解決策は次のとおりです。 -Infinityに行く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)で分割する必要がある場合があります。
2つの軸のみを回転させると、任意の方向から他の方向にあなたを得ることができるので、xとyを選択します。
x軸についての回転の回転行列、およびy軸についてのbは次のとおりです。
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についての回転を行うと、XY平面に垂直なベクトルのyの回転が続くと(0,0,1)、次のようになります。
ry.rx. {0,0,1} = {-cos [a] sin [b]、sin [a]、cos [a] cos [b]}
これはあなたのABC値です。
すなわち
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軸についての角度があります。
この後、飛行機が既に持っているものと一致するまで上下にシフトする必要があります。
現時点で持っている平面(これらの2つの回転の後)は、+cz = 0によってax+になります。
あなたが望む平面はax+bx+cz+d = 0です。 Dを見つけるために、Z軸があなたの平面を横切る場所を見るでしょう。
IE CZ+D = 0-> Z = -D/C
したがって、ax+by+cz = 0 by -d/cでzを変換して、
ax+by+c(z+d/c)= ax+by+cz+d = 0。ああ、あなたはそれを見ますか!
回転する角度があれば、余分な数学をする必要がないことがわかります!
2つの角度は、A、B、およびCを提供します。
それが助けてくれることを願っています、私はあなたが実際に飛行機を描く計画を完全には完全には確信していません...
恐ろしいフォーマットを修正するために編集。うまくいけば、今はもっと良いです。
他のヒント
次の変換マトリックスが必要です。
[ 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の直交の2つのベクトルであり、投影の回転とスキューを定義します。
次に、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に直交する2つの直線的に独立したベクトルである可能性があります。
最初に、x0ベクトルのxy平面のベクトルを選択しましょう。
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)
}
最後に、skewを望まないとし、x0とy0の両方に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)テストでは十分ではありません。物事の実装を開始する前に、浮遊点数学を読んでください。
編集:明確にするためにいくつかの変数を変更しました