|
- unit ugluVectorExHelper;
-
- {$mode objfpc}{$H+}
- {$modeswitch typehelpers}
-
- interface
-
- uses
- Classes, SysUtils;
-
- type
- generic TgluVectorHelper<T> = class
- public type
- TBaseType = T;
- PBaseType = ^TBaseType;
-
- TVector2 = array[0..1] of T;
- TVector3 = array[0..2] of T;
- TVector4 = array[0..3] of T;
-
- PVector2 = ^TVector2;
- PVector3 = ^TVector3;
- PVector4 = ^TVector4;
-
- public
- class function Vector2(const x, y: T): TVector2; overload; inline;
- class function Vector3(const x, y, z: T): TVector3; overload; inline;
- class function Vector4(const x, y, z, w: T): TVector4; overload; inline;
-
- class function Equals(const v1: TVector2; const v2: TVector2): Boolean; overload; inline;
- class function Equals(const v1: TVector3; const v2: TVector3): Boolean; overload; inline;
- class function Equals(const v1: TVector4; const v2: TVector4): Boolean; overload; inline;
-
- class function ToString(const v: TVector2; const aRound: Integer = -3): String; overload;
- class function ToString(const v: TVector3; const aRound: Integer = -3): String; overload;
- class function ToString(const v: TVector4; const aRound: Integer = -3): String; overload;
-
- class function TryFromString(const s: String; out v: TVector2): Boolean; overload; inline;
- class function TryFromString(const s: String; out v: TVector3): Boolean; overload; inline;
- class function TryFromString(const s: String; out v: TVector4): Boolean; overload; inline;
- class function TryFromString(const s: String; p: PBaseType; aCount: Integer): Boolean;
- end;
-
- generic TgluVectorHelperI<T> = class(specialize TgluVectorHelper<T>)
- public
- class function Length(const v: TVector2): Double; overload; inline;
- class function Length(const v: TVector3): Double; overload; inline;
- class function Length(const v: TVector4): Double; overload; inline;
-
- class function SqrLength(const v: TVector2): Double; overload; inline;
- class function SqrLength(const v: TVector3): Double; overload; inline;
- class function SqrLength(const v: TVector4): Double; overload; inline;
-
- class function Multiply(const v: TVector2; const a: T): TVector2; overload; inline;
- class function Multiply(const v: TVector3; const a: T): TVector3; overload; inline;
- class function Multiply(const v: TVector4; const a: T): TVector4; overload; inline;
-
- class function Multiply(const v1, v2: TVector2): TVector2; overload; inline;
- class function Multiply(const v1, v2: TVector3): TVector3; overload; inline;
- class function Multiply(const v1, v2: TVector4): TVector4; overload; inline;
-
- class function Add(const v1, v2: TVector2): TVector2; overload; inline;
- class function Add(const v1, v2: TVector3): TVector3; overload; inline;
- class function Add(const v1, v2: TVector4): TVector4; overload; inline;
-
- class function Sub(const v1, v2: TVector2): TVector2; overload; inline;
- class function Sub(const v1, v2: TVector3): TVector3; overload; inline;
- class function Sub(const v1, v2: TVector4): TVector4; overload; inline;
-
- class function ClampVal(const v, aMin, aMax: T): T; overload; inline;
- class function Clamp(const v, aMin, aMax: TVector2): TVector2; overload; inline;
- class function Clamp(const v, aMin, aMax: TVector3): TVector3; overload; inline;
- class function Clamp(const v, aMin, aMax: TVector4): TVector4; overload; inline;
- class function Clamp(const v: TVector2; const aMin, aMax: T): TVector2; overload; inline;
- class function Clamp(const v: TVector3; const aMin, aMax: T): TVector3; overload; inline;
- class function Clamp(const v: TVector4; const aMin, aMax: T): TVector4; overload; inline;
- end;
-
- generic TgluVectorHelperF<T> = class(specialize TgluVectorHelperI<T>)
- public
- class function Normalize(const v: TVector2): TVector2; overload; inline;
- class function Normalize(const v: TVector3): TVector3; overload; inline;
- class function Normalize(const v: TVector4): TVector4; overload; inline;
-
- class function Divide(const v: TVector2; const a: T): TVector2; overload; inline;
- class function Divide(const v: TVector3; const a: T): TVector3; overload; inline;
- class function Divide(const v: TVector4; const a: T): TVector4; overload; inline;
-
- class function Dot(const v1: TVector2; const v2: TVector2): T; overload; inline;
- class function Dot(const v1: TVector3; const v2: TVector3): T; overload; inline;
- class function Dot(const v1: TVector4; const v2: TVector4): T; overload; inline;
-
- class function Cross(const v1: TVector3; const v2: TVector3): TVector3; overload; inline;
-
- class function Angle(const v1: TVector2; const v2: TVector2): Double; overload; inline;
- class function Angle(const v1: TVector3; const v2: TVector3): Double; overload; inline;
- class function Angle2(const v1: TVector2; const v2: TVector2): Double; overload; inline;
- end;
-
- TgluVectorP = specialize TgluVectorHelper<Pointer>;
- TgluVectorE = specialize TgluVectorHelper<Cardinal>;
-
- TgluVectorI = specialize TgluVectorHelperI<Integer>;
- TgluVectorUS = specialize TgluVectorHelperI<Word>;
- TgluVectorUB = specialize TgluVectorHelperI<Byte>;
-
- TgluVectorF = specialize TgluVectorHelperF<Single>;
- TgluVectorD = specialize TgluVectorHelperF<Double>;
-
- TPointerTypeHelper = type helper for Pointer
- function ToString(const aRound: Integer = -3): String;
- class function TryFromString(s: String; out v: Pointer): Boolean; static;
- end;
-
- TCardinalTypeHelper = type helper for Cardinal
- function ToString(const aRound: Integer = -3): String;
- class function TryFromString(s: String; out v: Cardinal): Boolean; static;
- end;
-
- TIntegerTypeHelper = type helper for Integer
- function ToString(const aRound: Integer = -3): String;
- class function TryFromString(s: String; out v: Integer): Boolean; static;
- end;
-
- TWordTypeHelper = type helper for Word
- function ToString(const aRound: Integer = -3): String;
- class function TryFromString(s: String; out v: Word): Boolean; static;
- end;
-
- TByteTypeHelper = type helper for Byte
- function ToString(const aRound: Integer = -3): String;
- class function TryFromString(s: String; out v: Byte): Boolean; static;
- end;
-
- TSingleTypeHelper = type helper for Single
- function ToString(const aRound: Integer = -3): String;
- class function TryFromString(s: String; out v: Single): Boolean; static;
- end;
-
- TDoubleTypeHelper = type helper for Double
- function ToString(const aRound: Integer = -3): String;
- class function TryFromString(s: String; out v: Double): Boolean; static;
- end;
-
- implementation
-
- uses
- Math;
-
- function IntToStrRounded(i: Int64; const aRound: Integer): String;
- var p: Cardinal;
- begin
- if (aRound > 0) then begin
- p := Round(power(10, aRound));
- i := i div p;
- i := i * p;
- end;
- result := IntToStr(i);
- end;
-
- function FloatToStrRounded(f: Extended; const aRound: Integer): String;
- var p: Cardinal; fmt: TFormatSettings;
- begin
- if (aRound > 0) then begin
- p := Round(power(10, aRound));
- f := Round(f / p) * p;
- end;
- fmt.DecimalSeparator := '.';
- result := Format('%.*f', [Max(0, -aRound), f], fmt);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TPointerTypeHelper////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TPointerTypeHelper.ToString(const aRound: Integer): String;
- begin
- result := '0x' + IntToHex({%H-}PtrUInt(self), 2 * SizeOf(Pointer));
- end;
-
- class function TPointerTypeHelper.TryFromString(s: String; out v: Pointer): Boolean;
- var
- i: Int64;
- begin
- s := StringReplace(s, '0x', '$', [rfReplaceAll, rfIgnoreCase]);
- result := TryStrToInt64(s, i);
- if result
- then v := {%H-}Pointer(PtrUInt(i))
- else v := nil;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TCardinalTypeHelper///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TCardinalTypeHelper.ToString(const aRound: Integer): String;
- begin
- result := IntToStrRounded(self, aRound);
- end;
-
- class function TCardinalTypeHelper.TryFromString(s: String; out v: Cardinal): Boolean;
- var i: LongInt;
- begin
- result := TryStrToInt(s, i);
- if result
- then v := i
- else v := 0;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TIntegerTypeHelper////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TIntegerTypeHelper.ToString(const aRound: Integer): String;
- begin
- result := IntToStrRounded(self, aRound);
- end;
-
- class function TIntegerTypeHelper.TryFromString(s: String; out v: Integer): Boolean;
- begin
- result := TryStrToInt(s, v);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TWordTypeHelper///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TWordTypeHelper.ToString(const aRound: Integer): String;
- begin
- result := IntToStrRounded(self, aRound);
- end;
-
- class function TWordTypeHelper.TryFromString(s: String; out v: Word): Boolean;
- var i: LongInt;
- begin
- result := TryStrToInt(s, i);
- if result
- then v := i
- else v := 0;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TByteTypeHelper///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TByteTypeHelper.ToString(const aRound: Integer): String;
- begin
- result := IntToStrRounded(self, aRound);
- end;
-
- class function TByteTypeHelper.TryFromString(s: String; out v: Byte): Boolean;
- var i: LongInt;
- begin
- result := TryStrToInt(s, i);
- if result
- then v := i
- else v := 0;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TSingleTypeHelper/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TSingleTypeHelper.ToString(const aRound: Integer): String;
- begin
- result := FloatToStrRounded(self, aRound);
- end;
-
- class function TSingleTypeHelper.TryFromString(s: String; out v: Single): Boolean;
- var f: TFormatSettings;
- begin
- f.DecimalSeparator := '.';
- result := TryStrToFloat(s, v, f);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TDoubleTypeHelper/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TDoubleTypeHelper.ToString(const aRound: Integer): String;
- begin
- result := FloatToStrRounded(self, aRound);
- end;
-
- class function TDoubleTypeHelper.TryFromString(s: String; out v: Double): Boolean;
- var f: TFormatSettings;
- begin
- f.DecimalSeparator := '.';
- result := TryStrToFloat(s, v, f);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TgluVectorHelper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class function TgluVectorHelper.Vector2(const x, y: T): TVector2;
- begin
- result[0] := x;
- result[1] := y;
- end;
-
- class function TgluVectorHelper.Vector3(const x, y, z: T): TVector3;
- begin
- result[0] := x;
- result[1] := y;
- result[2] := z;
- end;
-
- class function TgluVectorHelper.Vector4(const x, y, z, w: T): TVector4;
- begin
- result[0] := x;
- result[1] := y;
- result[2] := z;
- result[3] := w;
- end;
-
- class function TgluVectorHelper.Equals(const v1: TVector2; const v2: TVector2): Boolean;
- begin
- result := (v1[0] = v2[0]) and (v1[1] = v2[1]);
- end;
-
- class function TgluVectorHelper.Equals(const v1: TVector3; const v2: TVector3): Boolean;
- begin
- result := Equals(PVector2(@v1[0])^, PVector2(@v2[0])^) and (v1[2] = v2[2]);
- end;
-
- class function TgluVectorHelper.Equals(const v1: TVector4; const v2: TVector4): Boolean;
- begin
- result := Equals(PVector3(@v1[0])^, PVector3(@v2[0])^) and (v1[3] = v2[3]);
- end;
-
- class function TgluVectorHelper.ToString(const v: TVector2; const aRound: Integer): String;
- begin
- result := v[0].ToString(aRound) + '; ' + v[1].ToString(aRound);
- end;
-
- class function TgluVectorHelper.ToString(const v: TVector3; const aRound: Integer): String;
- begin
- result := v[0].ToString(aRound) + '; ' + v[1].ToString(aRound) + '; ' + v[2].ToString(aRound);
- end;
-
- class function TgluVectorHelper.ToString(const v: TVector4; const aRound: Integer): String;
- begin
- result := v[0].ToString(aRound) + '; ' + v[1].ToString(aRound) + '; ' + v[2].ToString(aRound) + '; ' + v[3].ToString(aRound);
- end;
-
- class function TgluVectorHelper.TryFromString(const s: String; out v: TVector2): Boolean;
- begin
- result := TryFromString(s, @v[0], 2);
- end;
-
- class function TgluVectorHelper.TryFromString(const s: String; out v: TVector3): Boolean;
- begin
- result := TryFromString(s, @v[0], 3);
- end;
-
- class function TgluVectorHelper.TryFromString(const s: String; out v: TVector4): Boolean;
- begin
- result := TryFromString(s, @v[0], 4);
- end;
-
- class function TgluVectorHelper.TryFromString(const s: String; p: PBaseType; aCount: Integer): Boolean;
- var
- i, j, l: Integer;
- begin
- result := true;
- i := 1;
- j := 1;
- l := Length(s);
- while ({%H-}i <= {%H-}l) and (aCount > 0) and result {%H-}do begin
- if (s[i] = ';') or (i = l) then begin
- if (i = l) then inc(i);
- result := TBaseType.TryFromString(Trim(copy(s, j, i-{%H-}j)), p^);
- j := i+1;
- inc(p);
- dec(aCount);
- end;
- inc(i);
- end;
-
- result := (aCount = 0);
- while (aCount > 0) do begin
- p^ := TBaseType(0);
- inc(p);
- dec(aCount);
- end;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TgluVectorHelperI/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class function TgluVectorHelperI.Length(const v: TVector2): Double;
- begin
- result := SQRT(v[0]*v[0] + v[1]*v[1]);
- end;
-
- class function TgluVectorHelperI.Length(const v: TVector3): Double;
- begin
- result := SQRT(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
- end;
-
- class function TgluVectorHelperI.Length(const v: TVector4): Double;
- begin
- result := SQRT(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]) * v[3];
- end;
-
- class function TgluVectorHelperI.SqrLength(const v: TVector2): Double;
- begin
- result := v[0]*v[0] + v[1]*v[1];
- end;
-
- class function TgluVectorHelperI.SqrLength(const v: TVector3): Double;
- begin
- result := v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
- end;
-
- class function TgluVectorHelperI.SqrLength(const v: TVector4): Double;
- begin
- result := (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]) * v[3];
- end;
-
- class function TgluVectorHelperI.Multiply(const v: TVector2; const a: T): TVector2;
- begin
- result[0] := v[0] * a;
- result[1] := v[1] * a;
- end;
-
- class function TgluVectorHelperI.Multiply(const v: TVector3; const a: T): TVector3;
- begin
- result[0] := v[0] * a;
- result[1] := v[1] * a;
- result[2] := v[2] * a;
- end;
-
- class function TgluVectorHelperI.Multiply(const v: TVector4; const a: T): TVector4;
- begin
- result[0] := v[0] * a;
- result[1] := v[1] * a;
- result[2] := v[2] * a;
- result[3] := v[3] * a;
- end;
-
- class function TgluVectorHelperI.Multiply(const v1, v2: TVector2): TVector2;
- begin
- result[0] := v1[0] * v2[0];
- result[1] := v1[1] * v2[1];
- end;
-
- class function TgluVectorHelperI.Multiply(const v1, v2: TVector3): TVector3;
- begin
- result[0] := v1[0] * v2[0];
- result[1] := v1[1] * v2[1];
- result[2] := v1[2] * v2[2];
- end;
-
- class function TgluVectorHelperI.Multiply(const v1, v2: TVector4): TVector4;
- begin
- result[0] := v1[0] * v2[0];
- result[1] := v1[1] * v2[1];
- result[2] := v1[2] * v2[2];
- result[3] := v1[3] * v2[3];
- end;
-
- class function TgluVectorHelperI.Add(const v1, v2: TVector2): TVector2;
- begin
- result[0] := v1[0] + v2[0];
- result[1] := v1[1] + v2[1];
- end;
-
- class function TgluVectorHelperI.Add(const v1, v2: TVector3): TVector3;
- begin
- result[0] := v1[0] + v2[0];
- result[1] := v1[1] + v2[1];
- result[2] := v1[2] + v2[2];
- end;
-
- class function TgluVectorHelperI.Add(const v1, v2: TVector4): TVector4;
- begin
- result[0] := v1[0] + v2[0];
- result[1] := v1[1] + v2[1];
- result[2] := v1[2] + v2[2];
- result[3] := v1[3] + v2[3];
- end;
-
-
- class function TgluVectorHelperI.Sub(const v1, v2: TVector2): TVector2;
- begin
- result[0] := v1[0] - v2[0];
- result[1] := v1[1] - v2[1];
- end;
-
- class function TgluVectorHelperI.Sub(const v1, v2: TVector3): TVector3;
- begin
- result[0] := v1[0] - v2[0];
- result[1] := v1[1] - v2[1];
- result[2] := v1[2] - v2[2];
- end;
-
- class function TgluVectorHelperI.Sub(const v1, v2: TVector4): TVector4;
- begin
- result[0] := v1[0] - v2[0];
- result[1] := v1[1] - v2[1];
- result[2] := v1[2] - v2[2];
- result[3] := v1[3] - v2[3];
- end;
-
- class function TgluVectorHelperI.ClampVal(const v, aMin, aMax: T): T;
- begin
- if (v < aMin) then
- result := aMin
- else if (v > aMax) then
- result := aMax
- else
- result := v;
- end;
-
- class function TgluVectorHelperI.Clamp(const v, aMin, aMax: TVector2): TVector2;
- begin
- result[0] := ClampVal(v[0], aMin[0], aMax[0]);
- result[1] := ClampVal(v[1], aMin[1], aMax[1]);
- end;
-
- class function TgluVectorHelperI.Clamp(const v, aMin, aMax: TVector3): TVector3;
- begin
- result[0] := ClampVal(v[0], aMin[0], aMax[0]);
- result[1] := ClampVal(v[1], aMin[1], aMax[1]);
- result[2] := ClampVal(v[2], aMin[2], aMax[2]);
- end;
-
- class function TgluVectorHelperI.Clamp(const v, aMin, aMax: TVector4): TVector4;
- begin
- result[0] := ClampVal(v[0], aMin[0], aMax[0]);
- result[1] := ClampVal(v[1], aMin[1], aMax[1]);
- result[2] := ClampVal(v[2], aMin[2], aMax[2]);
- result[3] := ClampVal(v[3], aMin[3], aMax[3]);
- end;
-
- class function TgluVectorHelperI.Clamp(const v: TVector2; const aMin, aMax: T): TVector2;
- begin
- result[0] := ClampVal(v[0], aMin, aMax);
- result[1] := ClampVal(v[1], aMin, aMax);
- end;
-
- class function TgluVectorHelperI.Clamp(const v: TVector3; const aMin, aMax: T): TVector3;
- begin
- result[0] := ClampVal(v[0], aMin, aMax);
- result[1] := ClampVal(v[1], aMin, aMax);
- result[2] := ClampVal(v[2], aMin, aMax);
- end;
-
- class function TgluVectorHelperI.Clamp(const v: TVector4; const aMin, aMax: T): TVector4;
- begin
- result[0] := ClampVal(v[0], aMin, aMax);
- result[1] := ClampVal(v[1], aMin, aMax);
- result[2] := ClampVal(v[2], aMin, aMax);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TgluVectorHelperF/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class function TgluVectorHelperF.Normalize(const v: TVector2): TVector2;
- var l: Double;
- begin
- l := Length(v);
- result[0] := v[0] / l;
- result[1] := v[1] / l;
- end;
-
- class function TgluVectorHelperF.Normalize(const v: TVector3): TVector3;
- var l: Double;
- begin
- l := Length(v);
- result[0] := v[0] / l;
- result[1] := v[1] / l;
- result[2] := v[2] / l;
- end;
-
- class function TgluVectorHelperF.Normalize(const v: TVector4): TVector4;
- begin
- result := v;
- if (result[3] <> 0) then
- result := Divide(v, v[3]);
- PVector3(@result[0])^ := Normalize(PVector3(@result[0])^);
- end;
-
- class function TgluVectorHelperF.Divide(const v: TVector2; const a: T): TVector2;
- begin
- result[0] := v[0] / a;
- result[1] := v[1] / a;
- end;
-
- class function TgluVectorHelperF.Divide(const v: TVector3; const a: T): TVector3;
- begin
- result[0] := v[0] / a;
- result[1] := v[1] / a;
- result[2] := v[2] / a;
- end;
-
- class function TgluVectorHelperF.Divide(const v: TVector4; const a: T): TVector4;
- begin
- result[0] := v[0] / a;
- result[1] := v[1] / a;
- result[2] := v[2] / a;
- result[3] := v[3] / a;
- end;
-
- class function TgluVectorHelperF.Dot(const v1: TVector2; const v2: TVector2): T;
- begin
- result := v1[0] * v2[0] + v1[1] * v2[1];
- end;
-
- class function TgluVectorHelperF.Dot(const v1: TVector3; const v2: TVector3): T;
- begin
- result := v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
- end;
-
- class function TgluVectorHelperF.Dot(const v1: TVector4; const v2: TVector4): T;
- begin
- result := v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3];
- end;
-
- class function TgluVectorHelperF.Cross(const v1: TVector3; const v2: TVector3): TVector3;
- begin
- result[0] := v1[1] * v2[2] - v1[2] * v2[1];
- result[1] := v1[2] * v2[0] - v1[0] * v2[2];
- result[2] := v1[0] * v2[1] - v1[1] * v2[0];
- end;
-
- class function TgluVectorHelperF.Angle(const v1: TVector2; const v2: TVector2): Double;
- begin
- result := ArcCos(Dot(v1, v2) / (Length(v1) * Length(v2)));
- end;
-
- class function TgluVectorHelperF.Angle(const v1: TVector3; const v2: TVector3): Double;
- begin
- result := ArcCos(Dot(v1, v2) / (Length(v1) * Length(v2)));
- end;
-
- class function TgluVectorHelperF.Angle2(const v1: TVector2; const v2: TVector2): Double;
- begin
- result := arctan2(
- v2[0] * v1[1] - v2[1] * v1[0],
- v2[0] * v1[0] + v2[1] * v1[1]);
- end;
-
- end.
|