You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
301 lines
10 KiB
Plaintext
301 lines
10 KiB
Plaintext
unit GR32_Geometry;
|
|
|
|
(* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1 or LGPL 2.1 with linking exception
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of the
|
|
* Free Pascal modified version of the GNU Lesser General Public License
|
|
* Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
|
|
* of this license are applicable instead of those above.
|
|
* Please see the file LICENSE.txt for additional information concerning this
|
|
* license.
|
|
*
|
|
* The Original Code is Additional Math Routines for Graphics32
|
|
*
|
|
* The Initial Developers of the Original Code are
|
|
* Mattias Andersson |
|
* Michael Hansen |
|
*
|
|
* Portions created by the Initial Developers are Copyright (C) 2005-2009
|
|
* the Initial Developers. All Rights Reserved.
|
|
*
|
|
*
|
|
* ***** END LICENSE BLOCK ***** *)
|
|
|
|
interface
|
|
|
|
{$I GR32.inc}
|
|
|
|
uses
|
|
Math, GR32, GR32_Math;
|
|
|
|
type
|
|
PFixedVector = ^TFixedVector;
|
|
TFixedVector = TFixedPoint;
|
|
|
|
PFloatVector = ^TFloatVector;
|
|
TFloatVector = TFloatPoint;
|
|
|
|
function Add(const V1, V2: TFloatVector): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Add(const V: TFloatVector; Value: TFloat): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Sub(const V1, V2: TFloatVector): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Sub(const V: TFloatVector; Value: TFloat): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Mul(const V1, V2: TFloatVector): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Mul(const V: TFloatVector; Multiplier: TFloat): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Divide(const V: TFloatVector; Divisor: TFloat): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Divide(const V1, V2: TFloatVector): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
|
|
function Combine(const V1, V2: TFloatVector; W: TFloat): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function AbsV(const V: TFloatVector): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Neg(const V: TFloatVector): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Average(const V1, V2: TFloatVector): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Max(const V1, V2: TFloatVector): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Min(const V1, V2: TFloatVector): TFloatVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
|
|
function Dot(const V1, V2: TFloatVector): TFloat; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Distance(const V1, V2: TFloatVector): TFloat; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function SqrDistance(const V1, V2: TFloatVector): TFloat; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
|
|
// Fixed Overloads
|
|
function Add(const V1, V2: TFixedVector): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Add(const V: TFixedVector; Value: TFixed): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Sub(const V1, V2: TFixedVector): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Sub(const V: TFixedVector; Value: TFixed): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Mul(const V1, V2: TFixedVector): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Mul(const V: TFixedVector; Multiplier: TFixed): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Divide(const V: TFixedVector; Divisor: TFixed): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Divide(const V1, V2: TFixedVector): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
|
|
function Combine(const V1, V2: TFixedVector; W: TFixed): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function AbsV(const V: TFixedVector): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Neg(const V: TFixedVector): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Average(const V1, V2: TFixedVector): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Max(const V1, V2: TFixedVector): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Min(const V1, V2: TFixedVector): TFixedVector; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
|
|
function Dot(const V1, V2: TFixedVector): TFixed; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function Distance(const V1, V2: TFixedVector): TFixed; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
function SqrDistance(const V1, V2: TFixedVector): TFixed; overload;{$IFDEF USEINLINING} inline; {$ENDIF}
|
|
|
|
implementation
|
|
|
|
function Add(const V1, V2: TFloatVector): TFloatVector;
|
|
begin
|
|
Result.X := V1.X + V2.X;
|
|
Result.Y := V1.Y + V2.Y;
|
|
end;
|
|
|
|
function Add(const V: TFloatVector; Value: TFloat): TFloatVector;
|
|
begin
|
|
Result.X := V.X + Value;
|
|
Result.Y := V.Y + Value;
|
|
end;
|
|
|
|
function Sub(const V1, V2: TFloatVector): TFloatVector;
|
|
begin
|
|
Result.X := V1.X - V2.X;
|
|
Result.Y := V1.Y - V2.Y;
|
|
end;
|
|
|
|
function Sub(const V: TFloatVector; Value: TFloat): TFloatVector;
|
|
begin
|
|
Result.X := V.X - Value;
|
|
Result.Y := V.Y - Value;
|
|
end;
|
|
|
|
function Mul(const V1, V2: TFloatVector): TFloatVector;
|
|
begin
|
|
Result.X := V1.X * V2.X;
|
|
Result.Y := V1.Y * V2.Y;
|
|
end;
|
|
|
|
function Mul(const V: TFloatVector; Multiplier: TFloat): TFloatVector;
|
|
begin
|
|
Result.X := V.X * Multiplier;
|
|
Result.Y := V.Y * Multiplier;
|
|
end;
|
|
|
|
function Divide(const V: TFloatVector; Divisor: TFloat): TFloatVector;
|
|
begin
|
|
Divisor := 1 / Divisor;
|
|
Result.X := V.X * Divisor;
|
|
Result.Y := V.Y * Divisor;
|
|
end;
|
|
|
|
function Divide(const V1, V2: TFloatVector): TFloatVector;
|
|
begin
|
|
Result.X := V1.X / V2.X;
|
|
Result.Y := V1.Y / V2.Y;
|
|
end;
|
|
|
|
function Combine(const V1, V2: TFloatVector; W: TFloat): TFloatVector;
|
|
begin
|
|
Result.X := V2.X + (V1.X - V2.X) * W;
|
|
Result.Y := V2.Y + (V1.Y - V2.Y) * W;
|
|
end;
|
|
|
|
function AbsV(const V: TFloatVector): TFloatVector;
|
|
begin
|
|
Result.X := System.Abs(V.X);
|
|
Result.Y := System.Abs(V.Y);
|
|
end;
|
|
|
|
function Neg(const V: TFloatVector): TFloatVector;
|
|
begin
|
|
Result.X := - V.X;
|
|
Result.Y := - V.Y;
|
|
end;
|
|
|
|
function Average(const V1, V2: TFloatVector): TFloatVector;
|
|
begin
|
|
Result.X := (V1.X + V2.X) * 0.5;
|
|
Result.Y := (V1.Y + V2.Y) * 0.5;
|
|
end;
|
|
|
|
function Max(const V1, V2: TFloatVector): TFloatVector;
|
|
begin
|
|
Result := V1;
|
|
if V2.X > V1.X then Result.X := V2.X;
|
|
if V2.Y > V1.Y then Result.Y := V2.Y;
|
|
end;
|
|
|
|
function Min(const V1, V2: TFloatVector): TFloatVector;
|
|
begin
|
|
Result := V1;
|
|
if V2.X < V1.X then Result.X := V2.X;
|
|
if V2.Y < V1.Y then Result.Y := V2.Y;
|
|
end;
|
|
|
|
function Dot(const V1, V2: TFloatVector): TFloat;
|
|
begin
|
|
Result := V1.X * V2.X + V1.Y * V2.Y;
|
|
end;
|
|
|
|
function Distance(const V1, V2: TFloatVector): TFloat;
|
|
begin
|
|
Result := Hypot(V2.X - V1.X, V2.Y - V1.Y);
|
|
end;
|
|
|
|
function SqrDistance(const V1, V2: TFloatVector): TFloat;
|
|
begin
|
|
Result := Sqr(V2.X - V1.X) + Sqr(V2.Y - V1.Y);
|
|
end;
|
|
|
|
// Fixed overloads
|
|
|
|
function Add(const V1, V2: TFixedVector): TFixedVector;
|
|
begin
|
|
Result.X := V1.X + V2.X;
|
|
Result.Y := V1.Y + V2.Y;
|
|
end;
|
|
|
|
function Add(const V: TFixedVector; Value: TFixed): TFixedVector;
|
|
begin
|
|
Result.X := V.X + Value;
|
|
Result.Y := V.Y + Value;
|
|
end;
|
|
|
|
function Sub(const V1, V2: TFixedVector): TFixedVector;
|
|
begin
|
|
Result.X := V1.X - V2.X;
|
|
Result.Y := V1.Y - V2.Y;
|
|
end;
|
|
|
|
function Sub(const V: TFixedVector; Value: TFixed): TFixedVector;
|
|
begin
|
|
Result.X := V.X - Value;
|
|
Result.Y := V.Y - Value;
|
|
end;
|
|
|
|
function Mul(const V1, V2: TFixedVector): TFixedVector;
|
|
begin
|
|
Result.X := FixedMul(V1.X, V2.X);
|
|
Result.Y := FixedMul(V1.Y, V2.Y);
|
|
end;
|
|
|
|
function Mul(const V: TFixedVector; Multiplier: TFixed): TFixedVector;
|
|
begin
|
|
Result.X := FixedMul(V.X, Multiplier);
|
|
Result.Y := FixedMul(V.Y, Multiplier);
|
|
end;
|
|
|
|
function Divide(const V: TFixedVector; Divisor: TFixed): TFixedVector;
|
|
var
|
|
D: TFloat;
|
|
begin
|
|
D := FIXEDONE / Divisor;
|
|
Result.X := Round(V.X * D);
|
|
Result.Y := Round(V.Y * D);
|
|
end;
|
|
|
|
function Divide(const V1, V2: TFixedVector): TFixedVector;
|
|
begin
|
|
Result.X := FixedDiv(V1.X, V2.X);
|
|
Result.Y := FixedDiv(V1.Y, V2.Y);
|
|
end;
|
|
|
|
function Combine(const V1, V2: TFixedVector; W: TFixed): TFixedVector;
|
|
begin
|
|
Result.X := V2.X + FixedMul(V1.X - V2.X, W);
|
|
Result.Y := V2.Y + FixedMul(V1.Y - V2.Y, W);
|
|
end;
|
|
|
|
function AbsV(const V: TFixedVector): TFixedVector;
|
|
begin
|
|
Result.X := System.Abs(V.X);
|
|
Result.Y := System.Abs(V.Y);
|
|
end;
|
|
|
|
function Neg(const V: TFixedVector): TFixedVector;
|
|
begin
|
|
Result.X := - V.X;
|
|
Result.Y := - V.Y;
|
|
end;
|
|
|
|
function Average(const V1, V2: TFixedVector): TFixedVector;
|
|
begin
|
|
Result.X := (V1.X + V2.X) div 2;
|
|
Result.Y := (V1.Y + V2.Y) div 2;
|
|
end;
|
|
|
|
function Max(const V1, V2: TFixedVector): TFixedVector;
|
|
begin
|
|
Result := V1;
|
|
if V2.X > V1.X then Result.X := V2.X;
|
|
if V2.Y > V1.Y then Result.Y := V2.Y;
|
|
end;
|
|
|
|
function Min(const V1, V2: TFixedVector): TFixedVector;
|
|
begin
|
|
Result := V1;
|
|
if V2.X < V1.X then Result.X := V2.X;
|
|
if V2.Y < V1.Y then Result.Y := V2.Y;
|
|
end;
|
|
|
|
function Dot(const V1, V2: TFixedVector): TFixed;
|
|
begin
|
|
Result := FixedMul(V1.X, V2.X) + FixedMul(V1.Y, V2.Y);
|
|
end;
|
|
|
|
function Distance(const V1, V2: TFixedVector): TFixed;
|
|
begin
|
|
Result := Fixed(Hypot((V2.X - V1.X) * FixedToFloat, (V2.Y - V1.Y) * FixedToFloat));
|
|
end;
|
|
|
|
function SqrDistance(const V1, V2: TFixedVector): TFixed;
|
|
begin
|
|
Result := FixedSqr(V2.X - V1.X) + FixedSqr(V2.Y - V1.Y);
|
|
end;
|
|
|
|
end.
|