singlepost

Программа вращения закрашенного октаэдранаTurbo Pascal << На главную или назад  

Задача:написать программу для изображения многогранника, вращающегося вокруг оси оу. ось вращения не должна совпадать с собственной вертикальной осью фигуры.
октаэдр
проекция:перспектива (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.

8 ответов в теме “Программа вращения закрашенного октаэдранаTurbo Pascal”

  1. 8
    Вадим Харитонов ответил:

    нет) это как раз таки не проще) специальная тематика есть прорисовки этих неведимых линий

    следить за кол-вом рекурсий тоже не вариант, уже очень часто они вызываются) надо вообще от них избавлятся

  2. 7
    Дмитрий Лазученков ответил:

    Слышь, а че там про октаэдр за проблема? методы какие-то… разве не проще контролировать как ориентированы нормали к граням по отношению к наблюдателю, если видно грань, то тупо рисовать ее, если нет – то нет. Фигура выпуклая, значит видимые грани не будут накладываться

  3. 6
    Дмитрий Лазученков ответил:

    У тебя рекурсия без контроля кол-ва вложений(((((

    разве нельзя заменить
    If Diz(x,y) = 2 then diz := 0;

    на
    If (x+y) = 2 then diz := 0;

  4. 5
    Вадим Харитонов ответил:

    рекурсию слишком много раз запускаешь, поэтому происходит переполнение стека попробуй напиши вначале
    {$R-, S-}
    и посмотри что будет, если всё равно ошибка, то переделывай алгоритм в нерекурсивный :)

  5. 4
    Hrant Sahakyan ответил:

    Помогите пожалуйста, нужно написать прогу для вычисления проверочного кода Хемминга. Я вот тут написал, вроде работать должно, но выдаёт ошибку 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.

  6. 3
    Константин Гайдуков ответил:

    спасибо за совет;)

  7. 2
    Вадим Харитонов ответил:

    вращающийся октаэдр это дело не одного дня, врядли кто будет это делать за Вас. Пробуйте, метод проб и ошибок

  8. 1
    Вадим Харитонов ответил:

    //cylib.iit.nau.edu.ua/Books/Graph/Study/3d_cou...

    вот что могу посоветовать, Алгоритм Робертса, удаление невидимых линий математичиских фигур )

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.