C++ Builder. Programowanie obiektowe. Ćwiczenie 8. 1
______________________________________________________________________
©2004 Jerzy Kluczewski
PROGRAMOWANIE OBIEKTOWE
ĆWICZENIE 8
C++ BUILDER 6.0 PE
•
Grafika afiniczna
•
Tworzenie klasy TSkalowanie
•
Metoda TScalowanie:: daj_real_x
•
Metoda TScalowanie:: daj_real_y
•
Metoda TScalowanie:: daj_ekr_x
•
Metoda TScalowanie:: daj_ekr_y
•
Konstruktor TSkalowanie::TSkalowanie
•
Funkcja random()
2
C++ Builder. Programowanie obiektowe. Ćwiczenie 8.
______________________________________________________________________
______________________________________________________________________
©2004 Jerzy Kluczewski
I.
Wstęp
Wykonamy teraz kolorową paprotkę wykorzystując tak zwane przekształcenie
afiniczne (Przykład zaczerpnięty z książki Andrzeja Stasiewicza „C++ Builder - 20
efektownych programów”). Nasz projekt aplikacji zapiszemy w plikach
rozpoczynających się od nazwy Paproc8. Zmień tytuł formularza Form1 na Paproć
afiniczna, a kolor na clBlack.
II.
Tworzenie nowej klasy
Definicję naszej klasy TSkalowanie utworzymy w oddzielnych plikach źródłowych:
•
SKALA.H
•
SKALA.CPP.
Plik
New
Unit
Plik skala.h
#ifndef skalaH
#define skalaH
// Oto treść pliku skala.h - nagłówka modułu o nazwie skala, mieszczącego obiekt
TSkalowanie.
//
Skalowanie obszaru ekranowego w matematyczny i odwrotnie
//
UWAGA: OBSZARY SĄ RÓZNIE ZDEFINIOWANE!
//
(xe0, ye0) - lewy górny róg obszaru ekranowego,
//
eszer, ewys - szerokość i wysokość obszaru ekranowego
//
//
(xr0, yr0) - środek obszaru rzeczywistego,
//
rszer, rwys - szerokość i wysokość obszaru rzeczywistego
class TSkalowanie
{
private:
double A, B, C, D;
//skaling z real na ekr
double E, F, G, H;
//skaling odwrotny
public:
TSkalowanie( int xe0, int ye0, int eszer, int ewys, double xr0, double yr0, double
rszer, double rwys);
double daj_real_x( int xe);
double daj_real_y( int ye);
int daj_ekr_x( double xr);
int daj_ekr_y( double yr);
};
#endif
C++ Builder. Programowanie obiektowe. Ćwiczenie 8. 3
______________________________________________________________________
©2004 Jerzy Kluczewski
Plik skala.cpp
#include "skala.h"
// Oto treść pliku skala.cpp - implementacji algorytmów obiektu TSkalowanie.
//----------------------------------------------------
//
Konstruktor.
//
(xe0, ye0) - lewy górny róg obszaru ekranowego,
//
eszer, ewys - szerokość i wysokość obszaru ekranowego
//
(xr0, yr0) - środek obszaru rzeczywistego,
//
rszer, rwys - szerokość i wysokość obszaru rzeczywistego
TSkalowanie::TSkalowanie( int xe0, int ye0, int eszer, int ewys, double xr0, double
yr0, double rszer, double rwys)
{
A = (double) eszer / rszer; //z przestrzeni na ekran
B = (double) xe0 - A * (xr0 - rszer / 2.);
C = -(double)ewys / rwys;
D = (double) ye0 - C * (yr0 + rwys / 2.);
E = rszer / (double)eszer;
//z ekranu do przestrzeni
F = xr0 - rszer / 2. - E * (double)xe0;
G = -rwys / (double)ewys;
H = yr0 + rwys / 2. - G * (double)ye0;
}
//----------------------------------------------------
//
Wyliczenie współrzędnej ekranowej xe punktu,
//
gdy znana jest jego współrzędna rzeczywista x.
int TSkalowanie::daj_ekr_x( double x)
{
return (int)(A * x + B);
}
//----------------------------------------------------
//
Wyliczenie współrzędnej ekranowej ye punktu,
//
gdy znana jest jego współrzędna rzeczywista y.
int TSkalowanie::daj_ekr_y( double y)
{
return (int)(C * y + D);
}
//----------------------------------------------------
//
Wyliczenie współrzędnej rzeczywistej x punktu,
//
gdy znana jest jego współrzędna ekranowa xe.
double TSkalowanie::daj_real_x( int xe)
{
return E * xe + F;
}
4
C++ Builder. Programowanie obiektowe. Ćwiczenie 8.
______________________________________________________________________
______________________________________________________________________
©2004 Jerzy Kluczewski
//----------------------------------------------------
//
Wyliczenie współrzędnej rzeczywistej y punktu,
//
gdy znana jest jego współrzędna ekranowa ye.
double TSkalowanie::daj_real_y( int ye)
{
return G * ye + H;
}
//---------------------------------------------------------------------------
III.
Tworzenie obsługi formularza
Plik Paproc8Unit1.cpp
#include <vcl.h>
#pragma hdrstop
#include "Paproc8Unit1.h"
#include "skala.h"
#include "stdlib.h"
//random()
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)
{
}
Zdarzenie OnPaint
Przechodzimy do projektowania zdarzenia OnPaint, a potem do okna kodu funkcji
TForm1::FormPaint :
C++ Builder. Programowanie obiektowe. Ćwiczenie 8. 5
______________________________________________________________________
©2004 Jerzy Kluczewski
Wpisujemy kod funkcji FormPaint.
Funkcja TForm1::FormPaint
void __fastcall TForm1::FormPaint(TObject *Sender)
{
const int max_iter = 100000, max_il_przekszt = 4;
const double
A[] = { 0.0, 0.85, 0.2, -0.15},
B[] = { 0.0, 0.04,-0.26, 0.28},
C[] = { 0.0,-0.04, 0.23, 0.26},
D[] = { 0.16,0.85, 0.22, 0.24},
E[] = { 0.0, 0.0, 0.0, 0.0},
F[] = { 0.0, 1.6, 1.6, 0.44};
int P[] = { 1, 79, 10, 10};
//wagi niesprawiedliwości
TSkalowanie skal( 0, 0, ClientWidth, ClientHeight, 0.1, 5, 5, 11);
int i, nr_przekszt, xe, ye;
double x, y, x1;
TColor kolor[] = {clRed, clLime, clAqua, clFuchsia};
x = 0, y = 0;
//początek iteracji
for( i = 0; i < max_iter; i ++)
{
nr_przekszt = random_niesprawiedliwe( P, max_il_przekszt);
x1 = A[ nr_przekszt] * x + B[ nr_przekszt] * y + E[ nr_przekszt];
y = C[ nr_przekszt] * x + D[ nr_przekszt] * y + F[ nr_przekszt];
x = x1;
xe = skal.daj_ekr_x( x); //przeniesienie na ekran
ye = skal.daj_ekr_y( y);
Canvas -> Pixels[ xe][ ye] = kolor[ nr_przekszt];
}
}
6
C++ Builder. Programowanie obiektowe. Ćwiczenie 8.
______________________________________________________________________
______________________________________________________________________
©2004 Jerzy Kluczewski
Potrzebny nam jeszcze kod funkcji random_niesprawiedliwe:
Funkcja TForm1::random_niesprawiedliwe
int TForm1::random_niesprawiedliwe( int *p, int N)
{
int i, a, suma = 0, suma_wag = 0;
for( i = 0; i < N; i ++)
suma_wag += p[ i];
a = random( suma_wag);
for( i = 0; i < N; i ++)
{
suma += p[ i];
if( a < suma) break;
}
return i;
}
IV.
Uruchomienie naszej aplikacji
Uruchomienie aplikacji
Uruchom aplikację za pomocą polecenia Run
Run (F9)