[Delphi] POMOCY...

0

POTRZEBUJE PILNIE POMOCY.MAM DO NAPISANIA PROGRAM W DELPHI:
Przedstaw metodę i napisz program ilustrujący (animacją) obroty w R3. :-(
CZY MÓGŁBY MI KTOŚ POMÓC,PLISSSSS

0

Po pierwsze: następnym razem napisz temat coś mówiący (np. Obrót w przestrzeni).

A teraz fragmentaryczna pomoc.
Jeżeli mamy obrócić obiekt w przestrzeni to obrót może nam wyznaczyć macierz:
Ox' Oy' Oz'
Ox |l1 l2 l3|
Oy |m1 m2 m3|
Oz |n1 n2 n3|

Gdzie l1 to kosinusy kierunkowe nowych osi ukł. współrzędnych (czyli Ox', Oy' i Oz')

Jeżeli mamy już taką tablicę to funkcja obracjąca dany punkt wygląda tak:

type
TTablica = array ['X'..'Z', 'X'..'Z'] of Extended;
TPunkt = record
X, Y, Z: Extended;
end;
function Obrot(Punkt: TPunkt; Katy: TTablica): TPunkt;
begin
with Punkt do
begin
Result.X := Katy['X', 'X']*X+Katy['Y', 'X']*Y+Katy['Z', 'X']*Z;
Result.Y := Katy['X', 'Y']*X+Katy['Y', 'Y']*Y+Katy['Z', 'Y']*Z;
Result.Z := Katy['X', 'Z']*X+Katy['Y', 'Z']*Y+Katy['Z', 'Z']*Z;
end;
end;

Teraz zostało nam wyznaczyć te kosinusy kierunkowe (teoretycznie można kazać użytkownikowi podawać od razu kosinusy kierunkowe, ale to nieprofesjonalne). Wystarczy, że użytkownik poda nam tzw. kąty Eulera:

  1. Kąt nutacji: Pomiędzy dodanimi półosiami Ox i Ox' [Nut]
  2. Kąt precesji: Pomiędzy dodatnią półosią Ox i prostą OA wyznaczoną przez przesunięcie płaszczyzn Oxy i Ox'y' (przy czym kierunek OA dobieraz się tak, że OA, Oz i Oz' ma taki sam układ jak Ox, Oy, Oz. Czyli jedno i drugie prawoskrętne). To tak trochę skompilikowanie brzmi, ale jak się to rozrysuje to wszystko widać jak na dłoni. [Prec]
  3. Kąt właściwego obrotu: Pomiędzy OA i Ox'. [Obr]

A teraz wzorki.
Kosinusy kierunkowe wyliczy nam funkcja:
function KatEuler(Nut, Prec, Obr: Extended): TTablica;
var
c1, c2, c3, s1, s2, s3: Extended;
begin
c1 := cos(Nut);
c2 := cos(Prec);
c3 := cos(Obr);
s1 := sin(Nut);
s2 := sin(Prec);
s3 := sin(Obr);
Result['X', 'X'] := c2c3-c1s2s3;
Result['X', 'Y'] := -c2
c3-c1s2s3;
Result['X', 'Z'] := s1s2;
Result['Y', 'X'] := s2
c3+c1c2s3;
Result['Y', 'Y'] := -s2s3-c1c2c3;
Result['Y', 'Z'] := -s1
c2;
Result['Z', 'X'] := s1s3;
Result['Z', 'Y'] := s1
s3;
Result['Z', 'Z'] := c1;
end;

Teraz wystarczy dorzucić funkcję rysującą to oraz interface użytkownika.

0

Mam za miękkie serce :-D

Funkcja przekształcająca 3D w 2D (bardzo prosta. Wymaga jeszcze "kalibracji")
function XYZtoUV(Punkt: TPunkt): TPoint;
const
d = $FF; //Odległość użytkownika od ekranu :) Trzeba dopasować
begin
with Punkt do
begin
Result.X := Trunc(Xd/(Z+d));
Result.Y := Trunc(Y
d/(Z+d));
end;
end;

Funkcja rysująca prostą. Można też inne figury przestrzenne. To tylko przykład.

var
P1, P2: TPunkt;
k1, k2, k3: Extended;
Tab: TTablica;
P: TPoint;
begin
P1.X := StrToFloat(P1X.Text);//Edit zawierający współrzędną X pierwszego punktu
P1.Y := StrToFloat(P1Y.Text);
P1.Z := StrToFloat(P1Z.Text);
P2.X := StrToFloat(P2X.Text);//Edit zawierający współrzędną X drugiego punktu
P2.Y := StrToFloat(P2Y.Text);
P2.Z := StrToFloat(P2Z.Text);
k1 := StrToFloat(KNut.Text)*Pi/180;//Edit zawierający kąt nutacji
k2 := StrToFloat(KPrec.Text)*Pi/180;
k3 := StrToFloat(KObr.Text)*Pi/180;
Tab := KatEuler(k1, k2, k3);
P := XYZtoUV(Obrot(P1, Tab));
Canvas.MoveTo(200+P.X, 200+P.Y);
P := XYZtoUV(Obrot(P2, Tab));
Canvas.LineTo(200+P.X, 200+P.Y);
end;

Dodam tylko, że z DirectX i OpenGL pewnie byłoby łatwiej...

1 użytkowników online, w tym zalogowanych: 0, gości: 1