Регистрация: 29.11.2010
Сообщений: 4
|
Паскаль, графика. Вращение октаэдра вокруг осей координат.
Написал программу, работает, но не так, как нужно. Вместо октаэдра получилось нечто.
Октаэдр задаётся координатами центра (cx,cy), расстоянием от центра до вершин (r) и тремя углами (x,y,z), определяющими отклонение в радианах относительно начального положения по каждой из трёх осей. В программе, очевидно, что-то неправильно с тригонометрией, а именно, с переводом этих трёх углов в координаты точек на экране (фрагмент кода, выделенный красным).
Управление написано в комментариях в main program.
Код:
uses
crt,graph;
type
octahedron = object
{x,y,z - углы, определяющие положение октаэдра относительно начального;
r - расстояние от центра октаэдра до вершин;
cx,cy - координаты центра октаэдра;
build - вычислить координаты x,y 6-ти вершин октаэдра
и построить 12 рёбер, соединяющих вершины
clear - установить чёрный цвет, затем build;
show - установить белый цвет, затем build;
ox,oy,oz - повернуть октаэдр вокруг соответствующей оси
на угол, заданный в радианах;
zoom - масштабирование октаэдра путём изменения r;
movex,movey - перемещение октаэдра путём изменения cx и cy соответственно.}
x,y,z,r,x1,y1,z1,r1: real;
cx,cy,cx1,cy1: integer;
procedure build(var xx,yy,zz,rr: real; var cxx,cyy: integer);
procedure clear(var xx,yy,zz,rr: real; var cxx,cyy: integer);
procedure show(var xx,yy,zz,rr: real; var cxx,cyy: integer);
procedure ox(dx: real);
procedure oy(dy: real);
procedure oz(dz: real);
procedure zoom(dr: real);
procedure movex(dx: integer);
procedure movey(dy: integer);
end;
var
o: octahedron;
c: char; {Переменная для считывания нажатой клавиши.}
{Для удобства создаётся отдельная процедура инициализации графики.}
procedure initgraph1;
var
gd,gm: integer;
dr: string;
begin
gd:=VGA;
gm:=2; {640x480}
dr:='C:\BP\BGI';
initgraph(gd,gm,dr);
end;
procedure octahedron.build(var xx,yy,zz,rr: real; var cxx,cyy: integer);
var
oct: array [1..6,1..2] of integer; {Координаты x,y 6-ти вершин октаэдра.}
i: integer; {Счётчик цикла.}
{Проблема в этом куске кода}
{Вычисление координат x,y 6-ти вершин октаэдра.}
{В начальном положении:
1 - верхняя точка;
2 - нижняя;
3 - правая;
4 - левая;
5 - передняя;
6 - задняя.}
procedure calculate;
begin
oct[1,1]:=cxx+round(sin(zz)*sin(yy)*rr);
oct[1,2]:=cyy-round(cos(zz)*cos(xx)*rr);
oct[2,1]:=-oct[1,1]+cxx*2;
oct[2,2]:=-oct[1,2]+cyy*2;
oct[3,1]:=cxx+round(cos(zz)*cos(yy)*rr);
oct[3,2]:=cyy+round(sin(zz)*cos(xx)*rr);
oct[4,1]:=-oct[3,1]+cxx*2;
oct[4,2]:=-oct[3,2]+cyy*2;
oct[5,1]:=cxx+round(cos(zz)*sin(yy)*rr);
oct[5,2]:=cyy+round(sin(zz)*sin(xx)*rr);
oct[6,1]:=-oct[5,1]+cxx*2;
oct[6,2]:=-oct[5,2]+cyy*2;
end;
{Процедура построения линии между двумя вершинами октаэдра.}
procedure linemn(m,n: integer);
begin
line(oct[m,1],oct[m,2],oct[n,1],oct[n,2]);
end;
begin
calculate;
{Построение 12-ти рёбер октаэдра.}
for i:=3 to 6 do
begin
linemn(1,i);
linemn(2,i);
end;
linemn(5,3);
linemn(3,6);
linemn(6,4);
linemn(4,5);
end;
procedure octahedron.clear(var xx,yy,zz,rr: real; var cxx,cyy: integer);
begin
setcolor(0);
build(xx,yy,zz,rr,cxx,cyy);
end;
procedure octahedron.show(var xx,yy,zz,rr: real; var cxx,cyy: integer);
begin
setcolor(15);
build(xx,yy,zz,rr,cxx,cyy);
end;
procedure octahedron.ox(dx: real);
begin
c:=#0; {Обнуляем значение нажатой клавиши.}
x1:=x; {Запоминаем предыдущее значение переменной x.}
x:=x+dx; {Присваиваем переменной x новое значение.}
clear(x1,y,z,r,cx,cy); {Убираем с экрана октаэдр со старым значением переменной x.}
show(x,y,z,r,cx,cy); {Выводим на экран октаэдр с новым значением переменной x.}
end;
procedure octahedron.oy(dy: real); {Структура процедуры аналогична предыдущей.}
begin
c:=#0;
y1:=y;
y:=y+dy;
clear(x,y1,z,r,cx,cy);
show(x,y,z,r,cx,cy);
end;
procedure octahedron.oz(dz: real); {Структура процедуры аналогична предыдущей.}
begin
c:=#0;
z1:=z;
z:=z+dz;
clear(x,y,z1,r,cx,cy);
show(x,y,z,r,cx,cy);
end;
procedure octahedron.zoom(dr: real); {Структура процедуры аналогична предыдущей.}
begin
c:=#0;
r1:=r;
r:=r+dr;
clear(x,y,z,r1,cx,cy);
show(x,y,z,r,cx,cy);
end;
(Продолжение кода в следующем сообщении)
Последний раз редактировалось San-ch; 28.02.2011 в 04:52.
|