source: trunk/Packages/Graphics32/GR32_ArrowHeads.pas

Last change on this file was 2, checked in by chronos, 5 years ago
File size: 5.2 KB
Line 
1unit GR32_ArrowHeads;
2
3(* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1 or LGPL 2.1 with linking exception
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * Alternatively, the contents of this file may be used under the terms of the
17 * Free Pascal modified version of the GNU Lesser General Public License
18 * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
19 * of this license are applicable instead of those above.
20 * Please see the file LICENSE.txt for additional information concerning this
21 * license.
22 *
23 * The Original Code is Vectorial Polygon Rasterizer for Graphics32
24 *
25 * The Initial Developer of the Original Code is
26 * Angus Johnson < http://www.angusj.com >
27 *
28 * Portions created by the Initial Developer are Copyright (C) 2012
29 * the Initial Developer. All Rights Reserved.
30 *
31 * Contributor(s):
32 *
33 * ***** END LICENSE BLOCK ***** *)
34
35interface
36
37uses
38 SysUtils, GR32, GR32_Polygons, GR32_VectorUtils, GR32_Geometry;
39
40type
41 TArrowHeadAbstract = class
42 private
43 FSize: TFloat;
44 FTipPoint: TFloatPoint;
45 FBasePoint: TFloatPoint;
46 protected
47 function GetPointsInternal: TArrayOfFloatPoint; virtual; abstract;
48 public
49 constructor Create(size: TFloat); virtual;
50 function GetPoints(const Line: TArrayOfFloatPoint; AtEnd: Boolean): TArrayOfFloatPoint;
51 //Size: distance between arrow tip and arrow base
52 property Size: TFloat read FSize write FSize;
53 end;
54
55 TArrowHeadSimple = class(TArrowHeadAbstract)
56 protected
57 function GetPointsInternal: TArrayOfFloatPoint; override;
58 end;
59
60 TArrowHeadFourPt = class(TArrowHeadAbstract)
61 protected
62 function GetPointsInternal: TArrayOfFloatPoint; override;
63 end;
64
65 TArrowHeadCircle = class(TArrowHeadAbstract)
66 protected
67 function GetPointsInternal: TArrayOfFloatPoint; override;
68 end;
69
70 TArrowHeadDiamond = class(TArrowHeadAbstract)
71 protected
72 function GetPointsInternal: TArrayOfFloatPoint; override;
73 end;
74
75
76resourcestring
77 RCStrInsufficientPointsInArray = 'Insufficient points in array';
78
79implementation
80
81constructor TArrowHeadAbstract.Create(Size: TFloat);
82begin
83 FSize := Size;
84end;
85//------------------------------------------------------------------------------
86
87function TArrowHeadAbstract.GetPoints(const Line: TArrayOfFloatPoint;
88 AtEnd: Boolean): TArrayOfFloatPoint;
89var
90 HighI: Integer;
91 UnitVec: TFloatPoint;
92begin
93 HighI := high(Line);
94 if HighI < 1 then
95 raise exception.create(RCStrInsufficientPointsInArray);
96
97 if AtEnd then
98 begin
99 FBasePoint := Line[HighI];
100 UnitVec := GetUnitVector(Line[HighI -1], Line[HighI]);
101 end else
102 begin
103 FBasePoint := Line[0];
104 UnitVec := GetUnitVector(Line[1], Line[0]);
105 end;
106 FTipPoint := OffsetPoint(FBasePoint, UnitVec.X * FSize, UnitVec.Y * FSize);
107 Result := GetPointsInternal;
108end;
109//------------------------------------------------------------------------------
110
111function TArrowHeadSimple.GetPointsInternal: TArrayOfFloatPoint;
112var
113 UnitNorm: TFloatPoint;
114 Sz: Single;
115begin
116 SetLength(Result, 3);
117 UnitNorm := GetUnitNormal(FTipPoint, FBasePoint);
118 Sz := FSize * 0.5;
119 Result[0] := FTipPoint;
120 Result[1] := OffsetPoint(FBasePoint, UnitNorm.X *Sz, UnitNorm.Y *Sz);
121 Result[2] := OffsetPoint(FBasePoint, -UnitNorm.X *Sz, -UnitNorm.Y *Sz);
122end;
123//------------------------------------------------------------------------------
124
125function TArrowHeadFourPt.GetPointsInternal: TArrayOfFloatPoint;
126var
127 Angle: Double;
128begin
129 SetLength(Result, 4);
130 Result[0] := FTipPoint;
131 Angle := GetAngleOfPt2FromPt1(FTipPoint, FBasePoint);
132 Result[1] := GetPointAtAngleFromPoint(FBasePoint, FSize * 0.5, Angle + CRad60);
133 Result[2] := FBasePoint;
134 Result[3] := GetPointAtAngleFromPoint(FBasePoint, FSize * 0.5, Angle - CRad60);
135end;
136//------------------------------------------------------------------------------
137
138function TArrowHeadCircle.GetPointsInternal: TArrayOfFloatPoint;
139var
140 MidPt: TFloatPoint;
141begin
142 MidPt := Average(FTipPoint, FBasePoint);
143 Result := Circle(MidPt.X, MidPt.Y, FSize * 0.5, Round(FSize));
144end;
145//------------------------------------------------------------------------------
146
147function TArrowHeadDiamond.GetPointsInternal: TArrayOfFloatPoint;
148var
149 MidPt, UnitNorm: TFloatPoint;
150 Sz: Single;
151begin
152 MidPt := Average(FTipPoint, FBasePoint);
153 UnitNorm := GetUnitNormal(FTipPoint, FBasePoint);
154 Sz := FSize / 3;
155 SetLength(Result, 4);
156 Result[0] := FTipPoint;
157 Result[1] := OffsetPoint(MidPt, UnitNorm.X * Sz, UnitNorm.Y * Sz);
158 Result[2] := FBasePoint;
159 Result[3] := OffsetPoint(MidPt, -UnitNorm.X * Sz, -UnitNorm.Y * Sz);
160end;
161//------------------------------------------------------------------------------
162
163end.
Note: See TracBrowser for help on using the repository browser.