Rzutowanie 3D problem z implementacją

0

Witam.
Otóż potrzebuję napisać program w pascalu, w którym będzie można zobaczyć obracającą się trójwymiarową figurę. Zacząłem od odcinka, jednak wystąpił problem i zamiast końce odcinka ładnie poruszać się po powierzchni kuli, zmieniają one swe położenie znacznie względem ekranu.

 
program odcinek;

uses
  crt,graph;

type
  point = record
    x,y,z:integer;
    end;

var
  tryb,ster,r,speed,d: integer;
  anglex,angley,anglez:real;
  a,b,c,s,e:point;





{########## f. trygonometryczne katow w stopniach ##########}

function sinus(x:real):real;
  begin
    x:=(x*pi/180);
    sinus:=sin(x);
  end;

function cosin(x:real):real;
  begin
    x:=(x*pi/180);
    cosin:=cos(x);
  end;

{########## Obrot punktu 'a' wzgledem punktu 'o' wokol osi 'l' o kat 'alfa' ##########}

procedure twist(a,o:point;l:char;alfa:real; var p:point);
  begin
    l:=upcase(l);
    case l of
      'X' :
        begin
          p.x:=a.x;
          p.y:=round(o.y + (a.y - o.y)*cosin(alfa) - (a.z - o.z)*sinus(alfa));
          p.z:=round(o.z + (a.y - o.y)*sinus(alfa) + (a.z - o.z)*cosin(alfa));
        end;
      'Y' :
        begin
          p.x:=round(o.x + (a.z - o.z)*sinus(alfa) + (a.x - o.x)*cosin(alfa));
          p.y:=a.y;
          p.z:=round(o.z + (a.z - o.z)*cosin(alfa) - (a.x - o.x)*sinus(alfa));
        end;
      'Z' :
        begin
          p.x:=round(o.x + (a.x - o.x)*cosin(alfa) - (a.y - o.y)*sinus(alfa));
          p.y:=round(o.y + (a.x - o.x)*sinus(alfa) + (a.y - o.y)*cosin(alfa));
          p.z:=a.z;
        end;
    end;
  end;





begin
  clrscr;
  detectgraph(ster,tryb);
  initgraph(ster,tryb,'c:\bgi');

  s.x:=getmaxx div 2;
  s.y:=getmaxy div 2;
  s.z:=0;
  r:=100;

  anglez:=2.5;
  anglex:=1.3;
  angley:=0.8;
  speed:=50;
  d:=500;

  a.x:=s.x;
  a.y:=s.y - r;
  a.z:=s.z;

  b.x:=s.x;
  b.y:=s.y + r;
  b.z:=s.z;

  repeat
    {wydaje mi sie ze wlasnie w tym miejscu jest blad}
    c.x:=round(a.x*d/(a.z+d)) + (getmaxx div 2);
    c.y:=round(a.y*d/(a.z+d)) + (getmaxy div 2);
    e.x:=round(b.x*d/(b.z+d)) + (getmaxx div 2);
    e.y:=round(b.y*d/(b.z+d)) + (getmaxy div 2);
    line(c.x,c.y,e.x,e.y);

    twist(a,s,'Z',anglez,a);
    twist(a,s,'X',anglex,a);
    twist(a,s,'Y',angley,a);

    twist(b,s,'Z',anglez,b);
    twist(b,s,'X',anglex,b);
    twist(b,s,'Y',angley,b);

    delay(speed);
    cleardevice;
  until keypressed;

  closegraph;
end.

Korzystałem z rownań przekształcających punkt w postaci xyz do xy:
x'= xd/(z+d) + dx
y'= y
d/(z+d) + dy

gdzie:
x, y, z : współrzędne punktu w 3D
x', y' : współrzędne punktu w 2D
d : odległość obserwatora od obiektu
dx, dy : współrzędne środka ekranu graficznego

I wydaje mi się że właśnie w tym równaniu jest błąd.

0

korzystam z kompilatora TurboPascal 7.0

0
  1. zamiast robić takie funkcje sinus(), przelicz kąt alfa raz na radiany i potem używaj normalnych sin/cos.
  2. zanim się porwiesz na 3D, spróbuj najpierw z obrotem 2D.
0

Już próbowałem obrotu w 2D i wszystko wychodziło ładnie. A to że zmienię wywoływanie funkcji trygonometrycznych mi nie pomoże w rozwiązaniu problemu.

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