Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

Здравствуйте. Спасибо за проект. У меня вопрос, по какой причине определение принадлежности точки многоугольнику работает некорректно, если координаты из больших чисел состоят, например: int[] vertex = new int[] {...
Сейчас проверила нашла причину не запускания // Создание контекста воспроизведения OpenGL и привязка его к панели на форме OpenGLControl1:=TOpenGLControl.Create(Self); with OpenGLControl1 do begin Name:='OpenGLControl1'; //вот тут...
Ну..кажется что то пошло не так http://pp.usera...
Пример, к которому вы оставили комментарий строит именно то самое изображение на языке с#, которое вам необходимо. Отличается только цветовая палитра.

Счетчики и рейтинг

Рейтинг@Mail.ru
Скриншот к примеру
Среда программирования: 
Lazarus

Задача - построить перспективную проекцию усеченной пирамиды с четырехугольным основанием.

Создадим форму с кнопкой, при нажатии на которую стираются предыдущие результаты построения (если таковые имеются) и заново рисуется уже повернутая усеченная пирамида.

Используемые функции и процедуры:
FormCreate() - определение координат усеченной пирамиды;
Button1Click() - очищает экран, вращает и рисует заново усеченную пирамиду.

Код программы: 

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    PaintBox1: TPaintBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  var X, Y, Z : Array[0..7] Of Real;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  //определяем координаты усеченной пирамиды
  X[0] := -1.0; Y[0] := -1.0; Z[0] :=  1.0;
  X[1] :=  1.0; Y[1] := -1.0; Z[1] :=  1.0;
  X[2] :=  1.0; Y[2] :=  1.0; Z[2] :=  1.0;
  X[3] := -1.0; Y[3] :=  1.0; Z[3] :=  1.0;
  X[4] := -0.5; Y[4] := -0.5; Z[4] :=  3.0;
  X[5] :=  0.5; Y[5] := -0.5; Z[5] :=  3.0;
  X[6] :=  0.5; Y[6] :=  0.5; Z[6] :=  3.0;
  X[7] := -0.5; Y[7] :=  0.5; Z[7] :=  3.0;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var i, minside, tmpx, tmpy : Integer;
  newx, newy, newz : Real;
  p1, p2 : TPoint;
begin
  //очищаем экран
  PaintBox1.Canvas.Clear;
 
  // вращение усеченной пирамиды
  // 1)Сдвигаем все точки в центр вращения
  for i := 0 to 7 do
  begin
    Z[i] := Z[i] - 2.0;
  end;
  // 2)вращаем точки
  for i := 0 to 7 do
  begin
    // пересчитываем значения
    // вращаем
    newx :=  0.9854317338*x[i]-0.1127537376*y[i]+0.1273220038*z[i];
    newy :=  0.1273220038*x[i]+0.9854317338*y[i]-0.1127537376*z[i];
    newz := -0.1127537376*x[i]+0.1273220038*y[i]+0.9854317338*z[i];
    x[i] := newx;
    y[i] := newy;
    z[i] := newz;
  end;
  // 3)сдвигаем обратно на исходную позицию
  for i := 0 to 7 do
  begin
    Z[i] := Z[i] + 2.0;
  end;
 
 
  // отрисовываем усеченную пирамиду:
  // 1) определяем меньшую сторону окна
  if (PaintBox1.Width < PaintBox1.Height) then minside := PaintBox1.Width
  else minside := PaintBox1.Height;
  // 2) перевод координат в экранные и отрисовка линий
  with PaintBox1.Canvas do
  begin
    //лицевая сторона
    tmpx := round((X[0]/Z[0]+2.0)*minside/4);
    tmpy := round((Y[0]/Z[0]+2.0)*minside/4);
    MoveTo(tmpx, tmpy);
    tmpx := round((X[1]/Z[1]+2.0)*minside/4);
    tmpy := round((Y[1]/Z[1]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[2]/Z[2]+2.0)*minside/4);
    tmpy := round((Y[2]/Z[2]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[3]/Z[3]+2.0)*minside/4);
    tmpy := round((Y[3]/Z[3]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[0]/Z[0]+2.0)*minside/4);
    tmpy := round((Y[0]/Z[0]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
 
    //задняя сторона
    tmpx := round((X[4]/Z[4]+2.0)*minside/4);
    tmpy := round((Y[4]/Z[4]+2.0)*minside/4);
    MoveTo(tmpx, tmpy);
    tmpx := round((X[5]/Z[5]+2.0)*minside/4);
    tmpy := round((Y[5]/Z[5]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[6]/Z[6]+2.0)*minside/4);
    tmpy := round((Y[6]/Z[6]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[7]/Z[7]+2.0)*minside/4);
    tmpy := round((Y[7]/Z[7]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[4]/Z[4]+2.0)*minside/4);
    tmpy := round((Y[4]/Z[4]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
 
    //левая сторона
    tmpx := round((X[0]/Z[0]+2.0)*minside/4);
    tmpy := round((Y[0]/Z[0]+2.0)*minside/4);
    MoveTo(tmpx, tmpy);
    tmpx := round((X[4]/Z[4]+2.0)*minside/4);
    tmpy := round((Y[4]/Z[4]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[7]/Z[7]+2.0)*minside/4);
    tmpy := round((Y[7]/Z[7]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[3]/Z[3]+2.0)*minside/4);
    tmpy := round((Y[3]/Z[3]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[0]/Z[0]+2.0)*minside/4);
    tmpy := round((Y[0]/Z[0]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
 
    //правая сторона
    tmpx := round((X[1]/Z[1]+2.0)*minside/4);
    tmpy := round((Y[1]/Z[1]+2.0)*minside/4);
    MoveTo(tmpx, tmpy);
    tmpx := round((X[2]/Z[2]+2.0)*minside/4);
    tmpy := round((Y[2]/Z[2]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[6]/Z[6]+2.0)*minside/4);
    tmpy := round((Y[6]/Z[6]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[5]/Z[5]+2.0)*minside/4);
    tmpy := round((Y[5]/Z[5]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
    tmpx := round((X[1]/Z[1]+2.0)*minside/4);
    tmpy := round((Y[1]/Z[1]+2.0)*minside/4);
    LineTo(tmpx, tmpy);
  end;
end;
 
end.

Прикрепленный файлРазмер
rotation.rar971.13 кб