Równanie torusa leżącego w płaszczyźnie XZ:
(√x2+y2−R)2+y2=r2
Normalna to gradient funkcji:
f(x,y,z)=(√x2+y2−R)2+y2−r2
∇f=[2x−2xR√x2+z2,2y,2z−2zR√x2+z2]
Możemy także najpierw lekko uporządkować funkcje:
(√x2+z2−R)2+y2=r2
x2+z2−2R√x2+z2+R2+y2=r2
x2+y2+z2+R2−r2=2R√x2+z2
(x2+y2+z2+R2−r2)2=4R2(x2+z2)
f(x,y,z)=(x2+y2+z2+R2−r2)2−4R2(x2+z2)
∇f=[4x(x2+y2+z2+R2−r2)2−8xR2,4y(x2+y2+z2+R2−r2)2,4z(x2+y2+z2+R2−r2)2−8zR2]
W podejściu geometrycznym mamy punkt w który uderzył promień należący do torusa P(x,y,z). Torus leży w płaszczyźnie XZ. Rzut wektora →P (od środka torusa do punktu P) na płaszczyznę XZ to →A=[x,y,0]. Wektor o długości R o takim samym kierunku to →B=RˆA. Wektor ^→P−→B to normalna. Jeśli mamy uderzenie od środka torusa to należy ją wziąć ze znakiem minus.
Kod wszystkich trzech wersji:
public override Vector3 GetNormal( Intersection a_intersection) { Vector3 local_pos = a_intersection.LocalPos; //float R2 = m_local_big_radius * m_local_big_radius; //float n = local_pos.SqrLen + R2 - m_local_small_radius * m_local_small_radius; // //Vector3 normal = new Vector3( // local_pos.X * n - 2 * R2 * local_pos.X, // local_pos.Y * n, // local_pos.Z * n - 2 * R2 * local_pos.Z); // //if (a_intersection.BackHit) // return (LocalToWorldNormal * -normal).Normalized; //else // return (LocalToWorldNormal * normal).Normalized; if (a_intersection.BackHit) { return (LocalToWorldNormal * (new Vector3(local_pos.X, 0, local_pos.Z).Normalized * m_local_big_radius - local_pos)).Normalized; } else { return (LocalToWorldNormal * (local_pos - new Vector3(local_pos.X, 0, local_pos.Z).Normalized * m_local_big_radius)).Normalized; } //var nn = LocalToWorldNormal * new Vector3( // local_pos.X - local_pos.X * m_local_big_radius / // (float)Math.Sqrt(local_pos.X * local_pos.X + local_pos.Z * local_pos.Z), // local_pos.Y, // local_pos.Z - local_pos.Z * m_local_big_radius / // (float)Math.Sqrt(local_pos.X * local_pos.X + local_pos.Z * local_pos.Z) // ).Normalized; //if (a_intersection.BackHit) // return -nn; //else // return nn; }
Brak komentarzy:
Prześlij komentarz