Задача:написать программу для изображения многогранника, вращающегося вокруг оси оу. ось вращения не должна совпадать с собственной вертикальной осью фигуры.
октаэдр
проекция:перспектива (1 точки схода)
при выполнении этого задания необходимо реализовывать алгоритм удаления невидимых линий. все грани рисовать закрашеными различными цветами.
Октаэдр вращается полкруга нормально,а затем нижняя его часть пропадает,верхняя же вращается как не бывало…кто имеет опыт программирования в этой области,посмотрите,пожалуйста код:
program octahedron;
uses crt,graph;
type point_position = array [1..3] of real;
type side_position = array [1..3] of point_position;
type oct_coord = array [1..8] of side_position;
const Color: array[1..8] of Integer = (1,2,3,4,5,6,9,10);
{фигура Октаэдр}
const oct: oct_coord= (((100,100,60),(50,100,-40),(100,50,-40)),
((100,100,60),(50,100,-40),(100,150,-40)),
((100,100,-140),(100,50,-40),(50,100,-40)),
((100,100,-140),(100,150,-40),(50,100,-40)),
((100,100,-140),(150,100,-40),(100,50,-40)),
((100,100,-140),(100,150,-40),(150,100,-40)),
((100,100,60),(100,50,-40),(150,100,-40)),
((100,100,60),(150,100,-40),(100,150,-40)));
const p=-0.002;
var
pcos,psin:real;
oct_new,oct_old:oct_coord;
dv,mv,x0, y0: integer;
procedure init;
var i,j,k:integer;
begin
x0 := getMaxX div 2;
y0 := getMaxY div 2;
for i:=1 to High(oct) do
for j:=1 to High(oct[i]) do
for k:=1 to High(oct[i,j]) do
begin
oct_new[i,j,k] := oct[i,j,k];
oct_old[i,j,k] := oct[i,j,k];
end;
end;
{алгоритм робертса}
function robert(side:side_position):boolean;
var
a,b,c:real;
i,j:integer;
begin
c:=0;
robert:=true;
for i:=1 to high(side) do
begin
if i=high(side) then j:=1
else j:=i+1;
c:=c+(side[i,1]-side[j,1])*(side[i,2]+side[j,2]);
end;
if c<=0 then robert:=false;
end;
{процедура получения перспективы в одной точке схода}
procedure modif(x,y,z:real;var x1,y1,z1:real);
begin
x1:=x/(p*y+1);
y1:=y/(p*y+1);
z1:=z/(p*y+1);
end;
{прорисовка/стирание октаэдра в зависимости от флага new}
procedure draw_oct(new: boolean;figure:oct_coord);
var
i,j,k:integer;
area: array [1..3] of PointType;
new_side:side_position;
begin
setcolor(0);
for i:=1 to high(oct_new) do
begin
for k:=1 to high(new_side) do
begin
modif(figure[i,k,1], figure[i,k,2], figure[i,k,3],
new_side[k,1],new_side[k,2],new_side[k,3]);
end;
if robert(new_side) then
begin
if new then
begin
setFillStyle(solidfill, Color[i]);
end
else begin
setFillStyle(solidfill, 0);
end;
for j:=1 to High(new_side) do
begin
area[j].X :=x0+ round(new_side[j,1]);
area[j].Y := round(new_side[j,2]);
end;
fillpoly(sizeOf(area) div sizeOf(pointtype),area);
end;
end;
end;
{поворот октаэдра}
procedure rotate;
var
i, j: integer;
x_new, z_new: real;
begin
for i:=1 to High(oct_new) do
for j:=1 to High(oct_new[1]) do
begin
oct_old[i,j,1] := oct_new[i,j,1];
oct_old[i,j,3] := oct_new[i,j,3];
x_new:=oct_new[i,j,1]*pcos-oct_new[i,j,3]*psin;
z_new:=oct_new[i,j,1]*psin+oct_new[i,j,3]*pcos;
oct_new[i,j,1]:=x_new;
oct_new[i,j,3]:=z_new;
end;
end;
{основная часть программы}
begin
pcos:=cos(0.05);
psin:=sin(0.05);
dv := detect;
initGraph(dv,mv,'');
init;
repeat
rotate;
draw_oct(false,oct_old);
draw_oct(true,oct_new);
delay(10000);
until keypressed;
closegraph;
end.
5 августа 2009 в 17:04
нет) это как раз таки не проще) специальная тематика есть прорисовки этих неведимых линий
следить за кол-вом рекурсий тоже не вариант, уже очень часто они вызываются) надо вообще от них избавлятся
5 августа 2009 в 9:04
Слышь, а че там про октаэдр за проблема? методы какие-то… разве не проще контролировать как ориентированы нормали к граням по отношению к наблюдателю, если видно грань, то тупо рисовать ее, если нет – то нет. Фигура выпуклая, значит видимые грани не будут накладываться
5 августа 2009 в 9:03
У тебя рекурсия без контроля кол-ва вложений(((((
разве нельзя заменить
If Diz(x,y) = 2 then diz := 0;
на
If (x+y) = 2 then diz := 0;
30 июля 2009 в 19:04
рекурсию слишком много раз запускаешь, поэтому происходит переполнение стека попробуй напиши вначале
{$R-, S-}
и посмотри что будет, если всё равно ошибка, то переделывай алгоритм в нерекурсивный
29 июля 2009 в 20:00
Помогите пожалуйста, нужно написать прогу для вычисления проверочного кода Хемминга. Я вот тут написал, вроде работать должно, но выдаёт ошибку Stack Overflow Error. Можь кто поможет?
Program Xemming;
Uses Crt;
Var
b3,b5,b6,b7,b9,b10,b11,b12,b13,b14,b15,b17,b18,b19,b20,b21 : integer;
x1,x2,x4,x8,x16 : integer;
function Diz(x,y : integer) : integer;
Begin
Diz := x+y;
If Diz(x,y) = 2 then diz := 0;
end;
{$M 4096,0,10000}
Begin
ReadLn(b3,b5,b6,b7,b9,b10,b11,b12,b13,b14,b15,b17,b18,b19,b20,b21);
x1 := diz(b3,b5);
x1 := diz(x1,b7);
x1 := diz(x1,b9);
x1 := diz(x1,b11);
x1 := diz(x1,b13);
x1 := diz(x1,b15);
x1 := diz(x1,b17);
x1 := diz(x1,b19);
x1 := diz(x1,b21);
x2 := diz(b3,b6);
x2 := diz(x2,b7);
x2 := diz(x2,b10);
x2 := diz(x2,b11);
x2 := diz(x2,b14);
x2 := diz(x2,b15);
x2 := diz(x2,b18);
x2 := diz(x2,b19);
x4 := diz(b5,b6);
x4 := diz(x4,b7);
x4 := diz(x4,b12);
x4 := diz(x4,b13);
x4 := diz(x4,b14);
x4 := diz(x4,b15);
x4 := diz(x4,b20);
x4 := diz(x4,b21);
x8 := diz(b9,b10);
x8 := diz(x8,b11);
x8 := diz(x8,b12);
x8 := diz(x8,b13);
x8 := diz(x8,b14);
x8 := diz(x8,b15);
x16 := diz(b17,b18);
x16 := diz(x16,b19);
x16 := diz(x16,b20);
x16 := diz(x16,b21);
Write(x1,x2,b3,x4,b5,b6,b7,x8,b9,b10,b11,b12,b13,b14,b15,x16,b17,b18,b19,b20,b21);
Readkey;
end.
11 июля 2009 в 0:01
спасибо за совет;)
10 июля 2009 в 23:04
вращающийся октаэдр это дело не одного дня, врядли кто будет это делать за Вас. Пробуйте, метод проб и ошибок
10 июля 2009 в 23:04
//cylib.iit.nau.edu.ua/Books/Graph/Study/3d_cou...
вот что могу посоветовать, Алгоритм Робертса, удаление невидимых линий математичиских фигур )