x=P+→dt
Parametr t możemy potraktować jako czas. Jest ono identyczne z równaniem parametrycznym linii, nadajemy tylko innego znaczenia parametrom. Równanie parametryczne płaszczyzny w postaci wektorowej:
→n⋅x+D=0
Z porównania:→n(P+→dt)+D=0
Stąd:t=−D+→nP→n⋅→d
Jeśli t<0 to przecięcie nastąpiło po przed miejscem wyjścia promienia. Traktując promień jako prostą takie t ma sens. Jeśli t>=0 punkt przecięcia promienia z prostą istnieje. Warunkiem istnienia punktu przecięcia jest to by płaszczyzn była nierównoległa do promienia, czyli →n⋅→d≠0.
Punkt przecięcia wyznaczamy podstawiając t do równania prostej.
Aby ustalić z której strony płaszczyzny nastąpiło uderzenie badamy znak wyrażenia →n⋅→d. Jeśli →n⋅→d<0 uderzenie nastąpiło z przodu płaszczyzny (z kierunku który wskazuje normalna płaszczyzny). Jeśli →n⋅→d>0 uderzenie nastąpiło z tyłu. Jeśli →n⋅→d=0 promień jest równoległy do płaszczyzny.
Przykład implementacji w C#:
public override Intersection GetIntersection(Ray a_ray) { double denom = Normal * a_ray.Dir; if (OneSide) { if (denom > 0) return Scene.NoIntersection; } if (a_ray.PrevHit == this) return Scene.NoIntersection; if (!denom.IsZero()) { double dist = ((Normal * a_ray.Start) - Distance) / (-denom); if (dist <= 0) return Scene.NoIntersection; else { bool backHit = (denom > 0); if (backHit && OneSide) return Scene.NoIntersection; else { return new Intersection() { SceneObject = this, SourceRay = a_ray, Dist = dist, Scene = Scene, BackHit = backHit, Pos = a_ray.HitPoint(dist) }; } } } else return Scene.NoIntersection; }
Brak komentarzy:
Prześlij komentarz