Перейти к содержимому

RAWMIND

RAWMIND

Регистрация: 09.11.2007, 10:46
Offline Активность: 03.07.2009, 12:20
-----

Куб

21.07.2008, 22:39:09

Простая задачка. :eek: , но вкурить не получается :D

Задача: разработать программу, которая рисует вращающийся куб с разноцветными гранями в проекции Кавалье.
нерешенная проблема: определить, какие грани видимы (т.е. находятся на переднем плане проекции)

что есть: вращающийся куб без закрашивания граней (видны только линии пересечения этих граней).

Нужен алгоритм (или прога на любом языке).

Код на паскале вращающегося куба с видимыми линиями:
uses crt,graph;
const
  S=80; { размер стороны}
  ntck=8; { количество точек}
  nlin=6; { количество граней}
  EYEY=300;	 { расстояние до глаза}
  EYEL=200;	 { расстояние до экрана  }

type
  figura=record
{ Точки }
	tck:array [1..ntck] of record
	  x3,y3,z3:real;	{ Координаты 3D }
	  x2,y2:integer;	{ Координаты 2D }
	end;
{ Грани }
	lin:array [1..nlin] of record
	  a,b,c,d:integer;  { номера точек из tck }
	  cl:integer;	   { цвет }
	end;
  end;
  matr=array [1..4,1..4] of real;	   { тип «матрица»для преобразований }

{ выводим фигуру на экран }
procedure output(var f:figura);
var n:integer;
  t:array [1..5] of pointtype;
  cenX, cenY: integer;
begin
  cenX:= GetMaxX div 2;
  cenY:= GetMaxY div 2;
  SetLineStyle( 2, 0, 1);
  
  for n:=1 to ntck do with f.tck[n] do begin
{ приводим 3D к 2D }
	x2:=trunc(x3*EYEL/(z3-EYEY));
	y2:=trunc(y3*EYEL/(z3-EYEY));
  end;
{ просто закрашиваем старый экран }
  SetFillStyle(SolidFill, black);
  bar( 0,0, GetMaxX, GetMaxY);

  with f do for n:=1 to nlin do begin
	setfillstyle(1,lin[n].cl);
	t[1].x:=cenX+tck[lin[n].a].x2; t[1].y:=cenY-tck[lin[n].a].y2;
	t[2].x:=cenX+tck[lin[n].b].x2; t[2].y:=cenY-tck[lin[n].b].y2;
	t[3].x:=cenX+tck[lin[n].c].x2; t[3].y:=cenY-tck[lin[n].c].y2;
	t[4].x:=cenX+tck[lin[n].d].x2; t[4].y:=cenY-tck[lin[n].d].y2;
	t[5]:=t[1];

	SetColor(lin[n].cl);
	DrawPoly( 5, t);
  end;
end;

{преобразование фигуры в каждом цикле}
procedure prc(var f:figura;m:matr);
var
  nx,ny,nz:real;
  n:integer;
begin
{ просто умножаем каждую точку на матрицу, описываем изменения }
  for n:=1 to ntck do with f.tck[n] do begin
	nx:=m[1,1]*x3+m[1,2]*y3+m[1,3]*z3+m[1,4];
	ny:=m[2,1]*x3+m[2,2]*y3+m[2,3]*z3+m[2,4];
	nz:=m[3,1]*x3+m[3,2]*y3+m[3,3]*z3+m[3,4];
	x3:=nx;y3:=ny;z3:=nz;
  end;
end;

{ процедуры работы с матрицами }

{ создание матрицы смещения}
procedure one(var mm:matr);
var n,m:integer;
begin
  for n:=1 to 4 do for m:=1 to 4 do
	if (n<>m) then mm[n,m]:=0 else mm[n,m]:=1;
end;

{ создаем матрицы вращения любой оси координат }
procedure rot3(var m:matr;a:real;n:integer);
var
  ax1,ax2:integer;
begin
  one(m);
  ax1:=n+1;if ax1=4 then ax1:=1;
  ax2:=ax1+1;if ax2=4 then ax2:=1;
  m[ax1,ax1]:=cos(a);
  m[ax1,ax2]:=-sin(a);
  m[ax2,ax1]:=sin(a);
  m[ax2,ax2]:=cos(a);
end;

{ переменные программы }
var
  drv,mode:integer;	{для Initgraph }
  c:char;			  { считынный с клавиатуры }
  fg:figura;		   { данные фигуры }
  rt:matr;			 { матрица преобразования (вращения) }

begin
  drv:=DETECT;
  mode:=VGAHI;
  initgraph(drv,mode,'..\bgi');
  if (GraphResult=grOk) then begin
{ создаем фигуру }
  with fg do begin
{ создаем точки }
	tck[1].x3:=-S; tck[1].y3:=-S; tck[1].z3:=-S;
	tck[2].x3:=-S; tck[2].y3:=S; tck[2].z3:=-S;
	tck[3].x3:=S; tck[3].y3:=S; tck[3].z3:=-S;
	tck[4].x3:=S; tck[4].y3:=-S; tck[4].z3:=-S;
	tck[5].x3:=-S; tck[5].y3:=-S; tck[5].z3:=S;
	tck[6].x3:=-S; tck[6].y3:=S; tck[6].z3:=S;
	tck[7].x3:=S; tck[7].y3:=S; tck[7].z3:=S;
	tck[8].x3:=S; tck[8].y3:=-S; tck[8].z3:=S;
{ создаем плоскости и цвет }
	with lin[1] do begin a:=1;b:=2;c:=3;d:=4; cl:=red;end;
	with lin[2] do begin a:=1;b:=2;c:=6;d:=5; cl:=yellow;end;
	with lin[3] do begin a:=5;b:=6;c:=7;d:=8; cl:=green;end;
	with lin[4] do begin a:=8;b:=7;c:=3;d:=4; cl:=blue;end;
	with lin[5] do begin a:=1;b:=5;c:=8;d:=4; cl:=white;end;
	with lin[6] do begin a:=2;b:=6;c:=7;d:=3; cl:=magenta;end;

  end;
{ Поворачиваем фигуру, чтобы стояла не вертикально }
  rot3(rt,0.4,1);
  prc(fg,rt);
{ создаем матрицу для вращения вокруг оси Y }
	rot3(rt,0.01,2);
{ предварительно вычисляем плоские координаты}
	repeat
{ ‚выводим картинку }
	  output(fg);
	  delay(2000);	  {ждем некоторое время }
	  prc(fg,rt);	 { Преобразовываем (вращаем) }
	  if (keypressed) then begin
		c:=readkey;
	  end else c:=' ';
	until c=#27;
	closegraph;
  end else begin
	writeln;
	writeln(' Cannot initialize GRAPH');
  end;
end.


Пожалста, понимаю, что решение где-то на поверхности, но не могу понять...

вывод в конце процедуры output:

SetColor(lin[n].cl);
DrawPoly( 5, t);

Размещение рекламы на сайте     Предложения о сотрудничестве     Служба поддержки пользователей

© 2011-2022 vse.kz. При любом использовании материалов Форума ссылка на vse.kz обязательна.