Vectors2.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:12k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit Vectors2;
  2. //---------------------------------------------------------------------------
  3. // Vectors2.pas                                         Modified: 02-Feb-2007
  4. // Definitions and functions working with 2D vectors              Version 1.0
  5. //---------------------------------------------------------------------------
  6. // Important Notice:
  7. //
  8. // If you modify/use this code or one of its parts either in original or
  9. // modified form, you must comply with Mozilla Public License v1.1,
  10. // specifically section 3, "Distribution Obligations". Failure to do so will
  11. // result in the license breach, which will be resolved in the court.
  12. // Remember that violating author's rights is considered a serious crime in
  13. // many countries. Thank you!
  14. //
  15. // !! Please *read* Mozilla Public License 1.1 document located at:
  16. //  http://www.mozilla.org/MPL/
  17. //
  18. // If you require any clarifications about the license, feel free to contact
  19. // us or post your question on our forums at: http://www.afterwarp.net
  20. //---------------------------------------------------------------------------
  21. // The contents of this file are subject to the Mozilla Public License
  22. // Version 1.1 (the "License"); you may not use this file except in
  23. // compliance with the License. You may obtain a copy of the License at
  24. // http://www.mozilla.org/MPL/
  25. //
  26. // Software distributed under the License is distributed on an "AS IS"
  27. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  28. // License for the specific language governing rights and limitations
  29. // under the License.
  30. //
  31. // The Original Code is Vectors2.pas.
  32. //
  33. // The Initial Developer of the Original Code is M. Sc. Yuriy Kotsarenko.
  34. // Portions created by M. Sc. Yuriy Kotsarenko are Copyright (C) 2007,
  35. // Afterwarp Interactive. All Rights Reserved.
  36. //---------------------------------------------------------------------------
  37. interface
  38. //---------------------------------------------------------------------------
  39. uses
  40.  Types, Classes, Math, Vectors2px;
  41. //---------------------------------------------------------------------------
  42. type
  43.  PPoint2 = ^TPoint2;
  44.  TPoint2 = record
  45.   x, y: Single;
  46.   class operator Add(const a, b: TPoint2): TPoint2;
  47.   class operator Subtract(const a, b: TPoint2): TPoint2;
  48.   class operator Multiply(const a, b: TPoint2): TPoint2;
  49.   class operator Divide(const a, b: TPoint2): TPoint2;
  50.   class operator Negative(const v: TPoint2): TPoint2;
  51.   class operator Multiply(const v: TPoint2; const k: Single): TPoint2;
  52.   class operator Multiply(const v: TPoint2; const k: Integer): TPoint2;
  53.   class operator Divide(const v: TPoint2; const k: Single): TPoint2;
  54.   class operator Divide(const v: TPoint2; const k: Integer): TPoint2;
  55.   class operator Implicit(const Point: TPoint): TPoint2;
  56.   class operator Implicit(const Point: TPoint2): TPoint;
  57.   class operator Explicit(const Point: TPoint): TPoint2;
  58.   class operator Explicit(const Point: TPoint2): TPoint;
  59.   class operator Implicit(const Point: TPoint2px): TPoint2;
  60.   class operator Implicit(const Point: TPoint2): TPoint2px;
  61.   class operator Explicit(const Point: TPoint2px): TPoint2;
  62.   class operator Explicit(const Point: TPoint2): TPoint2px;
  63.  end;
  64. //---------------------------------------------------------------------------
  65.  TPoints2 = class
  66.  private
  67.   Data: array of TPoint2;
  68.   DataCount: Integer;
  69.   function GetItem(Num: Integer): PPoint2;
  70.   procedure Request(Amount: Integer);
  71.   function GetMemAddr(): Pointer;
  72.  public
  73.   property MemAddr: Pointer read GetMemAddr;
  74.   property Count: Integer read DataCount;
  75.   property Item[Num: Integer]: PPoint2 read GetItem; default;
  76.   function Add(const Point: TPoint2): Integer; overload;
  77.   function Add(x, y: Single): Integer; overload;
  78.   procedure Remove(Index: Integer);
  79.   procedure RemoveAll();
  80.   procedure CopyFrom(Source: TPoints2);
  81.   procedure AddFrom(Source: TPoints2);
  82.   procedure SaveToStream(Stream: TStream);
  83.   procedure LoadFromStream(Stream: TStream);
  84.   constructor Create();
  85.   destructor Destroy(); override;
  86.  end;
  87. //---------------------------------------------------------------------------
  88. const
  89.  ZeroVec2 : TPoint2 = (x: 0.0; y: 0.0);
  90.  UnityVec2: TPoint2 = (x: 1.0; y: 1.0);
  91. //---------------------------------------------------------------------------
  92. function Point2(x, y: Single): TPoint2;
  93. function Length2(const v: TPoint2): Single;
  94. function Norm2(const v: TPoint2): TPoint2;
  95. function Angle2(const v: TPoint2): Single;
  96. function Lerp2(const v0, v1: TPoint2; Alpha: Single): TPoint2;
  97. function Dot2(const a, b: TPoint2): Single;
  98. //---------------------------------------------------------------------------
  99. implementation
  100. //---------------------------------------------------------------------------
  101. const
  102.  CacheSize = 512;
  103. //---------------------------------------------------------------------------
  104. class operator TPoint2.Add(const a, b: TPoint2): TPoint2;
  105. begin
  106.  Result.x:= a.x + b.x;
  107.  Result.y:= a.y + b.y;
  108. end;
  109. //---------------------------------------------------------------------------
  110. class operator TPoint2.Subtract(const a, b: TPoint2): TPoint2;
  111. begin
  112.  Result.x:= a.x - b.x;
  113.  Result.y:= a.y - b.y;
  114. end;
  115. //---------------------------------------------------------------------------
  116. class operator TPoint2.Multiply(const a, b: TPoint2): TPoint2;
  117. begin
  118.  Result.x:= a.x * b.x;
  119.  Result.y:= a.y * b.y;
  120. end;
  121. //---------------------------------------------------------------------------
  122. class operator TPoint2.Divide(const a, b: TPoint2): TPoint2;
  123. begin
  124.  Result.x:= a.x / b.x;
  125.  Result.y:= a.y / b.y;
  126. end;
  127. //---------------------------------------------------------------------------
  128. class operator TPoint2.Negative(const v: TPoint2): TPoint2;
  129. begin
  130.  Result.x:= -v.x;
  131.  Result.y:= -v.y;
  132. end;
  133. //---------------------------------------------------------------------------
  134. class operator TPoint2.Multiply(const v: TPoint2;
  135.  const k: Single): TPoint2;
  136. begin
  137.  Result.x:= v.x * k;
  138.  Result.y:= v.y * k;
  139. end;
  140. //---------------------------------------------------------------------------
  141. class operator TPoint2.Multiply(const v: TPoint2; const k: Integer): TPoint2;
  142. begin
  143.  Result.x:= v.x * k;
  144.  Result.y:= v.y * k;
  145. end;
  146. //---------------------------------------------------------------------------
  147. class operator TPoint2.Divide(const v: TPoint2;
  148.  const k: Single): TPoint2;
  149. begin
  150.  Result.x:= v.x / k;
  151.  Result.y:= v.y / k;
  152. end;
  153. //---------------------------------------------------------------------------
  154. class operator TPoint2.Divide(const v: TPoint2; const k: Integer): TPoint2;
  155. begin
  156.  Result.x:= v.x / k;
  157.  Result.y:= v.y / k;
  158. end;
  159. //---------------------------------------------------------------------------
  160. class operator TPoint2.Implicit(const Point: TPoint): TPoint2;
  161. begin
  162.  Result.x:= Point.X;
  163.  Result.y:= Point.Y;
  164. end;
  165. //---------------------------------------------------------------------------
  166. class operator TPoint2.Implicit(const Point: TPoint2): TPoint;
  167. begin
  168.  Result.X:= Round(Point.x);
  169.  Result.Y:= Round(Point.y);
  170. end;
  171. //---------------------------------------------------------------------------
  172. class operator TPoint2.Explicit(const Point: TPoint): TPoint2;
  173. begin
  174.  Result.x:= Point.X;
  175.  Result.y:= Point.Y;
  176. end;
  177. //---------------------------------------------------------------------------
  178. class operator TPoint2.Explicit(const Point: TPoint2): TPoint;
  179. begin
  180.  Result.X:= Round(Point.x);
  181.  Result.Y:= Round(Point.y);
  182. end;
  183. //---------------------------------------------------------------------------
  184. class operator TPoint2.Implicit(const Point: TPoint2px): TPoint2;
  185. begin
  186.  Result.x:= Point.X;
  187.  Result.y:= Point.Y;
  188. end;
  189. //---------------------------------------------------------------------------
  190. class operator TPoint2.Implicit(const Point: TPoint2): TPoint2px;
  191. begin
  192.  Result.X:= Round(Point.x);
  193.  Result.Y:= Round(Point.y);
  194. end;
  195. //---------------------------------------------------------------------------
  196. class operator TPoint2.Explicit(const Point: TPoint2px): TPoint2;
  197. begin
  198.  Result.x:= Point.X;
  199.  Result.y:= Point.Y;
  200. end;
  201. //---------------------------------------------------------------------------
  202. class operator TPoint2.Explicit(const Point: TPoint2): TPoint2px;
  203. begin
  204.  Result.X:= Round(Point.x);
  205.  Result.Y:= Round(Point.y);
  206. end;
  207. //---------------------------------------------------------------------------
  208. function Length2(const v: TPoint2): Single;
  209. begin
  210.  Result:= Hypot(v.x, v.y);
  211. end;
  212. //---------------------------------------------------------------------------
  213. function Norm2(const v: TPoint2): TPoint2;
  214. var
  215.  Amp: Single;
  216. begin
  217.  Amp:= Length2(v);
  218.  if (Amp <> 0.0) then
  219.   begin
  220.    Result.x:= v.x / Amp;
  221.    Result.y:= v.y / Amp;
  222.   end else Result:= ZeroVec2;
  223. end;
  224. //---------------------------------------------------------------------------
  225. function Point2(x, y: Single): TPoint2;
  226. begin
  227.  Result.x:= x;
  228.  Result.y:= y;
  229. end;
  230. //---------------------------------------------------------------------------
  231. function Angle2(const v: TPoint2): Single;
  232. begin
  233.  Result:= ArcTan2(v.y, v.x);
  234. end;
  235. //---------------------------------------------------------------------------
  236. function Lerp2(const v0, v1: TPoint2; Alpha: Single): TPoint2;
  237. begin
  238.  Result.x:= v0.x + (v1.x - v0.x) * Alpha;
  239.  Result.y:= v0.y + (v1.y - v0.y) * Alpha;
  240. end;
  241. //---------------------------------------------------------------------------
  242. function Dot2(const a, b: TPoint2): Single;
  243. begin
  244.  Result:= (a.x * b.x) + (a.y * b.y);
  245. end;
  246. //---------------------------------------------------------------------------
  247. constructor TPoints2.Create();
  248. begin
  249.  inherited;
  250.  DataCount:= 0;
  251. end;
  252. //---------------------------------------------------------------------------
  253. destructor TPoints2.Destroy();
  254. begin
  255.  DataCount:= 0;
  256.  SetLength(Data, 0);
  257.  inherited;
  258. end;
  259. //---------------------------------------------------------------------------
  260. function TPoints2.GetMemAddr(): Pointer;
  261. begin
  262.  Result:= @Data[0];
  263. end;
  264. //---------------------------------------------------------------------------
  265. function TPoints2.GetItem(Num: Integer): PPoint2;
  266. begin
  267.  if (Num >= 0)and(Num < DataCount) then Result:= @Data[Num]
  268.   else Result:= nil;
  269. end;
  270. //---------------------------------------------------------------------------
  271. procedure TPoints2.Request(Amount: Integer);
  272. var
  273.  Required: Integer;
  274. begin
  275.  Required:= Ceil(Amount / CacheSize) * CacheSize;
  276.  if (Length(Data) < Required) then SetLength(Data, Required);
  277. end;
  278. //---------------------------------------------------------------------------
  279. function TPoints2.Add(const Point: TPoint2): Integer;
  280. var
  281.  Index: Integer;
  282. begin
  283.  Index:= DataCount;
  284.  Request(DataCount + 1);
  285.  Data[Index]:= Point;
  286.  Inc(DataCount);
  287.  Result:= Index;
  288. end;
  289. //---------------------------------------------------------------------------
  290. function TPoints2.Add(x, y: Single): Integer;
  291. begin
  292.  Result:= Add(Point2(x, y));
  293. end;
  294. //---------------------------------------------------------------------------
  295. procedure TPoints2.Remove(Index: Integer);
  296. var
  297.  i: Integer;
  298. begin
  299.  if (Index < 0)or(Index >= DataCount) then Exit;
  300.  for i:= Index to DataCount - 2 do
  301.   Data[i]:= Data[i + 1];
  302.  Dec(DataCount);
  303. end;
  304. //---------------------------------------------------------------------------
  305. procedure TPoints2.RemoveAll();
  306. begin
  307.  DataCount:= 0;
  308. end;
  309. //---------------------------------------------------------------------------
  310. procedure TPoints2.CopyFrom(Source: TPoints2);
  311. var
  312.  i: Integer;
  313. begin
  314.  Request(Source.DataCount);
  315.  for i:= 0 to Source.DataCount - 1 do
  316.   Data[i]:= Source.Data[i];
  317.  DataCount:= Source.DataCount;
  318. end;
  319. //---------------------------------------------------------------------------
  320. procedure TPoints2.AddFrom(Source: TPoints2);
  321. var
  322.  i: Integer;
  323. begin
  324.  Request(DataCount + Source.DataCount);
  325.  for i:= 0 to Source.DataCount - 1 do
  326.   Data[i + DataCount]:= Source.Data[i];
  327.  Inc(DataCount, Source.DataCount);
  328. end;
  329. //---------------------------------------------------------------------------
  330. procedure TPoints2.SaveToStream(Stream: TStream);
  331. begin
  332.  Stream.WriteBuffer(DataCount, SizeOf(Integer));
  333.  Stream.WriteBuffer(Data[0], DataCount * SizeOf(TPoint2));
  334. end;
  335. //---------------------------------------------------------------------------
  336. procedure TPoints2.LoadFromStream(Stream: TStream);
  337. begin
  338.  Stream.ReadBuffer(DataCount, SizeOf(Integer));
  339.  Request(DataCount);
  340.  Stream.ReadBuffer(Data[0], DataCount * SizeOf(TPoint2));
  341. end;
  342. //---------------------------------------------------------------------------
  343. end.