Здравствуйте!

Подскажите, как переделать программу:::
вращение октаэдра (ось вращения не совпадает с собственной осью фигуры)
а надо на основе этих же процедур преобразования реализовать вращение икосаэдра (20 граней треугольных, 12 вершин и 30 ребер)

текст ниже:

Код

Program Oktaedr1;
Uses crt,graph;
Type
  Oktaedr=record { Данные всех точек октаэдра }
    mass1:array [1..10] of record
      x3d,y3d,z3d:real;    { Координаты в трехмерном пространстве }
      x2,y2:integer;       { Новые координаты на экране }
      xold,yold:integer;   { Для стирания старого изображения }
    end;
{ Данные всех граней октаэдра }
    gran:array [1..10] of record
      a,b,c:integer;    { Номера точек }
      cl:integer;       { Цвет }
    end;
    npixel:integer;      { Реально используемое количество точек}
    plosk:integer;       { Реально используемое количество плоскостей }
  end;
  matr=array [1..4,1..4] of real;    { Тип "матрица" для преобразований (4x4) }


const S=200; { сторона октаэдра }

{-----------------------процедура вывода октаэдра на экран }
procedure otobragenie(var f:oktaedr);
var
  n:integer;
  t:array [1..3] of pointtype;
  o,a1,a2,a3,a4:real;
const
  EYEY=350;     { Расстояние до глаза }
  EYEL=200;     { Расстояние до экрана }
begin
  with f do
    for n:=1 to npixel do with mass1[n] do begin
{ Копируем старые значения }
    xold:=x2;yold:=y2;
{ Вычисляем значения координат с учетом положения }
{ Считаем что ось Y - вертикально, X - горизонтально }
{ Вычисляем координаты на экране }
    x2:=trunc(x3d*EYEL/(z3d-EYEY));
    y2:=trunc(y3d*EYEL/(z3d-EYEY));
  end;
{ Удаляем старые данные }
  setcolor(0);
  setfillstyle(1,0);
  with f do for n:=1 to plosk do begin
{размещаем октаэдр посередине экрана }
    t[1].x:=320+mass1[gran[n].a].xold;t[1].y:=240-mass1[gran[n].a].yold;
    t[2].x:=320+mass1[gran[n].b].xold;t[2].y:=240-mass1[gran[n].b].yold;
    t[3].x:=320+mass1[gran[n].c].xold;t[3].y:=240-mass1[gran[n].c].yold;
    fillpoly(3,t);
  end;
{ Рисуем изображение }
  setcolor(0);
  with f do for n:=1 to plosk do begin
    setfillstyle(1,gran[n].cl);
    t[1].x:=320+mass1[gran[n].a].x2;t[1].y:=240-mass1[gran[n].a].y2;
    t[2].x:=320+mass1[gran[n].b].x2;t[2].y:=240-mass1[gran[n].b].y2;
    t[3].x:=320+mass1[gran[n].c].x2;t[3].y:=240-mass1[gran[n].c].y2;
{ Проверяем направление обхода выводимой плоскости и выводим при правильном }
    a1:=t[2].x-t[1].x;
    a2:=t[3].y-t[2].y;
    a3:=t[3].x-t[2].x;
    a4:=t[2].y-t[1].y;
    o:=a1*a2-a3*a4;
    if (o<0) then
      fillpoly(3,t);
  end;
end;

{ Преобразование фигуры в каждом цикле }
procedure preobraz(var f:oktaedr;m:matr);
var
  nx,ny,nz:real;
  n:integer;
begin
{ Просто умножаем каждую точу на матрицу, описывающую изменения }
  for n:=1 to f.npixel do with f.mass1[n] do begin
    nx:=m[1,1]*x3d+m[1,2]*y3d+m[1,3]*z3d+m[1,4];
    ny:=m[2,1]*x3d+m[2,2]*y3d+m[2,3]*z3d+m[2,4];
    nz:=m[3,1]*x3d+m[3,2]*y3d+m[3,3]*z3d+m[3,4];
    x3d:=nx;y3d:=ny;z3d:=nz;
  end;
end;

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

{ Создание матрицы смещения }
procedure smeshenie(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 rotate(var m:matr;a:real;n:integer);
var
  ax1,ax2:integer;
begin
  smeshenie(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;  
  c:char;              { Символ, считанный с клавиатуры }
  fg:oktaedr;          { Данные октаэдра }
  rt:matr;             { Матрица вращения }

begin
{-----Инициализация графики----------}
  drv:=DETECT;
  mode:=VGAHI;
  initgraph(drv,mode,'');
  if (GraphResult=grOk) then
{Если инициализация прошла успешно, рисуем октаэдр}
begin
  with fg do begin
    npixel:=6;
    plosk:=8;
{ Задаем точки }
    mass1[1].x3d:=S;mass1[1].y3d:=0;mass1[1].z3d:=0;
    mass1[2].x3d:=0;mass1[2].y3d:=S;mass1[2].z3d:=0;
    mass1[3].x3d:=-S;mass1[3].y3d:=0;mass1[3].z3d:=0;
    mass1[4].x3d:=0;mass1[4].y3d:=-S;mass1[4].z3d:=0;
    mass1[5].x3d:=0;mass1[5].y3d:=0;mass1[5].z3d:=S;
    mass1[6].x3d:=0;mass1[6].y3d:=0;mass1[6].z3d:=-S;
{ Задаем грани и их цвет}
    with gran[1] do begin a:=1;b:=2;c:=5;cl:=1;end;
    with gran[2] do begin a:=2;b:=3;c:=5;cl:=7;end;
    with gran[3] do begin a:=3;b:=4;c:=5;cl:=2;end;
    with gran[4] do begin a:=4;b:=1;c:=5;cl:=3;end;
    with gran[5] do begin a:=2;b:=1;c:=6;cl:=4;end;
    with gran[6] do begin a:=3;b:=2;c:=6;cl:=5;end;
    with gran[7] do begin a:=4;b:=3;c:=6;cl:=9;end;
    with gran[8] do begin a:=1;b:=4;c:=6;cl:=8;end;
  end;
{ Поворачиваем фигуру, чтобы стояла не вертикально }
  rotate(rt,0.25,1);
  preobraz(fg,rt);
{ Создаем матрицу для вращения вокруг оси Y }
    rotate(rt,0.13,2);
{ Предварительно вычисляем плоские координаты }
    repeat
{ Выводим картинку }
      otobragenie(fg);
      delay(10000);      { Задержка используется для корректного отображения фигуры на экране }
      preobraz(fg,rt);     {Вращаем октаэдр}
      if (keypressed) then begin
        c:=readkey;
      end else c:=' ';
    until c=#27; {Пока не нажата клавиша ?Esc?}
    closegraph;
  end else begin {Выводим сообщение об ошибке инициализации графики}
    writeln;
    writeln('Error initialize !!!');
  end;
end.