[minirt]#5具体実施


光線照射時の軌跡一次方程式と球円を表す二次方程式が存在する.ルートの式を用いて,両者を組み合わせて,ルートの衝突の有無を解くことができる.
球を構成する構造体または生成者は実習資料を基礎とする.この部分は実習資料のコードとほぼ同じです.

円との衝突



前述の実験では,カメラから出発し,ビューポートを貫通する無数の画素の光線方向ベクトルを求めることに成功した.この方向ベクトルを用いると,画像上に3次元座標上に数値的に存在する物体を実現できる.

2 D円の方程式


理解するために、3 D座標平面ではなく2 D座標平面を想像してみてください.
座標平面上で円を表す方程式は次のとおりです.
x2+y2=r2x^2 + y^2 = r^2x2+y2=r2
円の中心が原点(0,0)の円であると仮定し,x,yは球上(円の境界)の座標,rはその円の半径を表す.

(-y,x)誤字!→ (x, -y)
座標点がどこにあるかにかかわらず、この式は成立しており、どの枠に垂直に足を下ろすと直角三角形が発生し、この三角形の斜面が円の半径になるので、ピタゴラスの定理で半径を求めることができる.
x2+y2=z2x^2 + y^2 = z^2x2+y2=z2

円心移動の円方程式

// object_create.c

struct t_point3
{
    double x;
    double y;
    double z;
};

t_sphere    sphere(t_point3 center, double radius)
{
    t_sphere sp;

    sp.center = center;
    sp.radius = radius;
    sp.radius2 = radius * radius;
    return (sp);
}

// main.c
t_sphere    sp;

sp = sphere(point3(-4, -8, -30), 20);
実際に円を配置すると、3 D座標の原点から離れた位置に配置されます.円の中心点はベクトル構造体で表されますが、原点からどのくらい離れているかを意味します.

実際の円の座標、円の中点が(3,2)の場合、半径の値を正しく導くには、円の球の座標値をどのくらい減算して移動する必要があります.
円の中心を表す座標をCと呼ぶと、次のように表すことができます.
(x−C.x)2+(y−C.y)2=r2(x - C.x)^2 + (y - C.y)^2 = r^2(x−C.x)2+(y−C.y)2=r2
このときx,yの座標は円の球囲を表す.どこでもいいです.

背面に表示します。


座標平面上の特定の点は、ベクトルで表すことができます.
円の中心がCであり、円の球がPである場合、円の半径rは、
∣CP→∣=r|\overrightarrow{CP}| = r∣CP∣=r|백터|は、ベクトルの長さ(スカラー)値を意味する.

このとき,両側を平方にして左側を内在的に表現することで,以下のような方式が成立する.
∣CP→∣2=r2|\overrightarrow{CP}|^2 = r^2∣CP∣2=r2
C⃗⋅P⃗=r2\vec C\cdot\vec P = r^2C⋅P=r2

ないぶとくせい


私は百メートルの長さの平方がどのように百メートルの内積と等しいのか理解していません.これは私の敵の特徴のためです.

内積フィーチャーでは、同じベクトルがある場合、2つのベクトルの形成角度は0度であるため、cos 0=1のフィーチャーを有する.したがって、ベクトルaの絶対値(長さ)の二乗が分かる.
[3 D数学]ベクトルの内積

中心Cは、ボールポジションPをバックフィールドに置き換える



二つの点C、Pが異なるにもかかわらず、同じ点(裏面P-backterC)で表現する方法が理解できず、絵を描きながら真似しているので、無理に理解できます.
各点は、次の接尾辞で表すことができます.

逆数の減算はAベクトル+(−B)ベクトル(逆数)に等しい.
バックグラウンドPからバックグラウンドCを減算すると、バックグラウンドPの終点でバックグラウンドCの起点を反対方向に伸ばします.


リトラクトの結果はリトラクトの大きさと方向が同じで、2つのリトラクトの大きさ、方向が同じであれば、位置に関係なく同じリトラクトになります.
つまり、
(P⃗−C⃗)⋅(P⃗−C⃗)=r2(\vec P -\vec C)\cdot (\vec P -\vec C)= r^2(P−C)⋅(P−C)=r2
ここで,光を出射する際,その光が円の球に衝突し,後Pを光を出射する際の方程式に変換すると仮定する.
(3)ベクトル演算!

光を放つと


こうせんほうていしき


次の方法は、実際にレーザ光を放出する場合の方法です.
P(t)=O+D×tP(t) = O + D\times tP(t)=O+D×t

O-原点座標


