3

私は C で Raytracer を書いており、球体を描画するためにデカルト方程式を使用しています。

x^2 + y^2 + z^2 = R^2.

目の位置 (x_eye、y_eye、z_eye) と目のベクトル (Vx、Vy、Vz) があります。私の線のパラメトリック方程式は次のとおりです。

x = x_eye + k * Vx  
y = y_eye + k * Vy  
z = z_eye + k * Vz

線のパラメトリック方程式を球のデカルト方程式に入れて、それを解きます

(x_eye + k * Vx)^2 + (y_eye + k * Vy)^2 + (z_eye + k * Vz)^2 = R^2  

(Vx^2 + Vy^2 + Vz^2) * k^2 + 2 * (x_eye*Vx + y_eye*Vy + z_eye*Vz) * k + (x_eye^2 + y_eye^2 + z_eye^2 - R^2) = 0  

ax^2 + bx + c = 0 のような式を取得し、a、b、c を次のように定義します。

a = (Vx^2 + Vy^2 + Vz^2) * k^2  
b = 2 * (x_eye * Vx + y_eye * Vy + z_eye * Vz) * k  
c = (x_eye^2 + y_eye^2 + z_eye^2 - R^2)  

次に、交差がある場合、各ピクセルの k を見つけることができます (b^2 - 4.ac >= 0)。


しかし、これらの線と球線 のパラメトリック方程式を使用して k を見つける他の方法はありますか?

x = x_eye + k * Vx  
y = y_eye + k * Vy  
z = z_eye + k * Vz  

球の場合:

x = R.cos(u).cos(v)  
y = R.sin(u).cos(v)  
z = R.sin(v)  

これら2つのパラメトリック方程式でkを見つけるにはどうすればよいですか?
やるべきですか

x_eye + k * Vx  = R.cos(u).cos(v)  
y_eye + k * Vy  = R.sin(u).cos(v)  
z_eye + k * Vz  = R.sin(v)  
4

2 に答える 2

2

システムを解決するには

x_eye + k * Vx  = R.cos(u).cos(v)  
y_eye + k * Vy  = R.sin(u).cos(v)  
z_eye + k * Vz  = R.sin(v)

各方程式の両辺を 2 乗することから始め、次に 3 つの方程式すべてを足し合わせます。次に、三角恒等式を使用して右辺を次のように単純化します。

(x_eye + k * Vx)^2 + (y_eye + k * Vy)^2 + (z_eye + k * Vz)^2 = R2  

これは、前に持っていたものと同じ方程式ですk

ただし、一般的には、これは実際的なアプローチではない可能性があります。レイトレーサーを作成しようとしているので、すべての方程式を手で解く必要はありません。代わりに、いくつかのシステム解決アルゴリズムを使用してください。良い出発点は、いくつかの変数に対するニュートン法とセカント法に関する情報を調べることです。数値解析の入門書には、作業を開始するための情報が豊富に含まれている必要があります。

于 2011-03-12T19:29:17.527 に答える
1

だからあなたの質問は基本的に「球光線の交差点を解決するための最良の方法は何ですか」。あなたはすでにコーディングの観点から最良の方法を使用していると思います。つまり、二次方程式を解きます(これはまさに私のレイトレーシングプロジェクトpvtraceで行っていることです。これが最良のアプローチであると思う理由はほとんどありません。

  1. これは分析的です。つまり、数値の反復は必要ありません。
  2. 球がヒットしたかどうかを判断するために、math.h関数を呼び出す必要はありません。つまり、b ^ 2-4.ac> = 0を使用するだけで、交差の判別式を計算できます(指摘したとおり)。
  3. さらに一歩進んで交点を計算する必要がある場合は、1回のsqrt()関数呼び出しを行うだけです。これは、trigへの複数の呼び出しよりも高速になると思います。ニュートンラプソン法と組み合わせた関数に加えて、コードがはるかに少なくなります(常に良いことです!)。
于 2011-03-13T13:52:40.703 に答える