Меню сайта


Статистика



Главная » Статьи » Уроки » С/C++, Lua, HLSL, DirectX, OpenGL

Программирование основных геометрических операций
Итак, это небольшая помощь тем, кто решил вступить на нелёгкий путь гейм-мэйкера =) Собственно, название статьи целиком отражает её содержимое: примеры реализации геометрических операций с векторами и матрицами. Примеры на Delphi, но переделать под С не составит труда.
Итак, начнём) Для начала укажем типы для векторов(за стандартный можно взять например вектор из 4-х чисел с плавающей точкой):
type
TVector4f = array[0..3] of single;
TVector = TVector4f;
Ещё неплохо бы задать константы для единичных векторов:

const NullVector: TVector = ((0),(0),(0),(0));
const Vector1 : TVector = ((1),(1),(1),(1));
const XVector1 : TVector = ((1),(0),(0),(0));
const YVector1 : TVector = ((0),(1),(0),(0));
const ZVector1 : TVector = ((0),(0),(1),(0));

Задавать вектора удобно с помощью ф-ий, вроде этой:

function VectorMake(X,Y,Z: single; W: single = 1): TVector; overload;
var V: TVector;
begin
V[0]:=X;
V[1]:=Y;
V[2]:=Z;
V[3]:=W;
VectorMake:=V;
end;

Очень частая операция - нахождение длины вектора(корень из суммы квадратов разности координат начала и конца вектора, но начало-то у нас в 0.0.0):

function VectorLength(V: TVector): single;
var a: single;
begin
a:=Sqr(V[0])+Sqr(V[1])+Sqr(V[2]);
Result:=Sqrt(A);
end; //без оптимизации)

По определению - расстояние между точками(их радиус-векторами):
function Distance(V1,V2: TVector): single;
begin
Result:=Sqrt(Sqr(V1[0]-V2[0])+Sqr(V1[1]-V2[1])+Sqr(V1[2]-V2[2]));
end;

Часто приходится отразить вектор относительно нуля, т.е. V[i] = -V[i]:
function VectorNegate(Vector: TVector): TVector;
begin
Result[0]:= -Vector[0];
Result[1]:= -Vector[1];
Result[2]:= -Vector[2];
end;

Простейшая "арифметика" - сложение, вычитание...:

function VectorAdd(V1,V2: TVector): TVector;
var V: TVector;
begin
V[0]:=V1[0]+V2[0];
V[1]:=V1[1]+V2[1];
V[2]:=V1[2]+V2[2];
Result:=V;
end;

function VectorSubtract(V1,V2: TVector): TVector;
begin
Result:=VectorAdd(V1,VectorNegate(V2));
end;

function VectorScale(Vector: TVector; f: single): TVector;
var V: TVector;
begin
V[0]:=Vector[0]*f;
V[1]:=Vector[1]*f;
V[2]:=Vector[2]*f;
Result:=V;
end;

Скалярное произведение:

function VectorDotProduct(V1,V2: TVector): single;
var a: single;
begin
a:=(V1[0]*V2[0]+V1[1]*V2[1]+V1[2]*V2[2])/VectorLength(V1)/VectorLength(V2);
Result:=a;
end;

И векторное:

function VectorCrossProduct(V1,V2: TVector): TVector;
var V: TVector;
begin
V[0]:=V1[1]*V2[2]-V1[2]*V2[1];
V[1]:=V1[2]*V2[0]-V1[0]*V2[2];
V[2]:=V1[0]*V2[1]-V1[1]*V2[0];
Result:=V;
end;

Нормализация(приведение к длине 1):

function VectorNormalize(V: TVector): TVector;
var L: single;
begin
L:=VectorLength(V);
if L = 0 then begin
Result:=NullVector;
Exit;
end;
Result[0]:=V[0]/L;
Result[1]:=V[1]/L;
Result[2]:=V[2]/L;
end;

Категория: С/C++, Lua, HLSL, DirectX, OpenGL | Добавил: Molch (18.11.2009)
Просмотров: 1196 | Комментарии: 1 | Рейтинг: 5.0/1
Всего комментариев: 1
1 Призрачный_Гонщик  
Превосходно:) Спс:)

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Скачать