Analitička geometrija i C# programiranje dio 5/n


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:

\frac{x-X_A}{X_B-X_A}=\frac{y-Y_A}{Y_B-Y_A}=\frac{z-Z_A}{Z_B-Z_A},

gdje je (X_A,Y_A,Z_A) koordinate tačke A, a (X_B,Y_B,Z_B) koordinate tačke B.

Opći oblik jednačine ravni koja je definisana jednom tačkom i vektorom normale data je u obliku:

A(x-X_R)+B(y-Y_R)+C(z-Z_R)=0 ,

gdje je (A,B,C) predstavlja koordinate vektora normale, a R(X_R,Y_R, Z_R) 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.

p(t)=A+t(B-A), ………(1)

2. Uvrštavajući gornju jednačinu prave u jednačinu ravni imamo:

V x (A'-V)=0. ………(2).

Zamjenom 1 u 2 možemo izračunati parametar t:

t= V x (V-A)/(N x (B-A)) .

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();
}