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.
RnQ/for.RnQ/Graphics32/GR32_Geometry.pas

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.