//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop

#include "stereo.h"
#include "math.h"
//---------------------------------------------------------------------------
//	Konstruktor główny, inicjujący wszystkie parametry projekcji.
TStereo :: TStereo( TPunkt obs,     //pozycja obserwatora
    int xe0, int ye0, int eszer, int ewys,  //okno ekranowe
    double baza,                    //odległość między oczami
    TCanvas *Acnv,                  //aparat graficzny
    StylPatrzenia sp/*=Zezem*/,     //typ okularów stereo
    double odl_ekr/*=0.5*/)
{
 TPunkt Lobs, Robs;                 //pozycja lewego i prawego oka
 int Lxe0, Lye0, Leszer, Lewys;     //oklo ekranowe obrazu dla lewego oka
 int Rxe0, Rye0, Reszer, Rewys;     //oklo ekranowe obrazu dla lewego oka
 double r1;                         //odległość obserwatora w płaszczyźnie OXY
 double sf, cf, b = baza/2;         //pomocnicze

 cnv = Acnv;                        //przechowanie adresu aparatu graficznego

 r1 = sqrt( obs.x * obs.x + obs.y * obs.y);
 if( r1 != 0)
 {
    sf = obs.y / r1;                //sin( fi)
    cf = obs.x / r1;                //cos( fi)
 }
 else
 {
    sf = 0;
    cf = 1;
 }

 Lobs.x = obs.x + b * sf;           //współrzędne lewego oka
 Lobs.y = obs.y - b * cf;
 Lobs.z = obs.z;

 Robs.x = obs.x - b * sf;           //współrzędne prawego oka
 Robs.y = obs.y + b * cf;
 Robs.z = obs.z;

 switch( sp)
 {
  case Zezem:                       //lewy obraz z prawej i odwrotnie
            Lxe0 = xe0 + eszer / 2;
            Lye0 = ye0;
            Leszer = eszer / 2;
            Lewys = ewys;
            Rxe0 = xe0;
            Rye0 = ye0;
            Reszer = eszer / 2;
            Rewys = ewys;
            break;
  case Peryskopy:                   //lewy obraz z lewej i prawy z prawej
            Lxe0 = xe0;
            Lye0 = ye0;
            Leszer = eszer / 2;
            Lewys = ewys;
            Rxe0 = xe0 + eszer / 2;
            Rye0 = ye0;
            Reszer = eszer / 2;
            Rewys = ewys;
            break;
  case Anaglif:                     //lewy i prawy obraz w tym samym miejscu
            Lxe0 = xe0;
            Lye0 = ye0;
            Leszer = eszer;
            Lewys = ewys;
            Rxe0 = xe0;
            Rye0 = ye0;
            Reszer = eszer;
            Rewys = ewys;
            break;
 }

 L = new T3d( Lobs, Lxe0, Lye0, Leszer, Lewys, odl_ekr);
 R = new T3d( Robs, Rxe0, Rye0, Reszer, Rewys, odl_ekr);
}
//---------------------------------------------------------------------------
//  Destruktor likwiduje obiekty Renderujące obraz dla lewego i prawego oka.
TStereo :: ~TStereo()
{
 delete R;
 delete L;
}
//---------------------------------------------------------------------------
//  Wykreślenie punktu dla lewego i prawego oka
bool TStereo :: punkt_stereo( TPunkt p,
        TColor Lkolor/*=clBlack*/, TColor Rkolor/*=clBlack*/)
{
 bool ret = true;
 int xe, ye;

 if( L -> punkt_3d( xe, ye, p))
    cnv -> Pixels[ xe][ ye] = Lkolor;
 else
    ret = false;

 if( R -> punkt_3d( xe, ye, p))
    cnv -> Pixels[ xe][ ye] = Rkolor;
 else
    ret = false;

 return ret;
}
//---------------------------------------------------------------------------
//  Wykreślenie linii dla lewego i prawego oka
bool TStereo :: linia_stereo( TPunkt p1, TPunkt p2,
        TColor Lkolor/*=clBlack*/, TColor Rkolor/*=clBlack*/)
{
 bool ret = true;
 int xe1, ye1, xe2, ye2;

 if( L -> punkt_3d(xe1, ye1, p1) &&
     L -> punkt_3d(xe2, ye2, p2))
 {
    cnv -> Pen -> Color = Lkolor;
    cnv -> MoveTo( xe1, ye1);
    cnv -> LineTo( xe2, ye2);
 }
 else
    ret = false;

 if( R -> punkt_3d(xe1, ye1, p1) &&
     R -> punkt_3d(xe2, ye2, p2))
 {
    cnv -> Pen -> Color = Rkolor;
    cnv -> MoveTo( xe1, ye1);
    cnv -> LineTo( xe2, ye2);
 }
 else
    ret = false;

 return ret;
}
//---------------------------------------------------------------------------
//  Wykreślenie czworokąta w wersji dla lewego i prawego oka
bool TStereo :: czworokat_stereo( TPunkt p1, TPunkt p2, TPunkt p3, TPunkt p4,
        TColor Lkolor1/*=clBlack*/, TColor Rkolor1/*=clBlack*/,    //kolory konturów
        TColor Lkolor2/*=clWhite*/, TColor Rkolor2/*=clWhite*/)    //kolory wypełnień
{
 bool ret = true;
 int xe1, ye1, xe2, ye2, xe3, ye3, xe4, ye4;
 TPoint p[ 4];                               //rogi rozpinanego czworokata

 if( L -> punkt_3d(xe1, ye1, p1) &&
     L -> punkt_3d(xe2, ye2, p2) &&
     L -> punkt_3d(xe3, ye3, p3) &&
     L -> punkt_3d(xe4, ye4, p4))
 {
    cnv -> Pen -> Color = Lkolor1;
    cnv -> Brush -> Color = Lkolor2;
    p[0].x = xe1, p[0].y = ye1;
    p[1].x = xe2, p[1].y = ye2;
    p[2].x = xe3, p[2].y = ye3;
    p[3].x = xe4, p[3].y = ye4;
    cnv -> Polygon( p, 3);
 }
 else
    ret = false;

 if( R -> punkt_3d(xe1, ye1, p1) &&
     R -> punkt_3d(xe2, ye2, p2) &&
     R -> punkt_3d(xe3, ye3, p3) &&
     R -> punkt_3d(xe4, ye4, p4))
 {
    cnv -> Pen -> Color = Rkolor1;
    cnv -> Brush -> Color = Rkolor2;
    p[0].x = xe1, p[0].y = ye1;
    p[1].x = xe2, p[1].y = ye2;
    p[2].x = xe3, p[2].y = ye3;
    p[3].x = xe4, p[3].y = ye4;
    cnv -> Polygon( p, 3);
 }
 else
    ret = false;

 return ret;
}

