Текущий архив: 2010.09.12;
Скачать: CL | DM;
Вниз
Какое правильно "перевести"... Найти похожие ветки
← →
AKE (2010-06-13 11:43) [0]точку из аксонометрического в перспективный вид?
← →
MBo © (2010-06-13 11:55) [1]Аксонометрических проекций - вагон и маленькая тележка (в частности изометрий несколько штук)
По большому счету преобразование из одной проекции в другую выполняется с помощью умножения на соотв. матрицу перехода, однако ввиду того, что размерность координатного пространства при проекции сокращается с 3 до 2, однозначности не будет.
← →
AKE (2010-06-13 12:01) [2]MBo © (13.06.10 11:55) [1]
Не поделитесь пожалуйста видом матрицы.
У меня есть три координаты (x, y, z);
← →
AKE (2010-06-13 12:08) [3]MBo © (13.06.10 11:55) [1]
Я написал простенький код для прорисовки треугольников. Но здесь всё в аксонометрии. Как перевести в линейную перспективу. То есть чтобы более дальние были меньше передних.
unit Graphic1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TfrmForm = class(TForm)
imgDraw: TImage;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
ColorBox1: TColorBox;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmForm: TfrmForm;
X0, Y0: integer;
Buffer: array of array of integer;
implementation
{$R *.dfm}
function GetX(x, y, z: Integer): Integer;
begin
Result := Round(X0+y-x*1/Sqrt(2));
end;
function GetY(x, y, z: Integer): Integer;
begin
Result := Round(Y0-z+x*1/Sqrt(2))
end;
function PtInTriangle(ax, ay, bx, by, cx, cy, px, py: Integer): Boolean;
var
xb, yb, xc, yc, xp, yp, d: Integer;
bb, cc, oned: Double;
begin
Result := False;
xb := bx - ax;
yb := by - ay;
xc := cx - ax;
yc := cy - ay;
xp := px - ax;
yp := py - ay;
d := xb * yc - yb * xc;
if d <> 0 then begin
oned := 1 / d;
bb := (xp * yc - xc * yp) * oned;
cc := (xb * yp - xp * yb) * oned;
Result := (bb >= 0) and (cc >= 0) and (bb + cc <= 1);
end;
end;
procedure TfrmForm.FormCreate(Sender: TObject);
var
i, j: Integer;
begin
SetLength(Buffer, imgDraw.Width, imgDraw.Height);
for i := 0 to imgDraw.Width-1 do
for j := 0 to imgDraw.Height-1 do
begin
Buffer[i][j] := -1000;
end;
X0 := imgDraw.Width shr 1;
Y0 := imgDraw.Height shr 1;
Label4.Caption := IntToStr(X0);
Label5.Caption := IntToStr(Y0);
imgDraw.Canvas.Pen.Color := clBlack;
imgDraw.Canvas.MoveTo(X0, Y0);
imgDraw.Canvas.LineTo(GetX(250,0,0),GetY(250,0,0));
imgDraw.Canvas.MoveTo(X0, Y0);
imgDraw.Canvas.LineTo(GetX(0,250,0),GetY(0,250,0));
imgDraw.Canvas.MoveTo(X0, Y0);
imgDraw.Canvas.LineTo(GetX(0,0,250),GetY(0,0,250));
end;
function Min3(x, y, z: Integer): Integer;
begin
if (x >= y) then
begin
if (y >= z) then
Result := z
else
Result := y;
end
else
begin
if (x >= z) then
Result := z
else Result := x;
end;
end;
function Max3(x, y, z: Integer): Integer;
begin
if (x >= y) then
begin
if (x >= z) then
Result := x
else
Result := z;
end
else
begin
if (y >= z) then
Result := y
else Result := z;
end;
end;
procedure TfrmForm.Button1Click(Sender: TObject);
var
X_1, Y_1: integer;
X_2, Y_2: integer;
X_3, Y_3: integer;
MinX, MaxX: integer;
MinY, MaxY: integer;
MinZ, MaxZ: integer;
x, y, z : Integer;
x1, y1, z1: Integer;
x2, y2, z2: Integer;
i, j, k: integer;
X_, Y_:integer;
begin
x := StrToInt(Edit1.Text);
y := StrToInt(Edit2.Text);
z := StrToInt(Edit3.Text);
x1 := StrToInt(Edit4.Text);
y1 := StrToInt(Edit5.Text);
z1 := StrToInt(Edit6.Text);
x2 := StrToInt(Edit7.Text);
y2 := StrToInt(Edit8.Text);
z2 := StrToInt(Edit9.Text);
X_1 := GetX(x,y,z); Y_1 := GetY(x,y,z);
X_2 := GetX(x1,y1,z1); Y_2 := GetY(x1,y1,z1);
X_3 := GetX(x2,y2,z2); Y_3 := GetY(x2,y2,z2);
MinX := Min3(x, x1, x2);
MinY := Min3(y, y1, y2);
MinZ := Min3(z, z1, z2);
MaxX := Max3(x, x1, x2);
MaxY := Max3(y, y1, y2);
MaxZ := Max3(z, z1, z2);
for i := MinX to MaxX do
for j := MinY to MaxY do
for k := MinZ to MaxZ do
begin
X_ := GetX(i, j, k);
Y_ := GetY(i, j, k);
if PtInTriangle(X_1, Y_1, X_2, Y_2, X_3, Y_3, X_, Y_) and
(Buffer[X_, Y_] <= i) then
begin
imgDraw.Canvas.Pixels[X_, Y_] := ColorBox1.Selected;
Buffer[X_, Y_] := i;
end;
end;
end;
end.
← →
MBo © (2010-06-13 12:13) [4]>Не поделитесь пожалуйста видом матрицы.
У меня ее нет, а вот гугл знает.
← →
MBo © (2010-06-13 12:16) [5]Так из трехмерных координат сразу и надо перспективную проекцию получать...
← →
AKE (2010-06-13 12:19) [6]MBo © (13.06.10 12:16) [5]
А какая формула??
← →
0x00FF00 (2010-06-14 19:59) [7]
> А какая формула??
Формула!! Где формула???!! © Телереклама
=)
зы. взгляни в сторону Борескова "Графика игры на основе OpenGL". Матчасть отрисовки (и перспективы в частности) там разъяснена весьма грамотно.
← →
Dimka Maslov © (2010-06-15 12:13) [8]Алгоритм простой, как два байта переслать:
http://kladovka.net.ru/delphibase/?action=viewfunc&topic=mathcalc&id=10097
Главное правильно подобрать параметры
Страницы: 1 вся ветка
Текущий архив: 2010.09.12;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.011 c