これは
  • 光を放出する起点です.
  • (0, 0, 0)
  • D方向ベクトル

  • ユニットバック、ベクトル指向.
  • tベクトルの大きさ(長さ)

  • スカラは、1を基準に標準化されていて、どれくらい時間がかかるか分かりません.
  • 光線が衝突したとき


    方向ベクトル方向に光線を射出する場合、座標上の球に我々が射出した光線に当たる点があると、その点が円の球上、後P、tの値が、接触点と頂点Aとの間のグラム数となる.

    このときベクトルPをP(t)に置き換えても問題はない.距離が分からなくても、単位が100メートルであることを知っているので、同じ方向に出続けると、当たる光にぶつかることがあります.

    解が存在する場合,この式の結果は私たちが射出した光が球にあることを示している.
    すなわち,上に展開したポストPは,我々が実際に放出したレーザ光の方程式に対応している.
    (P⃗−C⃗)⋅(P⃗−C⃗)=r2(\vec P -\vec C)\cdot (\vec P -\vec C)= r^2(P−C)⋅(P−C)=r2
    (P(t)−C)∗(P(t)−C)=r2(P(t) - C) * (P(t) - C) = r^2(P(t)−C)∗(P(t)−C)=r2
    上記の儀式を展開し、以下のようにします.
    (t⋅t)t2+2tD⋅(O−C)+(O−C)⋅(O−C)−r2=0(t\cdot t)t^2 + 2tD\cdot (O - C) + (O-C)\cdot (O-C) - r^2 = 0(t⋅t)t2+2tD⋅(O−C)+(O−C)⋅(O−C)−r2=0
    もう一度指摘しましょう.

    O-背面の原点、光線起点


    D-光線の単位バックエンド、0~1の範囲の値。


    t-backの長さは,1で標準化された単位ベクトルで,値がどの程度であるかは不明である.


    C-円の中心点は、後方ではなく、3 D空間内の座標です。原点からどのくらい離れているかを含めます。


    r-円の半径。


    カメラの位置はA(頂点座標)であり、rayを射出する方向b(方向ベクトル)が知られている.また,球中央の頂点座標Cと球の直径rはともに知られている.
    したがって,我々が知らない変数はtであり,tの式に対して上の式を整理すると,次のような式が得られる.
    私たちが要求する値はt値です.二次方程式の解を求めるために,ルートの式を用いることができる.上の式をルートの式で解くと、次のような形になります.
    At2+Bt+C=0At^2 + Bt + C = 0At2+Bt+C=0
    この場合、t(x)の二次項、一次項、定数項は以下のようになる.
    A=D⋅DA = D\cdot DA=D⋅D
    B=2D⋅(O−C)B = 2D\cdot (O - C)B=2D⋅(O−C)
    C=(O−C)⋅(O−C)−r2C = (O - C)\cdot (O - C) - r^2C=(O−C)⋅(O−C)−r2
    これをよく知られているルートの公式に変えて、次のように変えることができます.
    −b±b2−4ac2a{-b\pm\sqrt{b^2 - 4ac} }\over {2a}2a−b±b2−4ac​​

    ルート判別式


    光が図形に衝突するかどうかの判定は根の有無にかかっている.ルートが存在する場合、光線、方程式は円と衝突することを意味するからです.これに対する判別式は以下の通りである.
    b2−4ac\sqrt{b^2 - 4ac}b2−4ac​
    ルートの式に基づいてルートの存在を判断します.
    光線が照射されたときの値が0以上の場合、光線は円と衝突し、0未満の場合は衝突しないと判断できます.


    次のようにコードに移動します.
    // hit_sphere.c
    
    t_bool      hit_sphere(t_sphere *sp, t_ray *ray)
    {
        t_vec3  oc; // 0에서부터 벡터로 나타낸 구의 중심.
        //a, b, c는 각각 t에 관한 근의 공식 2차 방정식의 계수
        double  a;
        double  b;
        double  c;
        double  discriminant; //판별식
    
        oc = vminus(ray->orig, sp->center);
        a = vdot(ray->dir, ray->dir);
        b = 2 * vdot(oc, ray->dir);
        c = vdot(oc, oc) - sp->radius2;
        discriminant = (b * b) - (4 * a * c);
        printf ("a : %f, b: %f, c : %f, 판별식 : %f\n", a, b, c, discriminant);
    
        // 판별식(내적의 값)이 0보다 크다면 광선이 구를 hit한 것!
        // 내적이 양수 : cos 값이 양수, 예각
        // 내적이 0 : cos 값이 0, 직각
        // 내적이 음수 : cos 값이 음수, 둔각
         
        return (discriminant > 0);
    }
    判別式の判別式が0より大きいと、その光線は、その物体に衝突し、その物体の色でその画素の色を置き換えるルートが存在することを示す.

    判別式が分かれば,二次方程式の根の個数が分かる.
    (6)レーシングカーOne Weekend式を理解!3
    mini_raytracing_in_c/04.sphere.md at main · GaepoMorningEagles/mini_raytracing_in_c