Новичок
Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.12.2005
Репутация: нет Всего: нет
|
Я пишу программу, которая вращает точки с 3d координатами вокруг 3 осей ( на кнопочки вверх, вправо , влево ) Я немного запутался ( он вращает в определенном направление нормально, при его изменение точки глючат, думаю из-за того что arctan возвращает значения только от -pi/2 до pi/2 ) вообщем если есть лучше способ, чем я наворотил (он не доделан, но все же... ) или если есть ошибки прошу написать. (при нажатие вниз она восстанавливает картинку) Модератор: Содержимое файла| Код | {$r+} program p3d_task; uses graph,crt; const amount=8; type maas= array[0..30,0..3,0..1] of integer; malpha=array[0..amount] of real; pT3d=^T3d; T3d=object {Public members} constructor init; procedure points(amnt,x,y,z:integer); {amtn=number of the point; x,y,z=position} procedure shift(n:byte;var dx,dy,dz:integer); {n=direction; dx,dy,dz=augment} procedure turn(var n:byte;var dalpha,dphi,domega:real); {n=direction; delta angle} procedure draw(n:byte); {It draws the 3d object, n = draw type} procedure recalc(amnt:integer);{This one recalc all angles, only 4 seldom usage!!!} destructor exit; {/Public members} private {Private members} dp_own:^maas; {main massiv, points are fixed} dp_dyn:^maas; {massiv 4 drawng points, program change it, calculating new coordinates} alpha:malpha; {angles, - ugly s osyami kkordinat, (center of you monitor)} phi:malpha; omega:malpha; {/Private members} end;
constructor T3d.init; begin new(dp_own); new(dp_dyn); end;
destructor T3d.exit; begin dispose(dp_own); dispose(dp_dyn); end;
procedure T3d.recalc(amnt:integer); {it MUST calculate angles in a proper way, but i think it should be done in another way} begin if dp_dyn^[amnt,1,0]<>0 then if(dp_dyn^[amnt,1,0]<0) then alpha[amnt]:=-arctan(dp_dyn^[amnt,0,0]/dp_dyn^[amnt,1,0]) else alpha[amnt]:=arctan(dp_dyn^[amnt,0,0]/dp_dyn^[amnt,1,0]) else alpha[amnt]:=pi/2;
if dp_dyn^[amnt,2,0]<>0 then if(dp_dyn^[amnt,2,0]<0) then phi[amnt]:=-arctan(dp_dyn^[amnt,0,0]/dp_dyn^[amnt,2,0]) else phi[amnt]:=arctan(dp_dyn^[amnt,0,0]/dp_dyn^[amnt,2,0]) else phi[amnt]:=pi/2;
if dp_dyn^[amnt,2,0]<>0 then if(dp_dyn^[amnt,2,0]<0) then omega[amnt]:=-arctan(dp_dyn^[amnt,1,0]/dp_dyn^[amnt,2,0]) else omega[amnt]:=arctan(dp_dyn^[amnt,1,0]/dp_dyn^[amnt,2,0]) else omega[amnt]:=pi/2;
end;
procedure T3d.points(amnt,x,y,z:integer); {procedure 4 adding points to massive} var i:integer; begin dp_own^[amnt,0,0]:=x; dp_own^[amnt,1,0]:=y; dp_own^[amnt,2,0]:=z; dp_dyn^[amnt,0,0]:=x; dp_dyn^[amnt,1,0]:=y; dp_dyn^[amnt,2,0]:=z; {recalc(amnt);} end;
procedure T3d.shift(n:byte;var dx,dy,dz:integer); {not realised, you can pay no attention to it} var i:integer; begin for i:=1 to amount do begin dp_dyn^[i,0,0]:=dp_own^[i,0,0]+dx; dp_dyn^[i,1,0]:=dp_own^[i,1,0]+dy; dp_dyn^[i,2,0]:=dp_own^[i,1,0]+dz; end; end; {This one turn our points, n: 1- alpha, 2-phi, 3-omega, n- only for debugging} procedure T3d.turn(var n:byte;var dalpha,dphi,domega:real); var i:integer; r:double; out:string;
begin case n of 1: begin for i:=1 to amount do begin r:=sqrt(dp_own^[i,0,0]*dp_own^[i,0,0]+dp_own^[i,1,0]*dp_own^[i,1,0]); alpha[i]:=alpha[i]+dalpha; dp_dyn^[i,0,0]:=round(r*sin(alpha[i])); dp_dyn^[i,1,0]:=round(r*cos(alpha[i])); end; end; 2: begin for i:=1 to amount do begin phi[i]:=phi[i]+dphi; r:=sqrt(dp_own^[i,0,0]*dp_own^[i,0,0]+dp_own^[i,2,0]*dp_own^[i,2,0]); dp_dyn^[i,0,0]:=round(r*sin(phi[i])); dp_dyn^[i,2,0]:=round(r*cos(phi[i])); end; end; 3: begin for i:=1 to amount do begin omega[i]:=omega[i]+domega; r:=sqrt(dp_own^[i,1,0]*dp_own^[i,1,0]+dp_own^[i,2,0]*dp_own^[i,2,0]); dp_dyn^[i,1,0]:=round(r*sin(omega[i])); dp_dyn^[i,2,0]:=round(r*cos(omega[i])); end; end; end; end; {it draws our points} {pay atention on setactivepage(visual) is it should work?} procedure T3d.draw(n:byte); var i,midx,midy:integer; begin cleardevice; setactivepage(1); midx:=round(getmaxx/2); midy:=round(getmaxy/2); for i:=1 to amount do begin putpixel(dp_dyn^[i,0,0]+midx,dp_dyn^[i,1,0]+midy,white); end; setvisualpage(1); end;
{Main Procedure} var a,b,key,keytmp:integer; ang:real; n:byte; stri:string; threed:pT3d; begin initgraph(a,b,''); new(threed,Init); {threed^.points(1,10,10,10); threed^.points(2,20,20,20); threed^.points(3,30,30,30); threed^.points(4,50,50,50); threed^.points(5,0,0,0); threed^.points(6,70,70,70); threed^.points(7,100,100,100); threed^.points(8,5,5,5);} threed^.points(1,60,10,10); threed^.points(2,10,60,10); threed^.points(3,10,10,60); threed^.points(4,60,60,60); threed^.points(5,10,10,10); threed^.points(6,60,60,10); threed^.points(7,10,60,60); threed^.points(8,60,10,60);
ang:=0.001; n:=1; threed^.draw(1); repeat key:=ord(readkey); if key<>0 then begin {++++++}
if key<>keytmp then begin for n:=1 to amount do begin threed^.recalc(n); sound(500); delay(1000); nosound; end; end;
keytmp:=key;
case key of 72: begin repeat n:=1; threed^.turn(n,ang,ang,ang); threed^.draw(n); until keypressed; end; 75: begin repeat n:=2; threed^.turn(n,ang,ang,ang); threed^.draw(n); until keypressed; end; 77: begin repeat n:=3; threed^.turn(n,ang,ang,ang); threed^.draw(n); until keypressed; end; 80: begin threed^.points(1,60,10,10); threed^.points(2,10,60,10); threed^.points(3,10,10,60); threed^.points(4,60,60,60); threed^.points(5,10,10,10); threed^.points(6,60,60,10); threed^.points(7,10,60,60); threed^.points(8,60,10,60); end; end; end; {------------------} until key=27; closegraph; dispose(threed,Exit); end. {==End==}
|
Это сообщение отредактировал(а) Fixin - 17.2.2006, 23:53
Присоединённый файл ( Кол-во скачиваний: 5 )
T3D.PAS 5,71 Kb
|