Problem 6: Presjek prave i ravni.
Pretpostavimo da imamo pravu p na kojoj poznajemo koordinate tačaka A i B. Također pretpostavimo da imamo ravan Π
koja je definisana tačkom na ravni R i vektorom normale V. Potrebno je izračunati koordinate tačke A’ odnosno probodišta.
Rješenje:
Za rješenje ovog problem potrebno je da znamo parametarski oblik jednačine prave, odnosno jednačinu ravi. Pored toga potrebno je da znamo vektorski odnosno skalarni proizvod dva vektora.
Ukoliko imamo dvije tačke A i B, jednačina prave kroz dvije tačke data je kao:
,
gdje je koordinate tačke A, a koordinate tačke B.
Opći oblik jednačine ravni koja je definisana jednom tačkom i vektorom normale data je u obliku:
,
gdje je predstavlja koordinate vektora normale, a koordinate tačke R koja pripada toj ravni.
Postupak rješavanje probojne tačke je slijedeći:
1. Formirajmo parametarski oblike jednačine prave p, gdje t predstavlja parametar.
, ………(1)
2. Uvrštavajući gornju jednačinu prave u jednačinu ravni imamo:
. ………(2).
Zamjenom 1 u 2 možemo izračunati parametar t:
.
Kada imamo vrijednost parametra t, sada je moguće izračunati koordinate tražene tačke A’.
C# implementacija problema 6 izgleda na slijedeći način.
Implementacije klase Point koja implementira tačku u 3D prostoru preko koordinata x,z,y, te skupa metoda za skalarni, vektorski proizvod, kao i modul vektora.
class Point { public float x; public float y; public float z; public Point() { } public Point(float xx, float yy, float zz) { x = xx; y = yy; z = zz; } /// <summary> /// Izracunavanje vektorskog proizvoda dva vektora /// </summary> /// <param name="vectorA"></param> /// <param name="vectorB"></param> /// <returns>vektorski proizvod</returns> public static Point CrossProduct(Point vectorA, Point vectorB) { // | i j k | // | x1 y1 z1 |=i*(y1*z2-z1*y2)-j*(x1*z2-z1*x2)+k*(x1*y2-y1*x2) // | x2 y2 z2 | return new Point() { x = vectorA.y * vectorB.z - vectorA.z * vectorB.y, y = -vectorA.x * vectorB.z + vectorA.z * vectorB.x, z = vectorA.x * vectorB.y - vectorA.y * vectorB.x }; } /// <summary> /// Izracunavanje skalarnog proizvoda dva vektora /// </summary> /// <param name="vectorA"></param> /// <param name="vectorB"></param> /// <returns></returns> public static float ScalarProduct(Point vectorA, Point vectorB) { // proizvod=x1*x2+y1*y2+z1*z2 float retVal = vectorA.x * vectorB.x + vectorA.y * vectorB.y + vectorA.z * vectorB.z; return retVal; } /// <summary> /// Odredjivanje vektora kroz dvije tacke /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <returns></returns> public static Point Vector(Point A, Point B) { //referentni vektor ili pravac kroz referentne tačke na pravoj Point vektor = new Point(); vektor.x = B.x - A.x; vektor.y = B.y - A.y; vektor.z = B.z - A.z; return vektor; } /// <summary> /// Odredjivanje modula vektora /// </summary> /// <param name="A"></param> /// <returns></returns> public static float Modul(Point A) { return (float)Math.Sqrt(A.x*A.x+A.y*A.y); } }
Kada imamo ovako implementiranu klasu onda je određivanje probojne tačke prave i ravni dato kao:
static void Main(string[] args) { //Zadatak 1: data je ravan 2x-y+z-6=0 i prava (x)/-1 = (y-1)/-1 ) (z-6)/1 //ulazni podaci za zadatak 1. Point B = new Point(2f, 4f, 0f); //tacka na pravoj Point A = new Point(0f, 1f, -1f); //tačka na pravoj Point R = new Point(0f, 0f, 6f); //tacka na ravni Point Vn = new Point(2f, -1f, 1f); //vektor normalne ravni //Zadatak 2: data je ravan 2x-y+z-6=0 i prava (x-1)/-1 = (y+1)/-1 ) = (z-4)/1 //ulazni podaci za zadatak 2. //Point B = new Point(0f, -2f, 5f); //tacka na pravoj //Point A = new Point(1f, -1f, 4f); //tačka na pravoj //Point R = new Point(0f, 0f, 6f); //tacka na ravni //Point Vn = new Point(2f, -1f, 1f); //vektor normalne ravni //Probojna tačka koju treba odrediti Point proboj = new Point(); //Vektor pravca kojeg obrazuju tacke A i B Point zraka = Point.Vector(A,B); //ako je skalarni proizvod vektora prave i normale jednak nuli // tada prava ne sijece ravan float scalVal = Point.ScalarProduct(Vn,zraka); if(scalVal==0) { Console.WriteLine("Prava ne sijece ravan"); Console.Read(); return; } //skalarni proizvod tačke na ravni sa float D = Point.ScalarProduct(Vn,R); float AR = Point.ScalarProduct(A,Vn); float zrakaR = Point.ScalarProduct(zraka,Vn); // float t = (D - AR) / (zrakaR); //tacka probodistva proboj.x = A.x + zraka.x * t; proboj.y = A.y + zraka.y * t; proboj.z = A.z + zraka.z * t; Console.WriteLine("Tacka probodista je A'({0},{1},{2})",proboj.x,proboj.y,proboj.z); Console.Read(); }