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

#include "ffiltracja3.h"
#include "skala.h"
#include "math.h"
#include "widmo.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1 :: TForm1(TComponent* Owner): TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
 int i, j;
 inicjuj_parametry();
 for( i = 0; i < IL_PODZ; i ++)
 {
    for( j = 0; j < IL_PODZ; j ++)
    {
        P[ i][ j] = 0;  //nie ma dziurek
        F[ i][ j] = 1;  //nie ma filtra
        E[ i][ j] = 0;  //nie ma obrazu
    }
 }
}
//---------------------------------------------------------------------------
//  Wyodrębniony algorytm sczytywania nastaw interfejsu.
void TForm1 :: inicjuj_parametry( void)
{
 try                        //spodziewamy się różnych błędów w danych
 {
    rozm_p = 0.001*Edit1 -> Text.ToDouble(); //szerokość przesłony
    rozm_e = 0.001*Edit2 -> Text.ToDouble(); //szerokość ekranu
    odl    = Edit3 -> Text.ToDouble();       //odległość ekran-przesłona
    L      = 1e-6*Edit4 -> Text.ToDouble();  //dłg. fali światła
 }
 catch(...)                 //nie zmienione wartości parametrów
 {
 }
}
//---------------------------------------------------------------------------
//  Odczyt z dysku mapy bitowej przesłony.
//  (Rozmiar mapy powinien być uzgodniony z wymiarem IL_PODZ)
//  Przepisanie mapy z unormowaniem do tablicy P.
//  Pod uwagę jest brana składowa czerwona koloru piksela.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 if( OpenDialog1 -> Execute())
 {
    int i, j;
    Graphics::TBitmap *b = new Graphics::TBitmap();
    try
    {
        b -> LoadFromFile( OpenDialog1 -> FileName);
        for( i = 0; i < IL_PODZ; i ++)
            for( j = 0; j < IL_PODZ; j ++)
                P[i][j] = GetRValue( b->Canvas->Pixels[i][j])/255.;
    }
    catch (...)
    {
        MessageBeep(0);
    }
    delete b;
    PaintBox1 -> Refresh();          //odrysowanie nowej zawartości przesłony
 }
}
//---------------------------------------------------------------------------
//  Odczyt z dysku mapy bitowej filtru
//  (Rozmiar mapy powinien być uzgodniony z wymiarem IL_PODZ)
//  Przepisanie mapy z unormowaniem do tablicy F.
//  Pod uwagę jest brana składowa czerwona koloru piksela.
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 if( OpenDialog2 -> Execute())
 {
    int i, j;
    Graphics::TBitmap *b = new Graphics::TBitmap();
    try
    {
        b -> LoadFromFile( OpenDialog2 -> FileName);
        for( i = 0; i < IL_PODZ; i ++)
            for( j = 0; j < IL_PODZ; j ++)
                F[i][j] = GetRValue( b->Canvas->Pixels[i][j])/255.;
    }
    catch (...)
    {
        MessageBeep(0);
    }
    delete b;
    PaintBox2 -> Refresh();          //odrysowanie nowej zawartości przesłony
 }
}
//---------------------------------------------------------------------------
//  Konstrukcja obrazu interferencyjnego z uwzględnieniem filtra.
//  Na zakonczenie unormowanie tego obrazu do zakresu -1...+1
void __fastcall TForm1::Button3Click(TObject *Sender)
{
 TCursor old = Cursor;
 Cursor = crHourGlass;        //kursor = klepsydra

 inicjuj_parametry();         //odczyt parametrów fizycznych

 int i, j, m, n;
 double x_p, y_p, x_e, y_e;   //bieżąca pozycja na przesł. i ekr.
 double r;                    //odległość bieżących pozycji przesł. - ekr.
 double odl2 = odl*odl;       //pomocnicze - kwadrat odległości przysł.-ekr.
 double k = 2 * M_PI/L;       //pomocnicze - tzw. liczba falowa
 double a;                    //amplituda przefiltrowana
 double suma_fal;             //amplituda złożenia fal ze wszystkich otworków
 double min_suma_fal=0, max_suma_fal=0;	//wartości skrajne do unormowania amplitud na ekranie
 TSkalowanie s_p( 0, 0, IL_PODZ-1, IL_PODZ-1, 0, 0, rozm_p, rozm_p);
 TSkalowanie s_e( 0, 0, IL_PODZ-1, IL_PODZ-1, 0, 0, rozm_e, rozm_e);

 for( i = 0; i < IL_PODZ; i++)
 {
    x_e = s_e.daj_real_x( i);
    for( j = 0; j < IL_PODZ; j++)
    {
        y_e = s_e.daj_real_y( j);
        suma_fal = 0.0;         //ważne. Za chwilę zbierzemy tutaj amplitudy
        for( m = 0; m < IL_PODZ; m++)
        {
            x_p = s_p.daj_real_x( m);
            for( n = 0; n < IL_PODZ; n++)
            {
                a = P[m][n]*F[m][n];  //przefiltrowana amplituda
                if( a != 0)    //jest światło?
                {
                    y_p = s_p.daj_real_y( n);
                    r = sqrt((x_e-x_p) * (x_e-x_p) + (y_e-y_p) * (y_e-y_p) + odl2);
                    suma_fal += a * sin( k*r);
                }
            }
        }
        E[i][j] = suma_fal;     //przechowanie wyliczonej amplitudy
        if( suma_fal < min_suma_fal)
       	    min_suma_fal = suma_fal; //wyłapanie najmniejszej amplitudy
        if( suma_fal > max_suma_fal)
       	    max_suma_fal = suma_fal; //wyłapanie największej amplitudy
    }
 }
 if( max_suma_fal < -min_suma_fal)   //która ze skrajnych wartości jest bezwzględnie większa?
    max_suma_fal = - min_suma_fal;
 if( max_suma_fal != 0)
 {
    for( i = 0; i < IL_PODZ; i ++)   //zawartość tablicy unormuj do zakresu -1 ...+1
	    for( j = 0; j < IL_PODZ; j ++)
            E[i][j] = E[i][j] / max_suma_fal;
 }
 PaintBox3 -> Refresh();        //odrysowanie nowej zawartości ekranu

 Cursor = old;                  //stary kursor
}
//---------------------------------------------------------------------------
//  Skopiowanie do przesłony obrazu interferencyjnego.
void __fastcall TForm1::Button4Click(TObject *Sender)
{
 int i, j;
 for( i = 0; i < IL_PODZ; i ++)
 {
    for( j = 0; j < IL_PODZ; j ++)
    {
        P[ i][ j] = E[ i][ j];
    }
 }
 PaintBox1 -> Refresh();            //odrysowanie nowej zawartości przesłony
}
//---------------------------------------------------------------------------
//  Koniec
void __fastcall TForm1::Button5Click(TObject *Sender)
{
 Close();
}
//---------------------------------------------------------------------------
//  Wyświetlenie przesłony
void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{
 int i, j, m, n, a;
 TSkalowanie s( 0, PaintBox1 -> Height, PaintBox1 -> Width, -PaintBox1 -> Height,
                IL_PODZ/2, IL_PODZ/2, IL_PODZ, IL_PODZ);
 for( i = 0; i < PaintBox1 -> Width; i ++)
 {
    m = s.daj_real_x( i);
    for( j = 0; j < PaintBox1 -> Height; j ++)
    {
        n = s.daj_real_y( j);
        a = P[m][n] * 255.;
        if( a < 0)                  //amplituda ujemna - kolor niebieski
            PaintBox1 -> Canvas -> Pixels[i][j] = RGB(0,0,-a);
        else                        //dodatnia - czerwony
            PaintBox1 -> Canvas -> Pixels[i][j] = RGB(a,0,0);
    }
 }
}
//---------------------------------------------------------------------------
//  Wyświetlenie filtra
void __fastcall TForm1::PaintBox2Paint(TObject *Sender)
{
 int i, j, m, n, a;
 TSkalowanie s( 0, PaintBox2 -> Height, PaintBox2 -> Width, -PaintBox2 -> Height,
                IL_PODZ/2, IL_PODZ/2, IL_PODZ, IL_PODZ);
 for( i = 0; i < PaintBox2 -> Width; i ++)
 {
    m = s.daj_real_x( i);
    for( j = 0; j < PaintBox2 -> Height; j ++)
    {
        n = s.daj_real_y( j);
        a = F[m][n] * 255.;
        PaintBox2 -> Canvas -> Pixels[i][j] = RGB(a,a,a);
    }
 }
}
//---------------------------------------------------------------------------
//  Wyświetlenie ekranu w kolorze zgodnym z dłg. fali światła
void __fastcall TForm1::PaintBox3Paint(TObject *Sender)
{
 int i, j, m, n, a;
 TWidmo w;
 TSkalowanie s( 0, PaintBox3 -> Height, PaintBox3 -> Width, -PaintBox3 -> Height,
                IL_PODZ/2, IL_PODZ/2, IL_PODZ, IL_PODZ);
 for( i = 0; i < PaintBox3 -> Width; i ++)
 {
    m = s.daj_real_x( i);
    for( j = 0; j < PaintBox3 -> Height; j ++)
    {
        n = s.daj_real_y( j);
        a = E[m][n]*E[m][n]*100;   //oświetlenie to kwadrat amplitudy
        PaintBox3->Canvas->Pixels[i][j] = w.lambda_to_kolor( a, L);
    }
 }
}
//---------------------------------------------------------------------------

