@armyc2.c5isr.renderer/mil-sym-ts-web 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +57 -0
  3. package/buildNode.bat +2 -0
  4. package/buildWeb.bat +2 -0
  5. package/dist/C5Ren.d.ts +6970 -0
  6. package/dist/C5Ren.js +2 -0
  7. package/dist/C5Ren.js.map +1 -0
  8. package/dist/LICENSE +201 -0
  9. package/dist/README.md +57 -0
  10. package/dist/armyc2.c5isr.renderer-mil-sym-ts-web-2.2.0.tgz +0 -0
  11. package/dist/manifest.json +4 -0
  12. package/dist/package.json +16 -0
  13. package/index.ts +169 -0
  14. package/package.bak +50 -0
  15. package/package.json +40 -0
  16. package/package.node.json +43 -0
  17. package/package.pack.json +19 -0
  18. package/package.packWeb.json +16 -0
  19. package/package.web.json +40 -0
  20. package/src/main/ts/android/graphics/Bitmap.ts +7 -0
  21. package/src/main/ts/android/graphics/Paint.ts +26 -0
  22. package/src/main/ts/android/graphics/Path.ts +78 -0
  23. package/src/main/ts/android/graphics/PointF.ts +14 -0
  24. package/src/main/ts/android/graphics/Rect.ts +18 -0
  25. package/src/main/ts/android/graphics/RectF.ts +50 -0
  26. package/src/main/ts/android/graphics/Region.ts +36 -0
  27. package/src/main/ts/android/graphics/Typeface.ts +11 -0
  28. package/src/main/ts/armyc2/c5isr/JavaLineArray/BasicShapes.ts +99 -0
  29. package/src/main/ts/armyc2/c5isr/JavaLineArray/CChannelPoints2.ts +34 -0
  30. package/src/main/ts/armyc2/c5isr/JavaLineArray/CELineArray.ts +193 -0
  31. package/src/main/ts/armyc2/c5isr/JavaLineArray/Channels.ts +2971 -0
  32. package/src/main/ts/armyc2/c5isr/JavaLineArray/DISMSupport.ts +4008 -0
  33. package/src/main/ts/armyc2/c5isr/JavaLineArray/POINT2.ts +93 -0
  34. package/src/main/ts/armyc2/c5isr/JavaLineArray/Shape2.ts +89 -0
  35. package/src/main/ts/armyc2/c5isr/JavaLineArray/TacticalLines.ts +515 -0
  36. package/src/main/ts/armyc2/c5isr/JavaLineArray/arraysupport.ts +5403 -0
  37. package/src/main/ts/armyc2/c5isr/JavaLineArray/countsupport.ts +1084 -0
  38. package/src/main/ts/armyc2/c5isr/JavaLineArray/flot.ts +2173 -0
  39. package/src/main/ts/armyc2/c5isr/JavaLineArray/lineutility.ts +4934 -0
  40. package/src/main/ts/armyc2/c5isr/JavaLineArray/ref.ts +7 -0
  41. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/Modifier2.ts +5601 -0
  42. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/P1.ts +14 -0
  43. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/TGLight.ts +648 -0
  44. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsChannelUtility.ts +647 -0
  45. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsMETOC.ts +2994 -0
  46. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsUtility.ts +2663 -0
  47. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/mdlGeodesic.ts +669 -0
  48. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipPolygon2.ts +971 -0
  49. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipQuad.ts +871 -0
  50. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer.ts +3507 -0
  51. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer2.ts +500 -0
  52. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtility.ts +1089 -0
  53. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityCPOF.ts +2656 -0
  54. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityGE.ts +1419 -0
  55. package/src/main/ts/armyc2/c5isr/data/genc.json +1407 -0
  56. package/src/main/ts/armyc2/c5isr/data/msd.json +17311 -0
  57. package/src/main/ts/armyc2/c5isr/data/mse.json +18500 -0
  58. package/src/main/ts/armyc2/c5isr/data/svgd.json +31214 -0
  59. package/src/main/ts/armyc2/c5isr/data/svge.json +30558 -0
  60. package/src/main/ts/armyc2/c5isr/graphics2d/AffineTransform.ts +10 -0
  61. package/src/main/ts/armyc2/c5isr/graphics2d/Area.ts +437 -0
  62. package/src/main/ts/armyc2/c5isr/graphics2d/BasicStroke.ts +429 -0
  63. package/src/main/ts/armyc2/c5isr/graphics2d/BasicTypes.ts +7 -0
  64. package/src/main/ts/armyc2/c5isr/graphics2d/BufferedImage.ts +35 -0
  65. package/src/main/ts/armyc2/c5isr/graphics2d/Font.ts +111 -0
  66. package/src/main/ts/armyc2/c5isr/graphics2d/FontMetrics.ts +29 -0
  67. package/src/main/ts/armyc2/c5isr/graphics2d/FontRenderContext.ts +18 -0
  68. package/src/main/ts/armyc2/c5isr/graphics2d/GeneralPath.ts +211 -0
  69. package/src/main/ts/armyc2/c5isr/graphics2d/Graphics2D.ts +80 -0
  70. package/src/main/ts/armyc2/c5isr/graphics2d/IPathIterator.ts +33 -0
  71. package/src/main/ts/armyc2/c5isr/graphics2d/ImageIO.ts +16 -0
  72. package/src/main/ts/armyc2/c5isr/graphics2d/Line2D.ts +726 -0
  73. package/src/main/ts/armyc2/c5isr/graphics2d/PathIterator.ts +141 -0
  74. package/src/main/ts/armyc2/c5isr/graphics2d/Point.ts +112 -0
  75. package/src/main/ts/armyc2/c5isr/graphics2d/Point2D.ts +261 -0
  76. package/src/main/ts/armyc2/c5isr/graphics2d/Polygon.ts +391 -0
  77. package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle.ts +567 -0
  78. package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle2D.ts +445 -0
  79. package/src/main/ts/armyc2/c5isr/graphics2d/Shape.ts +31 -0
  80. package/src/main/ts/armyc2/c5isr/graphics2d/Stroke.ts +18 -0
  81. package/src/main/ts/armyc2/c5isr/graphics2d/TextLayout.ts +45 -0
  82. package/src/main/ts/armyc2/c5isr/graphics2d/TexturePaint.ts +25 -0
  83. package/src/main/ts/armyc2/c5isr/renderer/IIconRenderer.ts +15 -0
  84. package/src/main/ts/armyc2/c5isr/renderer/IconRenderer.ts +22 -0
  85. package/src/main/ts/armyc2/c5isr/renderer/MilStdIconRenderer.ts +269 -0
  86. package/src/main/ts/armyc2/c5isr/renderer/ModifierRenderer.ts +9882 -0
  87. package/src/main/ts/armyc2/c5isr/renderer/PatternFillRenderer.ts +146 -0
  88. package/src/main/ts/armyc2/c5isr/renderer/SinglePointSVGRenderer.ts +1265 -0
  89. package/src/main/ts/armyc2/c5isr/renderer/shapes/arc.ts +64 -0
  90. package/src/main/ts/armyc2/c5isr/renderer/shapes/bcurve.ts +95 -0
  91. package/src/main/ts/armyc2/c5isr/renderer/shapes/ellipse.ts +93 -0
  92. package/src/main/ts/armyc2/c5isr/renderer/shapes/line.ts +114 -0
  93. package/src/main/ts/armyc2/c5isr/renderer/shapes/path.ts +555 -0
  94. package/src/main/ts/armyc2/c5isr/renderer/shapes/pathiterator.ts +62 -0
  95. package/src/main/ts/armyc2/c5isr/renderer/shapes/point.ts +120 -0
  96. package/src/main/ts/armyc2/c5isr/renderer/shapes/rectangle.ts +431 -0
  97. package/src/main/ts/armyc2/c5isr/renderer/shapes/roundedrectangle.ts +99 -0
  98. package/src/main/ts/armyc2/c5isr/renderer/shapes/types.ts +25 -0
  99. package/src/main/ts/armyc2/c5isr/renderer/shapes/utilities.ts +203 -0
  100. package/src/main/ts/armyc2/c5isr/renderer/utilities/AffiliationColors.ts +104 -0
  101. package/src/main/ts/armyc2/c5isr/renderer/utilities/Color.ts +481 -0
  102. package/src/main/ts/armyc2/c5isr/renderer/utilities/DistanceUnit.ts +40 -0
  103. package/src/main/ts/armyc2/c5isr/renderer/utilities/DrawRules.ts +1323 -0
  104. package/src/main/ts/armyc2/c5isr/renderer/utilities/EntityCode.ts +51 -0
  105. package/src/main/ts/armyc2/c5isr/renderer/utilities/ErrorLogger.ts +736 -0
  106. package/src/main/ts/armyc2/c5isr/renderer/utilities/GENCLookup.ts +106 -0
  107. package/src/main/ts/armyc2/c5isr/renderer/utilities/GeoPixelConversion3D.ts +84 -0
  108. package/src/main/ts/armyc2/c5isr/renderer/utilities/IMultiPointRenderer.ts +87 -0
  109. package/src/main/ts/armyc2/c5isr/renderer/utilities/IPointConversion.ts +34 -0
  110. package/src/main/ts/armyc2/c5isr/renderer/utilities/ImageInfo.ts +324 -0
  111. package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUCache.ts +127 -0
  112. package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUEntry.ts +18 -0
  113. package/src/main/ts/armyc2/c5isr/renderer/utilities/LogLevel.ts +111 -0
  114. package/src/main/ts/armyc2/c5isr/renderer/utilities/MODrawRules.ts +219 -0
  115. package/src/main/ts/armyc2/c5isr/renderer/utilities/MSInfo.ts +1008 -0
  116. package/src/main/ts/armyc2/c5isr/renderer/utilities/MSLookup.ts +882 -0
  117. package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdAttributes.ts +380 -0
  118. package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdSymbol.ts +797 -0
  119. package/src/main/ts/armyc2/c5isr/renderer/utilities/Modifiers.ts +1699 -0
  120. package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversion.ts +178 -0
  121. package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversionDummy.ts +45 -0
  122. package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConverter3D.ts +126 -0
  123. package/src/main/ts/armyc2/c5isr/renderer/utilities/RectUtilities.ts +118 -0
  124. package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererException.ts +11 -0
  125. package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererSettings.ts +1201 -0
  126. package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererUtilities.ts +591 -0
  127. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGInfo.ts +29 -0
  128. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGLookup.ts +753 -0
  129. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGSymbolInfo.ts +137 -0
  130. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGTextInfo.ts +438 -0
  131. package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEvent.ts +19 -0
  132. package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEventListener.ts +10 -0
  133. package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsEventListener.ts +5 -0
  134. package/src/main/ts/armyc2/c5isr/renderer/utilities/Shape2SVG.ts +404 -0
  135. package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeInfo.ts +525 -0
  136. package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeUtilities.ts +55 -0
  137. package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolDimensionInfo.ts +36 -0
  138. package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolID.ts +1055 -0
  139. package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolUtilities.ts +2085 -0
  140. package/src/main/ts/armyc2/c5isr/renderer/utilities/TextInfo.ts +157 -0
  141. package/src/main/ts/armyc2/c5isr/web/render/GeoPixelConversion.ts +86 -0
  142. package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandler.ts +3798 -0
  143. package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandlerSVG.ts +412 -0
  144. package/src/main/ts/armyc2/c5isr/web/render/PointConverter.ts +124 -0
  145. package/src/main/ts/armyc2/c5isr/web/render/SymbolModifiers.ts +26 -0
  146. package/src/main/ts/armyc2/c5isr/web/render/WebRenderer.ts +677 -0
  147. package/src/main/ts/armyc2/c5isr/web/render/utilities/JavaRendererUtilities.ts +484 -0
  148. package/src/main/ts/armyc2/c5isr/web/render/utilities/LineInfo.ts +62 -0
  149. package/src/main/ts/armyc2/c5isr/web/render/utilities/SymbolInfo.ts +46 -0
  150. package/src/main/ts/armyc2/c5isr/web/render/utilities/TextInfo.ts +51 -0
  151. package/src/main/ts/org/gavaghan/geodesy/Angle.ts +31 -0
  152. package/src/main/ts/org/gavaghan/geodesy/Ellipsoid.ts +71 -0
  153. package/src/main/ts/org/gavaghan/geodesy/GeodeticCalculator.ts +200 -0
  154. package/src/main/ts/org/gavaghan/geodesy/GeodeticCurve.ts +55 -0
  155. package/src/main/ts/org/gavaghan/geodesy/GeodeticMeasurement.ts +68 -0
  156. package/src/main/ts/org/gavaghan/geodesy/GlobalCoordinates.ts +103 -0
  157. package/src/main/ts/org/gavaghan/geodesy/GlobalPosition.ts +90 -0
  158. package/test/ExportSPImages.js +692 -0
  159. package/test/MPWW.html +556 -0
  160. package/test/MPWorker.js +318 -0
  161. package/test/SPWorker.js +233 -0
  162. package/test/SVGWW.html +363 -0
  163. package/test/singlePointTester3.html +751 -0
  164. package/tsconfig.json +54 -0
  165. package/typedoc.json +30 -0
  166. package/updateVersion.js +21 -0
  167. package/webpack.config.js +34 -0
  168. package/webpackn.config.js +28 -0
  169. package/webpackr.config.js +47 -0
  170. package/webpackw.config.js +23 -0
@@ -0,0 +1,4934 @@
1
+ import { type int, type double, type long } from "../graphics2d/BasicTypes";
2
+
3
+ import { GeneralPath } from "../graphics2d/GeneralPath"
4
+ import { PathIterator } from "../graphics2d/PathIterator"
5
+ import { Point } from "../graphics2d/Point"
6
+ import { Point2D } from "../graphics2d/Point2D"
7
+ import { Shape } from "../graphics2d/Shape"
8
+ import { arraysupport } from "../JavaLineArray/arraysupport"
9
+ import { POINT2 } from "../JavaLineArray/POINT2"
10
+ import { ref } from "../JavaLineArray/ref"
11
+ import { Shape2 } from "../JavaLineArray/Shape2"
12
+ import { TacticalLines } from "../JavaLineArray/TacticalLines"
13
+ import { mdlGeodesic } from "../JavaTacticalRenderer/mdlGeodesic"
14
+ import { TGLight } from "../JavaTacticalRenderer/TGLight"
15
+ import { ErrorLogger } from "../renderer/utilities/ErrorLogger"
16
+ import { IPointConversion } from "../renderer/utilities/IPointConversion"
17
+ import { RendererException } from "../renderer/utilities/RendererException"
18
+ import { IPathIterator } from "../graphics2d/IPathIterator";
19
+
20
+
21
+ /**
22
+ * A class to provide the utility functions required for calculating the line
23
+ * points.
24
+ *
25
+ *
26
+ */
27
+ export class lineutility {
28
+
29
+ private static readonly _className: string = "lineutility";
30
+ public static readonly extend_left: int = 0;
31
+ public static readonly extend_right: int = 1;
32
+ public static readonly extend_above: int = 2;
33
+ public static readonly extend_below: int = 3;
34
+
35
+ /**
36
+ * Resizes the array to the length speicifed, called by the Channels class.
37
+ *
38
+ * @param pLinePoints the array to resize
39
+ * @param length the length to which to resize the array.
40
+ * @return the resized array
41
+ */
42
+ static ResizeArray(pLinePoints: POINT2[], length: int): POINT2[] {
43
+ let array: POINT2[] = new Array<POINT2>(length);
44
+ try {
45
+ if (pLinePoints.length <= length) {
46
+ return pLinePoints;
47
+ }
48
+
49
+ let j: int = 0;
50
+ for (j = 0; j < length; j++) {
51
+ array[j] = new POINT2(pLinePoints[j]);
52
+ }
53
+ } catch (exc) {
54
+ if (exc instanceof Error) {
55
+ ErrorLogger.LogException(lineutility._className, "ResizeArray",
56
+ new RendererException("Failed inside ResizeArray", exc));
57
+ } else {
58
+ throw exc;
59
+ }
60
+ }
61
+ return array;
62
+ }
63
+
64
+ /**
65
+ * post-segments a line segment into 50 pixel intervals
66
+ *
67
+ * @param pt0
68
+ * @param pt1
69
+ * @param shape
70
+ */
71
+ protected static SegmentLineShape(pt0: POINT2, pt1: POINT2, shape: Shape2): void {
72
+ try {
73
+ if (pt0 == null || pt1 == null) {
74
+ return;
75
+ }
76
+
77
+ let j: int = 0;
78
+ let n: int = 0;
79
+ let dist: double = lineutility.CalcDistanceDouble(pt0, pt1);
80
+ n = Math.trunc(dist / 25);
81
+ let pt: POINT2;
82
+ shape.lineTo(pt0);
83
+ for (j = 1; j <= n; j++) {
84
+ pt = lineutility.ExtendAlongLineDouble(pt0, pt1, 25);
85
+ shape.lineTo(pt);
86
+ }
87
+ shape.lineTo(pt1);
88
+ } catch (exc) {
89
+ if (exc instanceof Error) {
90
+ ErrorLogger.LogException(lineutility._className, "SegmentLineShape",
91
+ new RendererException("Failed inside SegmentLineShape", exc));
92
+ } else {
93
+ throw exc;
94
+ }
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Calculates the middle segment for the Direction of Attack Aviation symbol
100
+ *
101
+ * @param pLinePoints the point array
102
+ * @param vblSaveCounter the size of the point array
103
+ * @return the middle segment
104
+ */
105
+ public static GetDirAtkAirMiddleSegment(pLinePoints: POINT2[],
106
+ vblSaveCounter: int): int {
107
+ let middleSegment: int = -1;
108
+ try {
109
+ let d: double = 0;
110
+ let k: int = 0;
111
+ for (k = vblSaveCounter - 1; k > 0; k--) {
112
+ d += lineutility.CalcDistanceDouble(pLinePoints[k], pLinePoints[k - 1]);
113
+ if (d > 60) {
114
+ break;
115
+ }
116
+ }
117
+ if (d > 60) {
118
+ middleSegment = k;
119
+ } else {
120
+ if (vblSaveCounter <= 3) {
121
+ middleSegment = 1;
122
+ } else {
123
+ middleSegment = 2;
124
+ }
125
+ }
126
+ } catch (exc) {
127
+ if (exc instanceof Error) {
128
+ ErrorLogger.LogException(lineutility._className, "GetDirAtkAirMiddleSegment",
129
+ new RendererException("Failed inside GetDirAtkAirMiddleSegment", exc));
130
+ } else {
131
+ throw exc;
132
+ }
133
+ }
134
+ return middleSegment;
135
+ }
136
+
137
+ /**
138
+ * Computes the angle in radians between two points
139
+ *
140
+ * @param pt0 the first point
141
+ * @param pt1 the last point
142
+ *
143
+ * @return the angle in radians
144
+ */
145
+ static CalcSegmentAngleDouble(pt0: POINT2,
146
+ pt1: POINT2): double {
147
+ let dAngle: double = 0;
148
+ try {
149
+ //declarations
150
+ let nTemp: int = 0;
151
+ let m: ref<number[]> = new ref();
152
+ //end declarations
153
+
154
+ nTemp = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
155
+ if (nTemp === 0) {
156
+ dAngle = Math.PI / 2;
157
+ } else {
158
+ dAngle = Math.atan(m.value[0]);
159
+ }
160
+
161
+ } catch (exc) {
162
+ if (exc instanceof Error) {
163
+ ErrorLogger.LogException(lineutility._className, "CalcSegmentAngleDouble",
164
+ new RendererException("Failed inside CalcSegmentAngleDouble", exc));
165
+ } else {
166
+ throw exc;
167
+ }
168
+ }
169
+ return dAngle;
170
+ }
171
+
172
+ /**
173
+ * POINT2 in previous applications has been a struct that did not require
174
+ * initialization.
175
+ *
176
+ * @param pts array of points to instantiate.
177
+ */
178
+ static InitializePOINT2Array(pts: POINT2[]): void {
179
+ //int j=0;
180
+ if (pts == null || pts.length === 0) {
181
+ return;
182
+ }
183
+ let n: int = pts.length;
184
+ //for (int j = 0; j < pts.length; j++)
185
+ for (let j: int = 0; j < n; j++) {
186
+ pts[j] = new POINT2();
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Calculates the center point of an area using the first vblCounter points
192
+ * in the array.
193
+ *
194
+ * @param pLinePoints the client points
195
+ * @param vblCounter the number of points in the array to use
196
+ *
197
+ * @return the center point
198
+ */
199
+ static CalcCenterPointDouble(pLinePoints: POINT2[],
200
+ vblCounter: int): POINT2 {
201
+ let CenterLinePoint: POINT2 = new POINT2(pLinePoints[0]);
202
+ try {
203
+ //declarations
204
+ let j: int = 0;
205
+ let dMinX: double = pLinePoints[0].x;
206
+ let
207
+ dMinY: double = pLinePoints[0].y;
208
+ let
209
+ dMaxX: double = pLinePoints[0].x;
210
+ let
211
+ dMaxY: double = pLinePoints[0].y;
212
+
213
+ //end declarations
214
+ dMinX = pLinePoints[0].x;
215
+ dMinY = pLinePoints[0].y;
216
+ dMaxX = pLinePoints[0].x;
217
+ dMaxY = pLinePoints[0].y;
218
+
219
+ for (j = 0; j < vblCounter; j++) {
220
+ if (pLinePoints[j].x < dMinX) {
221
+ dMinX = pLinePoints[j].x;
222
+ }
223
+
224
+ if (pLinePoints[j].y < dMinY) {
225
+ dMinY = pLinePoints[j].y;
226
+ }
227
+
228
+ if (pLinePoints[j].x > dMaxX) {
229
+ dMaxX = pLinePoints[j].x;
230
+ }
231
+
232
+ if (pLinePoints[j].y > dMaxY) {
233
+ dMaxY = pLinePoints[j].y;
234
+ }
235
+
236
+ } //end for
237
+
238
+ CenterLinePoint.x = (dMinX + dMaxX) / 2;
239
+ CenterLinePoint.y = (dMinY + dMaxY) / 2;
240
+ } catch (exc) {
241
+ if (exc instanceof Error) {
242
+ ErrorLogger.LogException(lineutility._className, "CalcCenterPointDouble",
243
+ new RendererException("Failed inside CalcCenterPointDouble", exc));
244
+ } else {
245
+ throw exc;
246
+ }
247
+ }
248
+ return CenterLinePoint;
249
+ }
250
+
251
+ /**
252
+ * Called by renderer Modifier2 class after ArrayList.ToArray was called,
253
+ * which produces an array of objects.
254
+ *
255
+ * @param pLinePoints
256
+ * @param vblCounter
257
+ * @return
258
+ */
259
+ public static CalcCenterPointDouble2(pLinePoints: POINT2[],
260
+ vblCounter: int): POINT2 {
261
+ let pt0: POINT2 = pLinePoints[0];
262
+ let CenterLinePoint: POINT2 = new POINT2();
263
+ try {
264
+ //declarations
265
+ let j: int = 0;
266
+ let dMinX: double = pt0.x;
267
+ let
268
+ dMinY: double = pt0.y;
269
+ let
270
+ dMaxX: double = pt0.x;
271
+ let
272
+ dMaxY: double = pt0.y;
273
+
274
+ //end declarations
275
+ dMinX = pt0.x;
276
+ dMinY = pt0.y;
277
+ dMaxX = pt0.x;
278
+ dMaxY = pt0.y;
279
+
280
+ let pt: POINT2;
281
+
282
+ for (j = 0; j < vblCounter; j++) {
283
+ pt = pLinePoints[j];
284
+ if (pt.x < dMinX) {
285
+ dMinX = pt.x;
286
+ }
287
+
288
+ if (pt.y < dMinY) {
289
+ dMinY = pt.y;
290
+ }
291
+
292
+ if (pt.x > dMaxX) {
293
+ dMaxX = pt.x;
294
+ }
295
+
296
+ if (pt.y > dMaxY) {
297
+ dMaxY = pt.y;
298
+ }
299
+
300
+ } //end for
301
+
302
+ CenterLinePoint.x = (dMinX + dMaxX) / 2;
303
+ CenterLinePoint.y = (dMinY + dMaxY) / 2;
304
+ } catch (exc) {
305
+ if (exc instanceof Error) {
306
+ ErrorLogger.LogException(lineutility._className, "CalcCenterPointDouble2",
307
+ new RendererException("Failed inside CalcCenterPointDouble2", exc));
308
+ } else {
309
+ throw exc;
310
+ }
311
+ }
312
+ return CenterLinePoint;
313
+ }
314
+
315
+ /**
316
+ * Calculates the distance in pixels between two points
317
+ *
318
+ * @param p1 the first point
319
+ * @param p2 the last point
320
+ *
321
+ * @return the distance between p1 and p2 in pixels
322
+ */
323
+ public static CalcDistanceDouble(p1: POINT2 | Point2D, p2: POINT2 | Point2D): double {
324
+
325
+ let returnValue: double = 0;
326
+ try {
327
+ returnValue = Math.sqrt((p1.getX() - p2.getX())
328
+ * (p1.getX() - p2.getX())
329
+ + (p1.getY() - p2.getY())
330
+ * (p1.getY() - p2.getY()));
331
+
332
+ //sanity check
333
+ //return x or y distance if returnValue is 0 or infinity
334
+ let xdist: double = Math.abs(p1.getX() - p2.getX());
335
+ let ydist: double = Math.abs(p1.getY() - p2.getY());
336
+ let max: double = xdist;
337
+ if (ydist > xdist) {
338
+ max = ydist;
339
+ }
340
+
341
+ if (returnValue === 0 || !Number.isFinite(returnValue)) {
342
+ if (max > 0) {
343
+ returnValue = max;
344
+ }
345
+ }
346
+ } catch (exc) {
347
+ if (exc instanceof Error) {
348
+ ErrorLogger.LogException(lineutility._className, "CalcDistanceDouble",
349
+ new RendererException("Failed inside CalcDistanceDouble", exc));
350
+ } else {
351
+ throw exc;
352
+ }
353
+ }
354
+ return returnValue;
355
+ }
356
+
357
+
358
+ /**
359
+ * Computes the slope of a line
360
+ *
361
+ * @param firstLinePoint the first line point
362
+ * @param lastLinePoint the last line point
363
+ * @param slope OUT - object with member to hold the slope of the line
364
+ *
365
+ * @return 1 if successful, else return 0
366
+ */
367
+ static CalcTrueSlopeDouble(firstLinePoint: POINT2,
368
+ lastLinePoint: POINT2,
369
+ slope: ref<number[]>): int//ref is a double
370
+ {
371
+ let result: int = 1;
372
+ try {
373
+ if (slope.value == null) {
374
+ slope.value = new Array<number>(1);
375
+ }
376
+
377
+ let deltaX: double = 0;
378
+ let deltaY: double = 0;
379
+ deltaX = firstLinePoint.x - lastLinePoint.x;
380
+ //if (deltaX == 0)
381
+ if (Math.abs(deltaX) < 1) {
382
+ //deltaX = 1;
383
+ if (deltaX >= 0) {
384
+
385
+ deltaX = 1;
386
+ }
387
+
388
+ else {
389
+
390
+ deltaX = -1;
391
+ }
392
+
393
+ result = 1;
394
+ }
395
+ deltaY = firstLinePoint.y - lastLinePoint.y;
396
+
397
+ slope.value[0] = deltaY / deltaX; //cannot blow up
398
+ } catch (exc) {
399
+ if (exc instanceof Error) {
400
+ ErrorLogger.LogException(lineutility._className, "CalcTrueSlopeDouble",
401
+ new RendererException("Failed inside CalcTrueSlopeDouble", exc));
402
+ } else {
403
+ throw exc;
404
+ }
405
+ }
406
+ return result;
407
+ }
408
+
409
+ /**
410
+ * reverses the first vblCounter points
411
+ *
412
+ * @param pLowerLinePoints OUT - points to reverse
413
+ * @param vblCounter
414
+ */
415
+ static ReversePointsDouble2(pLowerLinePoints: POINT2[],
416
+ vblCounter: int): void {
417
+ try {
418
+ let pResultPoints: POINT2[] = new Array<POINT2>(vblCounter);
419
+ let k: int = 0;
420
+ for (k = 0; k < vblCounter; k++) {
421
+ pResultPoints[k] = new POINT2(pLowerLinePoints[vblCounter - k - 1]);
422
+ }
423
+ for (k = 0; k < vblCounter; k++) {
424
+ pLowerLinePoints[k] = new POINT2(pResultPoints[k]);
425
+ }
426
+ } catch (exc) {
427
+ if (exc instanceof Error) {
428
+ ErrorLogger.LogException(lineutility._className, "ReversePointsDouble2",
429
+ new RendererException("Failed inside ReversePointsDouble2", exc));
430
+ } else {
431
+ throw exc;
432
+ }
433
+ }
434
+ }
435
+
436
+ public static CalcTrueSlopeDoubleForRoutes(firstLinePoint: POINT2,
437
+ lastLinePoint: POINT2,
438
+ slope: ref<number[]>): boolean {
439
+ try {
440
+ let deltaX: double = 0;
441
+ let deltaY: double = 0;
442
+ deltaX = (firstLinePoint.x) as double - (lastLinePoint.x) as double;
443
+ if (Math.abs(deltaX) < 2) //was 2,infinite slope
444
+ {
445
+ return (false);
446
+ }
447
+
448
+ deltaY = (firstLinePoint.y) as double - (lastLinePoint.y) as double;
449
+ if (slope.value == null) {
450
+ slope.value = new Array<number>(1);
451
+ }
452
+
453
+ slope.value[0] = deltaY / deltaX;
454
+ } catch (exc) {
455
+ if (exc instanceof Error) {
456
+ ErrorLogger.LogException(lineutility._className, "CalcTrueSlopeDoubleForRoutes",
457
+ new RendererException("Failed inside CalcTrueSlopeDoubleForRoutes", exc));
458
+ } else {
459
+ throw exc;
460
+ }
461
+ }
462
+ return true;
463
+ }
464
+
465
+ /**
466
+ * Computes the slope of a line
467
+ *
468
+ * @param firstLinePoint the first line point
469
+ * @param lastLinePoint the last line point
470
+ * @param slope OUT - object with member to hold the slope of the line
471
+ *
472
+ * @return true if successful
473
+ */
474
+ public static CalcTrueSlopeDouble2(firstLinePoint: POINT2,
475
+ lastLinePoint: POINT2,
476
+ slope: ref<number[]>): boolean {
477
+ let result: boolean = true;
478
+ try {
479
+ let deltaX: double = 0;
480
+ let deltaY: double = 0;
481
+ deltaX = (firstLinePoint.x) as double - (lastLinePoint.x) as double;
482
+ //if (deltaX == 0)
483
+ if (Math.abs(deltaX) < 1) {
484
+ //deltaX = 1;
485
+ if (deltaX >= 0) {
486
+
487
+ deltaX = 1;
488
+ }
489
+
490
+ else {
491
+
492
+ deltaX = -1;
493
+ }
494
+
495
+ result = false;
496
+ }
497
+
498
+ deltaY = (firstLinePoint.y) as double - (lastLinePoint.y) as double;
499
+ if (slope.value == null) {
500
+ slope.value = new Array<number>(1);
501
+ }
502
+
503
+ slope.value[0] = deltaY / deltaX;
504
+ } catch (exc) {
505
+ if (exc instanceof Error) {
506
+ ErrorLogger.LogException(lineutility._className, "CalcTrueSlopeDouble2",
507
+ new RendererException("Failed inside CalcTrueSlopeDouble2", exc));
508
+ } else {
509
+ throw exc;
510
+ }
511
+ }
512
+ return result;
513
+ }
514
+
515
+ /**
516
+ * Calculates the slopes and y intercepts in pixels for the line from pt1 to
517
+ * pt2 and a parallel line a vertical distance from the line
518
+ *
519
+ * @param nDistance the distance in pixels
520
+ * @param linePoint1 first point on the line
521
+ * @param linePoint2 last point on the line
522
+ * @param pdResult OUT - array to hold m, b for both lines
523
+ *
524
+ * @return 1 if the lines are not vertical, else return 0
525
+ */
526
+ static CalcTrueLinesDouble(nDistance: number,
527
+ linePoint1: POINT2,
528
+ linePoint2: POINT2,
529
+ pdResult: ref<number[]>): int //for vertical line e.g. if line equation is x=7
530
+ {
531
+ try {
532
+ //declarations
533
+ let nTemp: int = 0;
534
+ let b: double = 0;
535
+ let delta: double = 0;
536
+ let m: ref<number[]> = new ref();
537
+ //end declarations
538
+ nTemp = lineutility.CalcTrueSlopeDouble(linePoint1, linePoint2, m);
539
+ pdResult.value = new Array<number>(6);
540
+ //Fill the result array with the line parameters
541
+ if (nTemp === 0) //vertical lines
542
+ {
543
+ pdResult.value[3] = linePoint1.x + nDistance as double; //the lower line eqn, e.g. x=7
544
+ pdResult.value[5] = linePoint1.x - nDistance as double; //the upper line eqn,
545
+ return 0;
546
+ } else {
547
+ b = linePoint2.y - m.value[0] * linePoint2.x;
548
+ delta = Math.sqrt(m.value[0] * m.value[0] * ((nDistance) as double * (nDistance) as double)
549
+ + ((nDistance) as double * (nDistance) as double));
550
+ pdResult.value[0] = m.value[0]; //original line eq'n: y = mx + b
551
+ pdResult.value[1] = b;
552
+ pdResult.value[2] = m.value[0]; //lower line eq'n: y = mx + (b+dDistance)
553
+ pdResult.value[3] = b + delta;
554
+ pdResult.value[4] = m.value[0]; //upper line eq'n: y = mx + (b-dDistance)
555
+ pdResult.value[5] = b - delta;
556
+ }
557
+ } catch (exc) {
558
+ if (exc instanceof Error) {
559
+ ErrorLogger.LogException(lineutility._className, "CalcTrueLinesDouble",
560
+ new RendererException("Failed inside CalcTrueLinesDouble", exc));
561
+ } else {
562
+ throw exc;
563
+ }
564
+ }
565
+ return 1;
566
+ }
567
+
568
+ /**
569
+ * Calculates the intersection of two lines.
570
+ *
571
+ * @param m1 slope of first line
572
+ * @param b1 Y intercept of first line
573
+ * @param m2 slope of second line
574
+ * @param b2 Y intercept of second line
575
+ * @param bolVertical1 0 if first line is vertical, else 1
576
+ * @param bolVertical2 0 if second line is vertical, else 1
577
+ * @param X1 X intercept if first line is vertical
578
+ * @param X2 X intercept if 2nd line is vertical.
579
+ *
580
+ * @return intersection point
581
+ */
582
+ public static CalcTrueIntersectDouble2(m1: double,
583
+ b1: double,
584
+ m2: double,
585
+ b2: double,
586
+ bolVertical1: int,
587
+ bolVertical2: int,
588
+ X1: double, //x intercept if line1 is vertical
589
+ X2: double): POINT2 {
590
+ let ptIntersect: POINT2 = new POINT2();
591
+ try {
592
+ //declarations
593
+ let x: double = 0;
594
+ let y: double = 0;
595
+ //end declarations
596
+
597
+ //initialize ptIntersect
598
+ ptIntersect.x = X1;
599
+ ptIntersect.y = X2;
600
+ if (bolVertical1 === 0 && bolVertical2 === 0) //both lines vertical
601
+ {
602
+ return ptIntersect;
603
+ }
604
+ //the following 3 if blocks are the only ways to get an intersection
605
+ if (bolVertical1 === 0 && bolVertical2 === 1) //line1 vertical, line2 not
606
+ {
607
+ ptIntersect.x = X1;
608
+ ptIntersect.y = m2 * X1 + b2;
609
+ return ptIntersect;
610
+ }
611
+ if (bolVertical1 === 1 && bolVertical2 === 0) //line2 vertical, line1 not
612
+ {
613
+ ptIntersect.x = X2;
614
+ ptIntersect.y = m1 * X2 + b1;
615
+ return ptIntersect;
616
+ }
617
+ //if either of the lines is vertical function has already returned
618
+ //so both m1 and m2 should be valid
619
+ if (m1 !== m2) {
620
+ x = (b2 - b1) / (m1 - m2); //cannot blow up
621
+ y = (m1 * x + b1);
622
+ ptIntersect.x = x;
623
+ ptIntersect.y = y;
624
+ return ptIntersect;
625
+ }
626
+ } catch (exc) {
627
+ if (exc instanceof Error) {
628
+ ErrorLogger.LogException(lineutility._className, "CalcTrueIntersectDouble2",
629
+ new RendererException("Failed inside CalcTrueIntersectDouble2", exc));
630
+ } else {
631
+ throw exc;
632
+ }
633
+ }
634
+ return ptIntersect;
635
+ }
636
+
637
+ /**
638
+ * Calculates an offset point for channel types which require arrows.
639
+ *
640
+ * @param startLinePoint the first point
641
+ * @param endLinePoint the last point
642
+ * @param nOffset the offset in pixels
643
+ *
644
+ * @return the offset point
645
+ */
646
+ static GetOffsetPointDouble(startLinePoint: POINT2,
647
+ endLinePoint: POINT2,
648
+ nOffset: double): POINT2 {
649
+ let tempLinePoint: POINT2 = new POINT2(startLinePoint);
650
+ try {
651
+ //declarations
652
+ let dx: double = endLinePoint.x - startLinePoint.x;
653
+ let
654
+ dy: double = endLinePoint.y - startLinePoint.y;
655
+ let
656
+ dOffset: double = nOffset;
657
+ let
658
+ dHypotenuse: double = 0;
659
+ let
660
+ dAngle: double = 0;
661
+
662
+ //end declarations
663
+ if (dx === 0) {
664
+ if (dy > 0) {
665
+ tempLinePoint.x = endLinePoint.x;
666
+ tempLinePoint.y = endLinePoint.y + dOffset;
667
+ } else {
668
+ tempLinePoint.x = endLinePoint.x;
669
+ tempLinePoint.y = endLinePoint.y - dOffset;
670
+ }
671
+ return tempLinePoint;
672
+ }
673
+ if (dy === 0) {
674
+ if (dx > 0) {
675
+ tempLinePoint.x = endLinePoint.x + dOffset;
676
+ tempLinePoint.y = endLinePoint.y;
677
+ } else {
678
+ tempLinePoint.x = endLinePoint.x - dOffset;
679
+ tempLinePoint.y = endLinePoint.y;
680
+ }
681
+ return tempLinePoint;
682
+ }
683
+
684
+ if (dy === 0) {
685
+ dAngle = 0;
686
+ } else {
687
+ dAngle = Math.atan(dx / dy) + Math.PI / 2;//1.570795;
688
+ }
689
+ dHypotenuse = nOffset;
690
+ if (endLinePoint.x > startLinePoint.x) {
691
+ tempLinePoint.x = endLinePoint.x + dHypotenuse * Math.abs(Math.cos(dAngle));
692
+ } else {
693
+ tempLinePoint.x = endLinePoint.x - dHypotenuse * Math.abs(Math.cos(dAngle));
694
+ }
695
+ if (endLinePoint.y > startLinePoint.y) {
696
+ tempLinePoint.y = endLinePoint.y + dHypotenuse * Math.abs(Math.sin(dAngle));
697
+ } else {
698
+ tempLinePoint.y = endLinePoint.y - dHypotenuse * Math.abs(Math.sin(dAngle));
699
+ }
700
+
701
+ } catch (exc) {
702
+ if (exc instanceof Error) {
703
+ ErrorLogger.LogException(lineutility._className, "GetOffsetPointDouble",
704
+ new RendererException("Failed inside GetOffsetPointDouble", exc));
705
+ } else {
706
+ throw exc;
707
+ }
708
+ }
709
+ return (tempLinePoint);
710
+ }
711
+
712
+ /**
713
+ * Used for DMAF
714
+ *
715
+ * @param pLinePoints the client points
716
+ * @return ArrayList of X points
717
+ */
718
+ static LineOfXPoints(tg: TGLight, pLinePoints: POINT2[]): Array<POINT2> {
719
+ let xPoints: Array<POINT2> = new Array();
720
+ try {
721
+ let j: int = 0;
722
+ let k: int = 0;
723
+ let dist: double = 0;
724
+ let iterations: int = 0;
725
+ let frontPt: POINT2;
726
+ let backPt: POINT2;
727
+ let extendFrontAbove: POINT2;
728
+ let extendFrontBelow: POINT2;
729
+ let extendBackAbove: POINT2;
730
+ let extendBackBelow: POINT2;
731
+ let xPoint1: POINT2;
732
+ let xPoint2: POINT2;
733
+ let n: int = pLinePoints.length;
734
+ let xSize: double = arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
735
+ let dIncrement: double = xSize * 4;
736
+ //for (j = 0; j < pLinePoints.length - 1; j++)
737
+ for (j = 0; j < n - 1; j++) {
738
+ dist = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
739
+ iterations = Math.trunc((dist - xSize) / dIncrement);
740
+ if (dist - iterations * dIncrement > dIncrement / 2) {
741
+ iterations += 1;
742
+ }
743
+
744
+ for (k = 0; k < iterations; k++) {
745
+ frontPt = lineutility.ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * dIncrement - xSize);
746
+ backPt = lineutility.ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * dIncrement + xSize);
747
+ extendFrontAbove = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], frontPt, 2, xSize);
748
+ extendFrontBelow = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], frontPt, 3, xSize);
749
+ extendBackAbove = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], backPt, 2, xSize);
750
+ extendBackBelow = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], backPt, 3, xSize);
751
+ xPoints.push(extendFrontAbove);
752
+ extendBackBelow.style = 5;
753
+ xPoints.push(extendBackBelow);
754
+ xPoints.push(extendBackAbove);
755
+ extendFrontBelow.style = 5;
756
+ xPoints.push(extendFrontBelow);
757
+ }
758
+ }
759
+ } catch (exc) {
760
+ if (exc instanceof Error) {
761
+ ErrorLogger.LogException(lineutility._className, "LineOfXPoints",
762
+ new RendererException("Failed inside LineOfXPoints", exc));
763
+ } else {
764
+ throw exc;
765
+ }
766
+ }
767
+ return xPoints;
768
+ }
769
+
770
+ /**
771
+ * Computes the distance in pixels of pt3 to the line from pt1 to pt2.
772
+ *
773
+ * @param pt1 first line point
774
+ * @param pt2 last line point
775
+ * @param pt3 point distance to compute
776
+ * @return distance to pt3
777
+ */
778
+ public static CalcDistanceToLineDouble(pt1: POINT2,
779
+ pt2: POINT2,
780
+ pt3: POINT2): double {
781
+ let dResult: double = 0;
782
+ try {
783
+ //declarations
784
+ let m1: double = 1;
785
+ let b: double = 0;
786
+ let b1: double = 0;
787
+ let ptIntersect: POINT2 = new POINT2(pt1);
788
+ let bolVertical: int = 0;
789
+ let m: ref<number[]> = new ref();
790
+ //end declarations
791
+
792
+ bolVertical = lineutility.CalcTrueSlopeDouble(pt1, pt2, m);
793
+
794
+ //get line y intercepts
795
+ if (bolVertical !== 0 && m.value[0] !== 0) {
796
+ m1 = -1 / m.value[0];
797
+ b = pt1.y - m.value[0] * pt1.x;
798
+ b1 = pt3.y - m1 * pt3.x;
799
+ ptIntersect = lineutility.CalcTrueIntersectDouble2(m.value[0], b, m1, b1, 1, 1, ptIntersect.x, ptIntersect.y);
800
+ }
801
+ if (bolVertical !== 0 && m.value[0] === 0) //horizontal line
802
+ {
803
+ ptIntersect.y = pt1.y;
804
+ ptIntersect.x = pt3.x;
805
+ }
806
+ if (bolVertical === 0) //vertical line
807
+ {
808
+ ptIntersect.y = pt3.y;
809
+ ptIntersect.x = pt1.x;
810
+ }
811
+
812
+ dResult = lineutility.CalcDistanceDouble(pt3, ptIntersect);
813
+ } catch (exc) {
814
+ if (exc instanceof Error) {
815
+ //console.log(e.message);
816
+ ErrorLogger.LogException(lineutility._className, "CaclDistanceToLineDouble",
817
+ new RendererException("Failed inside CalcDistanceToLineDouble", exc));
818
+ } else {
819
+ throw exc;
820
+ }
821
+ }
822
+ return dResult;
823
+ }
824
+
825
+ /**
826
+ * Calculates a point along a line. Returns the past point if the distance
827
+ * is 0.
828
+ *
829
+ * @param pt1 first line point
830
+ * @param pt2 last line point
831
+ * @param dist extension distance in pixels from the beginning of the line
832
+ *
833
+ * @return the extension point
834
+ */
835
+ public static ExtendLineDouble(pt1: POINT2,
836
+ pt2: POINT2,
837
+ dist: double): POINT2 {
838
+ let pt3: POINT2 = new POINT2();
839
+ try {
840
+ let dOriginalDistance: double = lineutility.CalcDistanceDouble(pt1, pt2);
841
+ if (dOriginalDistance === 0 || dist === 0) {
842
+ return pt2;
843
+ }
844
+
845
+ pt3.x = (dOriginalDistance + dist) / dOriginalDistance * (pt2.x - pt1.x) + pt1.x;
846
+ pt3.y = (dOriginalDistance + dist) / dOriginalDistance * (pt2.y - pt1.y) + pt1.y;
847
+ } catch (exc) {
848
+ if (exc instanceof Error) {
849
+ //console.log(e.message);
850
+ ErrorLogger.LogException(lineutility._className, "ExtendLineDouble",
851
+ new RendererException("Failed inside ExtendLineDouble", exc));
852
+ } else {
853
+ throw exc;
854
+ }
855
+ }
856
+ return pt3;
857
+ }
858
+
859
+ /**
860
+ * Extends a point along a line. If dist is 0 returns last point.
861
+ *
862
+ * @param pt1 first point on the line
863
+ * @param pt2 last point on the line
864
+ * @param dist the distance in pixels from pt1
865
+ *
866
+ * @return the extended point
867
+ */
868
+ public static ExtendAlongLineDouble(pt1: POINT2, pt2: POINT2, dist: double): POINT2;
869
+
870
+ public static ExtendAlongLineDouble(pt1: POINT2, pt2: POINT2, dist: double, styl: int): POINT2;
871
+ public static ExtendAlongLineDouble(...args: unknown[]): POINT2 {
872
+ switch (args.length) {
873
+ case 3: {
874
+ const [pt1, pt2, dist] = args as [POINT2, POINT2, double];
875
+
876
+
877
+ let pt3: POINT2 = new POINT2();
878
+ try {
879
+ let dOriginalDistance: double = lineutility.CalcDistanceDouble(pt1, pt2);
880
+ if (dOriginalDistance === 0 || dist === 0) {
881
+ return pt2;
882
+ }
883
+
884
+ pt3.x = ((dist / dOriginalDistance) * (pt2.x - pt1.x) + pt1.x);
885
+ pt3.y = ((dist / dOriginalDistance) * (pt2.y - pt1.y) + pt1.y);
886
+ } catch (exc) {
887
+ if (exc instanceof Error) {
888
+ //console.log(e.message);
889
+ ErrorLogger.LogException(lineutility._className, "ExtendAlongLineDouble",
890
+ new RendererException("Failed inside ExtendAlongLineDouble", exc));
891
+ } else {
892
+ throw exc;
893
+ }
894
+ }
895
+ return pt3;
896
+
897
+
898
+ break;
899
+ }
900
+
901
+ case 4: {
902
+ const [pt1, pt2, dist, styl] = args as [POINT2, POINT2, double, int];
903
+
904
+
905
+ let pt3: POINT2 = new POINT2();
906
+ try {
907
+ let dOriginalDistance: double = lineutility.CalcDistanceDouble(pt1, pt2);
908
+ if (dOriginalDistance === 0 || dist === 0) {
909
+ return pt2;
910
+ }
911
+
912
+ pt3.x = (dist / dOriginalDistance * (pt2.x - pt1.x) + pt1.x);
913
+ pt3.y = (dist / dOriginalDistance * (pt2.y - pt1.y) + pt1.y);
914
+ pt3.style = styl;
915
+ } catch (exc) {
916
+ if (exc instanceof Error) {
917
+ //console.log(e.message);
918
+ ErrorLogger.LogException(lineutility._className, "ExtendAlongLineDouble",
919
+ new RendererException("Failed inside ExtendAlongLineDouble", exc));
920
+ } else {
921
+ throw exc;
922
+ }
923
+ }
924
+ return pt3;
925
+
926
+
927
+ break;
928
+ }
929
+
930
+ default: {
931
+ throw Error(`Invalid number of arguments`);
932
+ }
933
+ }
934
+ }
935
+
936
+
937
+ public static ExtendAlongLineDouble2(pt1: POINT2, pt2: POINT2, dist: double): POINT2;
938
+
939
+ public static ExtendAlongLineDouble2(pt1: Point2D, pt2: Point2D, dist: double): Point2D;
940
+ public static ExtendAlongLineDouble2(...args: unknown[]): POINT2 | Point2D {
941
+ if (args[0] instanceof POINT2) {
942
+ const [pt1, pt2, dist] = args as [POINT2, POINT2, double];
943
+
944
+ let pt3: POINT2 = new POINT2();
945
+ try {
946
+ let dOriginalDistance: double = lineutility.CalcDistanceDouble(pt1, pt2);
947
+ if (dOriginalDistance === 0 || dist === 0) {
948
+ return pt1;
949
+ }
950
+
951
+ pt3.x = (dist / dOriginalDistance * (pt2.x - pt1.x) + pt1.x);
952
+ pt3.y = (dist / dOriginalDistance * (pt2.y - pt1.y) + pt1.y);
953
+ } catch (exc) {
954
+ if (exc instanceof Error) {
955
+ //console.log(e.message);
956
+ ErrorLogger.LogException(lineutility._className, "ExtendAlongLineDouble2",
957
+ new RendererException("Failed inside ExtendAlongLineDouble2", exc));
958
+ } else {
959
+ throw exc;
960
+ }
961
+ }
962
+ return pt3;
963
+
964
+ } else {
965
+
966
+ const [pt1, pt2, dist] = args as [Point2D, Point2D, double];
967
+
968
+
969
+ try {
970
+ let dOriginalDistance: double = lineutility.CalcDistanceDouble(pt1, pt2);
971
+ if (dOriginalDistance === 0 || dist === 0) {
972
+ return new Point2D(pt1.getX(), pt1.getY());
973
+ }
974
+
975
+ let x: double = (dist / dOriginalDistance * (pt2.getX() - pt1.getX()) + pt1.getX());
976
+ let y: double = (dist / dOriginalDistance * (pt2.getY() - pt1.getY()) + pt1.getY());
977
+ return new Point2D(x, y);
978
+ } catch (exc) {
979
+ if (exc instanceof Error) {
980
+ ErrorLogger.LogException(lineutility._className, "ExtendAlongLineDouble2",
981
+ new RendererException("Failed inside ExtendAlongLineDouble2", exc));
982
+ } else {
983
+ throw exc;
984
+ }
985
+ }
986
+ return new Point2D(0, 0);
987
+ }
988
+ }
989
+
990
+
991
+ /**
992
+ * Extends a point above a line
993
+ *
994
+ * @param pt1 first line point
995
+ * @param pt2 last line point
996
+ * @param pt3 point at which to extend
997
+ * @param d distance in pixels to extend above the line
998
+ * @param X OUT - extended point x value
999
+ * @param Y OUT - extended point y value
1000
+ * @param direction direction to extend the line
1001
+ *
1002
+ * @return 1 if successful, else return 0
1003
+ */
1004
+ protected static ExtendLineAbove(pt1: POINT2,
1005
+ pt2: POINT2,
1006
+ pt3: POINT2,
1007
+ d: double,
1008
+ X: ref<number[]>,
1009
+ Y: ref<number[]>,
1010
+ direction: int): int {
1011
+ try {
1012
+ let m: ref<number[]> = new ref();
1013
+ let dx: double = 0;
1014
+ let dy: double = 0;
1015
+ let bolVertical: int = 0;
1016
+
1017
+ X.value = new Array<number>(1);
1018
+ Y.value = new Array<number>(1);
1019
+
1020
+ bolVertical = lineutility.CalcTrueSlopeDouble(pt1, pt2, m);
1021
+ if (bolVertical === 0) {
1022
+ return 0; //cannot extend above a vertical line
1023
+ }
1024
+ if (m.value[0] === 0) {
1025
+ X.value[0] = pt3.x;
1026
+ if (direction === 0) //extend above the line
1027
+ {
1028
+ Y.value[0] = pt3.y - Math.abs(d);
1029
+ } else //extend below the line
1030
+ {
1031
+ Y.value[0] = pt3.y + Math.abs(d);
1032
+ }
1033
+ return 1;
1034
+ }
1035
+ //the line is neither vertical nor horizontal
1036
+ //else function would already have returned
1037
+ if (direction === 0) //extend above the line
1038
+ {
1039
+ dy = -Math.abs(d / (m.value[0] * Math.sqrt(1 + 1 / (m.value[0] * m.value[0]))));
1040
+ } else //extend below the line
1041
+ {
1042
+ dy = Math.abs(d / (m.value[0] * Math.sqrt(1 + 1 / (m.value[0] * m.value[0]))));
1043
+ }
1044
+
1045
+ dx = -m.value[0] * dy;
1046
+ X.value[0] = pt3.x + dx;
1047
+ Y.value[0] = pt3.y + dy;
1048
+ } catch (exc) {
1049
+ if (exc instanceof Error) {
1050
+ //console.log(e.message);
1051
+ ErrorLogger.LogException(lineutility._className, "ExtendLineAbove",
1052
+ new RendererException("Failed inside ExtendLineAbove", exc));
1053
+ } else {
1054
+ throw exc;
1055
+ }
1056
+ }
1057
+ return 1;
1058
+ }
1059
+
1060
+ /**
1061
+ * Extends a point to the left of a line
1062
+ *
1063
+ * @param pt1 first line point
1064
+ * @param pt2 last line point
1065
+ * @param pt3 point at which to extend
1066
+ * @param d distance in pixels to extend above the line
1067
+ * @param X OUT - extended point x value
1068
+ * @param Y OUT - extended point y value
1069
+ * @param direction direction to extend the line
1070
+ *
1071
+ * @return 1 if successful, else return 0
1072
+ */
1073
+ protected static ExtendLineLeft(pt1: POINT2,
1074
+ pt2: POINT2,
1075
+ pt3: POINT2,
1076
+ d: double,
1077
+ X: ref<number[]>,
1078
+ Y: ref<number[]>,
1079
+ direction: int): int {
1080
+ try {
1081
+ let m: ref<number[]> = new ref();
1082
+ let dx: double = 0;
1083
+ let dy: double = 0;
1084
+ let bolVertical: int = 0;
1085
+
1086
+ X.value = new Array<number>(1);
1087
+ Y.value = new Array<number>(1);
1088
+
1089
+ bolVertical = lineutility.CalcTrueSlopeDouble(pt1, pt2, m);
1090
+ if (bolVertical !== 0 && m.value[0] === 0) {
1091
+ return 0; //cannot left of horiz line
1092
+ }
1093
+ if (bolVertical === 0) //vertical line
1094
+ {
1095
+ Y.value[0] = pt3.y;
1096
+ if (direction === 0) //extend left of the line
1097
+ {
1098
+ X.value[0] = pt3.x - Math.abs(d);
1099
+ } else //extend right of the line
1100
+ {
1101
+ X.value[0] = pt3.x + Math.abs(d);
1102
+ }
1103
+
1104
+ return 1;
1105
+ }
1106
+ //the line is neither vertical nor horizontal
1107
+ //else function would already have returned
1108
+ if (direction === 0) //extend left of the line
1109
+ {
1110
+ dx = -Math.abs(d / Math.sqrt(1 + 1 / (m.value[0] * m.value[0])));
1111
+ } else //extend right of the line
1112
+ {
1113
+ dx = Math.abs(d / Math.sqrt(1 + 1 / (m.value[0] * m.value[0])));
1114
+ }
1115
+
1116
+ dy = -(1 / m.value[0]) * dx;
1117
+
1118
+ X.value[0] = pt3.x + dx;
1119
+ Y.value[0] = pt3.y + dy;
1120
+ } catch (exc) {
1121
+ if (exc instanceof Error) {
1122
+ //console.log(e.message);
1123
+ ErrorLogger.LogException(lineutility._className, "ExtendLineLeft",
1124
+ new RendererException("Failed inside ExtendLineLeft", exc));
1125
+ } else {
1126
+ throw exc;
1127
+ }
1128
+ }
1129
+ return 1;
1130
+ }
1131
+
1132
+ /**
1133
+ * Calculates the direction of a point relative to a line
1134
+ *
1135
+ * @param pt0 first point fo the line
1136
+ * @param pt1 last point of the line
1137
+ * @param pt2 relative point
1138
+ * @deprecated
1139
+ * @return 0 if left, 1 if right, 2 if above, 3 if below
1140
+ */
1141
+ protected static CalcDirectionFromLine(pt0: POINT2,
1142
+ pt1: POINT2,
1143
+ pt2: POINT2): int {
1144
+ let result: int = -1;
1145
+ try {
1146
+ let m2: double = 0;
1147
+ let b1: double = 0;
1148
+ let b2: double = 0;
1149
+ let m1: ref<number[]> = new ref();
1150
+ let ptIntersect: POINT2 = new POINT2();
1151
+ //int direction=-1;
1152
+ //handle vertical line
1153
+ if (pt0.x === pt1.x) {
1154
+ if (pt2.x < pt0.x) {
1155
+ return 0;
1156
+ } else {
1157
+ return 1;
1158
+ }
1159
+ }
1160
+ //handle horizontal line so that we do not have slope = 0.
1161
+ if (pt0.y === pt1.y) {
1162
+ if (pt2.y < pt0.y) {
1163
+ return 2;
1164
+ } else {
1165
+ return 3;
1166
+ }
1167
+ }
1168
+ lineutility.CalcTrueSlopeDouble(pt0, pt1, m1);
1169
+ m2 = -1 / m1.value[0]; //slope for the perpendicular line from the line to pt2
1170
+ //b=mx-y line equation for line
1171
+ b1 = pt0.y - m1.value[0] * pt0.x;
1172
+ //b=mx-y line equation for perpendicular line which contains pt2
1173
+ b2 = pt2.y - m2 * pt2.x;
1174
+ ptIntersect = lineutility.CalcTrueIntersectDouble2(m1.value[0], b1, m2, b2, 1, 1, 0, 0);
1175
+ //compare the intersection point with pt2 to get the direction,
1176
+ //i.e. the direction from the line is the same as the direction
1177
+ //from the interseciton point.
1178
+ if (m1.value[0] > 1) //line is steep, use left/right
1179
+ {
1180
+ if (pt2.x < ptIntersect.x) {
1181
+ return 0;
1182
+ } else {
1183
+ return 1;
1184
+ }
1185
+ } else //line is not steep, use above/below
1186
+ {
1187
+ if (pt2.y < ptIntersect.y) {
1188
+ return 2;
1189
+ } else {
1190
+ return 3;
1191
+ }
1192
+ }
1193
+ //should not reach this point
1194
+ //return direction;
1195
+ } catch (e) {
1196
+ if (e instanceof Error) {
1197
+ console.log(e.message);
1198
+ } else {
1199
+ throw e;
1200
+ }
1201
+ }
1202
+ return result;
1203
+ }
1204
+
1205
+ /**
1206
+ * Returns a point extended perpendicularly from a line at a given direction
1207
+ *
1208
+ * @param pt1 first line point
1209
+ * @param pt2 last line point
1210
+ * @param pt0 on line from which to extend
1211
+ * @param direction the direction to extend: above, below, left, right
1212
+ * @param d the length to extend in pixels
1213
+ *
1214
+ */
1215
+ public static ExtendDirectedLine(pt1: POINT2,
1216
+ pt2: POINT2,
1217
+ pt0: POINT2,
1218
+ direction: int,
1219
+ d: double): POINT2;
1220
+
1221
+ /**
1222
+ * Returns a point extended perpendicularly from a line at a given direction
1223
+ *
1224
+ * @param pt1 first line point
1225
+ * @param pt2 last line point
1226
+ * @param pt0 on line from which to extend
1227
+ * @param direction the direction to extend: above, below, left, right
1228
+ * @param d the length to extend in pixels
1229
+ * @param style the style to assign the return point
1230
+ *
1231
+ */
1232
+ public static ExtendDirectedLine(pt1: POINT2,
1233
+ pt2: POINT2,
1234
+ pt0: POINT2,
1235
+ direction: int,
1236
+ d: double,
1237
+ style: int): POINT2;
1238
+ public static ExtendDirectedLine(...args: unknown[]): POINT2 {
1239
+ switch (args.length) {
1240
+ case 5: {
1241
+ const [pt1, pt2, pt0, direction, d] = args as [POINT2, POINT2, POINT2, int, double];
1242
+
1243
+
1244
+ let ptResult: POINT2 = new POINT2();
1245
+ try {
1246
+ let X: ref<number[]> = new ref();
1247
+ let Y: ref<number[]> = new ref();
1248
+ ptResult = new POINT2(pt0);
1249
+ switch (direction) {
1250
+ case 0: { //extend left
1251
+ lineutility.ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 0);
1252
+ break;
1253
+ }
1254
+
1255
+ case 1: { //extend right
1256
+ lineutility.ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 1);
1257
+ break;
1258
+ }
1259
+
1260
+ case 2: { //extend above
1261
+ lineutility.ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 0);
1262
+ break;
1263
+ }
1264
+
1265
+ case 3: { //extend below
1266
+ lineutility.ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 1);
1267
+ break;
1268
+ }
1269
+
1270
+ default: {
1271
+ break;
1272
+ }
1273
+
1274
+ }
1275
+ ptResult.x = X.value[0];
1276
+ ptResult.y = Y.value[0];
1277
+ } catch (exc) {
1278
+ if (exc instanceof Error) {
1279
+ //console.log(e.message);
1280
+ ErrorLogger.LogException(lineutility._className, "ExtendDirectedLine",
1281
+ new RendererException("Failed inside ExtendDirectedLine", exc));
1282
+ } else {
1283
+ throw exc;
1284
+ }
1285
+ }
1286
+ return ptResult;
1287
+
1288
+
1289
+ break;
1290
+ }
1291
+
1292
+ case 6: {
1293
+ let [pt1, pt2, pt0, direction, d, style] = args as [POINT2, POINT2, POINT2, int, double, int];
1294
+
1295
+ let ptResult: POINT2 = new POINT2(pt0);
1296
+ try {
1297
+ let X: ref<number[]> = new ref();
1298
+ let Y: ref<number[]> = new ref();
1299
+ //int bolResult=0;
1300
+ //handle parallel, perpendicular cases
1301
+ if (pt1.x === pt2.x) {
1302
+ if (direction === 2) {
1303
+ direction = 0;
1304
+ }
1305
+ if (direction === 3) {
1306
+ direction = 1;
1307
+ }
1308
+ }
1309
+ if (pt1.y === pt2.y) {
1310
+ if (direction === 0) {
1311
+ direction = 2;
1312
+ }
1313
+ if (direction === 1) {
1314
+ direction = 3;
1315
+ }
1316
+ }
1317
+ switch (direction) {
1318
+ case 0: { //extend left
1319
+ lineutility.ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 0);
1320
+ break;
1321
+ }
1322
+
1323
+ case 1: { //extend right
1324
+ lineutility.ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 1);
1325
+ break;
1326
+ }
1327
+
1328
+ case 2: { //extend above
1329
+ lineutility.ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 0);
1330
+ break;
1331
+ }
1332
+
1333
+ case 3: { //extend below
1334
+ lineutility.ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 1);
1335
+ break;
1336
+ }
1337
+
1338
+
1339
+ default:
1340
+
1341
+ }
1342
+ ptResult.x = X.value[0];
1343
+ ptResult.y = Y.value[0];
1344
+ ptResult.style = style;
1345
+ } catch (exc) {
1346
+ if (exc instanceof Error) {
1347
+ ErrorLogger.LogException(lineutility._className, "ExtendDirectedLine",
1348
+ new RendererException("Failed inside ExtendDirectedLine", exc));
1349
+ } else {
1350
+ throw exc;
1351
+ }
1352
+ }
1353
+ return ptResult;
1354
+
1355
+
1356
+ break;
1357
+ }
1358
+
1359
+ default: {
1360
+ throw Error(`Invalid number of arguments`);
1361
+ }
1362
+ }
1363
+ }
1364
+
1365
+
1366
+ /**
1367
+ * @deprecated Returns a point extended perpendicularly from a line at a
1368
+ * given direction same as original function except it accounts for vertical
1369
+ * lines and negative d values
1370
+ *
1371
+ * @param pt1 first line point
1372
+ * @param pt2 last line point
1373
+ * @param pt0 on line from which to extend
1374
+ * @param direction the direction to extend: above, below, left, right
1375
+ * @param d the length to extend in pixels
1376
+ *
1377
+ */
1378
+ public static ExtendDirectedLineText(pt1: POINT2,
1379
+ pt2: POINT2,
1380
+ pt0: POINT2,
1381
+ direction: int,
1382
+ d: double): POINT2 {
1383
+ let ptResult: POINT2 = new POINT2();
1384
+ try {
1385
+ let X: ref<number[]> = new ref();
1386
+ let Y: ref<number[]> = new ref();
1387
+ ptResult = new POINT2(pt0);
1388
+ if (d < 0) {
1389
+ switch (direction) {
1390
+ case 0: {
1391
+ direction = lineutility.extend_right;
1392
+ break;
1393
+ }
1394
+
1395
+ case 1: {
1396
+ direction = lineutility.extend_left;
1397
+ break;
1398
+ }
1399
+
1400
+ case 2: {
1401
+ direction = lineutility.extend_below;
1402
+ break;
1403
+ }
1404
+
1405
+ case 3: {
1406
+ direction = lineutility.extend_above;
1407
+ break;
1408
+ }
1409
+
1410
+ default: {
1411
+ break;
1412
+ }
1413
+
1414
+ }
1415
+ d = Math.abs(d);
1416
+ }
1417
+ if (pt1.y === pt2.y)//horizontal segment
1418
+ {
1419
+ switch (direction) {
1420
+ case 0: {//left means above
1421
+ direction = lineutility.extend_above;
1422
+ break;
1423
+ }
1424
+
1425
+ case 1: {//right means below
1426
+ direction = lineutility.extend_below;
1427
+ break;
1428
+ }
1429
+
1430
+ default: {
1431
+ break;
1432
+ }
1433
+
1434
+ }
1435
+ }
1436
+ if (pt1.x === pt2.x)//vertical segment
1437
+ {
1438
+ switch (direction) {
1439
+ case 2: {//above means left
1440
+ direction = lineutility.extend_left;
1441
+ break;
1442
+ }
1443
+
1444
+ case 3: {//below means right
1445
+ direction = lineutility.extend_right;
1446
+ break;
1447
+ }
1448
+
1449
+ default: {
1450
+ break;
1451
+ }
1452
+
1453
+ }
1454
+ }
1455
+ switch (direction) {
1456
+ case 0: { //extend left
1457
+ lineutility.ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 0);
1458
+ break;
1459
+ }
1460
+
1461
+ case 1: { //extend right
1462
+ lineutility.ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 1);
1463
+ break;
1464
+ }
1465
+
1466
+ case 2: { //extend above
1467
+ lineutility.ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 0);
1468
+ break;
1469
+ }
1470
+
1471
+ case 3: { //extend below
1472
+ lineutility.ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 1);
1473
+ break;
1474
+ }
1475
+
1476
+ default: {
1477
+ break;
1478
+ }
1479
+
1480
+ }
1481
+ ptResult.x = X.value[0];
1482
+ ptResult.y = Y.value[0];
1483
+ } catch (exc) {
1484
+ if (exc instanceof Error) {
1485
+ //console.log(e.message);
1486
+ ErrorLogger.LogException(lineutility._className, "ExtendDirectedLine",
1487
+ new RendererException("Failed inside ExtendDirectedLine", exc));
1488
+ } else {
1489
+ throw exc;
1490
+ }
1491
+ }
1492
+ return ptResult;
1493
+ }
1494
+
1495
+ /**
1496
+ * Calculates a point along a line
1497
+ *
1498
+ * @param pt1 first line point
1499
+ * @param pt2 last line point
1500
+ * @param dist extension distance in pixels from the beginning of the line
1501
+ * @param styl the line style to assign the point
1502
+ *
1503
+ * @return the extension point
1504
+ */
1505
+ static ExtendLine2Double(pt1: POINT2,
1506
+ pt2: POINT2,
1507
+ dist: double,
1508
+ styl: int): POINT2 {
1509
+ let pt3: POINT2 = new POINT2();
1510
+ try {
1511
+ let dOriginalDistance: double = lineutility.CalcDistanceDouble(pt1, pt2);
1512
+
1513
+ pt3.x = pt2.x;
1514
+ pt3.y = pt2.y;
1515
+ if (dOriginalDistance > 0) {
1516
+ pt3.x = ((dOriginalDistance + dist) / dOriginalDistance * (pt2.x - pt1.x) + pt1.x);
1517
+ pt3.y = ((dOriginalDistance + dist) / dOriginalDistance * (pt2.y - pt1.y) + pt1.y);
1518
+ pt3.style = styl;
1519
+ }
1520
+ } catch (exc) {
1521
+ if (exc instanceof Error) {
1522
+ ErrorLogger.LogException(lineutility._className, "ExtendLine2Double",
1523
+ new RendererException("Failed inside ExtendLine2Double", exc));
1524
+ } else {
1525
+ throw exc;
1526
+ }
1527
+ }
1528
+ return pt3;
1529
+ }
1530
+
1531
+ /**
1532
+ * Extends a point at an angle from a line.
1533
+ *
1534
+ * @param pt0 the first line point
1535
+ * @param pt1 the second line point
1536
+ * @param pt2 point on line from which to extend
1537
+ * @param alpha angle of extension in degrees
1538
+ * @param d the distance in pixels to extend
1539
+ *
1540
+ * @return the extension point
1541
+ */
1542
+ public static ExtendAngledLine(pt0: POINT2,
1543
+ pt1: POINT2,
1544
+ pt2: POINT2,
1545
+ alpha: double,
1546
+ d: double): POINT2 {
1547
+ let pt: POINT2 = new POINT2();
1548
+ try {
1549
+ //first get the angle psi between pt0 and pt1
1550
+ let psi: double = Math.atan((pt1.y - pt0.y) / (pt1.x - pt0.x));
1551
+ //convert alpha to radians
1552
+ let alpha1: double = Math.PI * alpha / 180;
1553
+
1554
+ //theta is the angle of extension from the x axis
1555
+ let theta: double = psi + alpha1;
1556
+ //dx is the x extension from pt2
1557
+ let dx: double = d * Math.cos(theta);
1558
+ //dy is the y extension form pt2
1559
+ let dy: double = d * Math.sin(theta);
1560
+ pt.x = pt2.x + dx;
1561
+ pt.y = pt2.y + dy;
1562
+ } catch (exc) {
1563
+ if (exc instanceof Error) {
1564
+ ErrorLogger.LogException(lineutility._className, "ExtendAngledLine",
1565
+ new RendererException("Failed inside ExtendAngledLine", exc));
1566
+ } else {
1567
+ throw exc;
1568
+ }
1569
+ }
1570
+ return pt;
1571
+ }
1572
+
1573
+ /**
1574
+ * Returns an integer indicating the quadrant for the direction of the line
1575
+ * from pt1 to pt2
1576
+ *
1577
+ * @param pt1 first line point
1578
+ * @param pt2 second line point
1579
+ *
1580
+ * @return the quadrant
1581
+ */
1582
+ public static GetQuadrantDouble(pt1: POINT2,
1583
+ pt2: POINT2): int;
1584
+
1585
+ public static GetQuadrantDouble(x1: double, y1: double,
1586
+ x2: double, y2: double): int;
1587
+ public static GetQuadrantDouble(...args: unknown[]): int {
1588
+ switch (args.length) {
1589
+ case 2: {
1590
+ const [pt1, pt2] = args as [POINT2, POINT2];
1591
+
1592
+
1593
+ let nQuadrant: int = 1;
1594
+ try {
1595
+ if (pt2.x >= pt1.x && pt2.y <= pt1.y) {
1596
+ nQuadrant = 1;
1597
+ }
1598
+ if (pt2.x >= pt1.x && pt2.y >= pt1.y) {
1599
+ nQuadrant = 2;
1600
+ }
1601
+ if (pt2.x <= pt1.x && pt2.y >= pt1.y) {
1602
+ nQuadrant = 3;
1603
+ }
1604
+ if (pt2.x <= pt1.x && pt2.y <= pt1.y) {
1605
+ nQuadrant = 4;
1606
+ }
1607
+
1608
+ } catch (exc) {
1609
+ if (exc instanceof Error) {
1610
+ ErrorLogger.LogException(lineutility._className, "GetQuadrantDouble",
1611
+ new RendererException("Failed inside GetQuadrantDouble", exc));
1612
+ } else {
1613
+ throw exc;
1614
+ }
1615
+ }
1616
+ return nQuadrant;
1617
+
1618
+
1619
+ break;
1620
+ }
1621
+
1622
+ case 4: {
1623
+ const [x1, y1, x2, y2] = args as [double, double, double, double];
1624
+
1625
+
1626
+ let nQuadrant: int = 1;
1627
+ try {
1628
+ // if(pt2.x>=pt1.x && pt2.y<=pt1.y)
1629
+ // nQuadrant=1;
1630
+ // if(pt2.x>=pt1.x && pt2.y>=pt1.y)
1631
+ // nQuadrant=2;
1632
+ // if(pt2.x<=pt1.x && pt2.y>=pt1.y)
1633
+ // nQuadrant=3;
1634
+ // if(pt2.x<=pt1.x && pt2.y<=pt1.y)
1635
+ // nQuadrant=4;
1636
+
1637
+ if (x2 >= x1 && y2 <= y1) {
1638
+ nQuadrant = 1;
1639
+ }
1640
+ if (x2 >= x1 && y2 >= y1) {
1641
+ nQuadrant = 2;
1642
+ }
1643
+ if (x2 <= x1 && y2 >= y1) {
1644
+ nQuadrant = 3;
1645
+ }
1646
+ if (x2 <= x1 && y2 <= y1) {
1647
+ nQuadrant = 4;
1648
+ }
1649
+ } catch (exc) {
1650
+ if (exc instanceof Error) {
1651
+ ErrorLogger.LogException(lineutility._className, "GetQuadrantDouble",
1652
+ new RendererException("Failed inside GetQuadrantDouble", exc));
1653
+ } else {
1654
+ throw exc;
1655
+ }
1656
+ }
1657
+ return nQuadrant;
1658
+
1659
+
1660
+ break;
1661
+ }
1662
+
1663
+ default: {
1664
+ throw Error(`Invalid number of arguments`);
1665
+ }
1666
+ }
1667
+ }
1668
+
1669
+
1670
+ /**
1671
+ * Returns the smallest x and y pixel values from an array of points
1672
+ *
1673
+ * @param ptsSeize array of points from which to find minimum vaules
1674
+ * @param vblCounter the number of points to test in the array
1675
+ * @param x OUT - an object with a member to hold the xminimum
1676
+ * @param y OUT - an object with a member to hold the y minimum value
1677
+ *
1678
+ */
1679
+ public static GetPixelsMin(ptsSeize: POINT2[],
1680
+ vblCounter: int,
1681
+ x: ref<number[]>,
1682
+ y: ref<number[]>): void {
1683
+ try {
1684
+ let xmin: double = Number.POSITIVE_INFINITY;
1685
+ let ymin: double = Number.POSITIVE_INFINITY;
1686
+ let j: int = 0;
1687
+
1688
+ for (j = 0; j < vblCounter; j++) {
1689
+ if (ptsSeize[j].x < xmin) {
1690
+ xmin = ptsSeize[j].x;
1691
+ }
1692
+ if (ptsSeize[j].y < ymin) {
1693
+ ymin = ptsSeize[j].y;
1694
+ }
1695
+ }
1696
+ x.value = new Array<number>(1);
1697
+ y.value = new Array<number>(1);
1698
+ x.value[0] = xmin;
1699
+ y.value[0] = ymin;
1700
+ } catch (exc) {
1701
+ if (exc instanceof Error) {
1702
+ ErrorLogger.LogException(lineutility._className, "GetPixelsMin",
1703
+ new RendererException("Failed inside GetPixelsMin", exc));
1704
+ } else {
1705
+ throw exc;
1706
+ }
1707
+ }
1708
+ }
1709
+
1710
+ /**
1711
+ * Returns the largest x and y pixel values from an array of points
1712
+ *
1713
+ * @param ptsSeize array of points from which to find maximum values
1714
+ * @param vblCounter the number of points to test in the array
1715
+ * @param x OUT - an object with a member to hold the x maximum value
1716
+ * @param y OUT - an object with a member to hold the y maximum value
1717
+ *
1718
+ */
1719
+ public static GetPixelsMax(ptsSeize: POINT2[],
1720
+ vblCounter: int,
1721
+ x: ref<number[]>,
1722
+ y: ref<number[]>): void {
1723
+ try {
1724
+ let xmax: double = Number.NEGATIVE_INFINITY;
1725
+ let ymax: double = Number.NEGATIVE_INFINITY;
1726
+ let j: int = 0;
1727
+
1728
+ for (j = 0; j < vblCounter; j++) {
1729
+ if (ptsSeize[j].x > xmax) {
1730
+ xmax = ptsSeize[j].x;
1731
+ }
1732
+ if (ptsSeize[j].y > ymax) {
1733
+ ymax = ptsSeize[j].y;
1734
+ }
1735
+ }
1736
+ x.value = new Array<number>(1);
1737
+ y.value = new Array<number>(1);
1738
+ x.value[0] = xmax;
1739
+ y.value[0] = ymax;
1740
+ } catch (exc) {
1741
+ if (exc instanceof Error) {
1742
+ ErrorLogger.LogException(lineutility._className, "GetPixelsMax",
1743
+ new RendererException("Failed inside GetPixelsMax", exc));
1744
+ } else {
1745
+ throw exc;
1746
+ }
1747
+ }
1748
+ }
1749
+
1750
+ /**
1751
+ * Returns center point for a clockwise arc to connect pts 1 and 2. Also
1752
+ * returns an extended point on the line between pt1 and the new center
1753
+ * Caller passes a POINT1 array of size 2 for ptsSeize, passes pt1 and pt2
1754
+ * in ptsSeize Returns the radius of the 90 degree arc between C (arc
1755
+ * center) and pt1
1756
+ *
1757
+ * @param ptsSeize OUT - two point array also used for the returned two
1758
+ * points
1759
+ *
1760
+ * @return the radius
1761
+ */
1762
+ static CalcClockwiseCenterDouble(ptsSeize: POINT2[]): double {
1763
+ let dRadius: double = 0;
1764
+ try {
1765
+ //declarations
1766
+ let pt1: POINT2 = new POINT2(ptsSeize[0]);
1767
+ let pt2: POINT2 = new POINT2(ptsSeize[1]);
1768
+ let C: POINT2 = new POINT2(pt1);
1769
+ let midPt: POINT2 = new POINT2(pt1); //the center to calculate
1770
+ let E: POINT2 = new POINT2(pt1); //the extended point to calculate
1771
+ let ptYIntercept: POINT2 = new POINT2(pt1);
1772
+ let nQuadrant: int = 1;
1773
+ let b: double = 0;
1774
+ let b1: double = 0;
1775
+ let b2: double = 0;
1776
+ let dLength: double = 0;
1777
+ let m: ref<number[]> = new ref();
1778
+ let bolVertical: int = 0;
1779
+ let offsetX: ref<number[]> = new ref();
1780
+ let offsetY: ref<number[]> = new ref();
1781
+ let ptsTemp: POINT2[] = new Array<POINT2>(2);
1782
+ //end declarations
1783
+
1784
+ //must offset the points if necessary because there will be calculations
1785
+ //extending from the Y Intercept
1786
+ ptsTemp[0] = new POINT2(pt1);
1787
+ ptsTemp[1] = new POINT2(pt2);
1788
+ lineutility.GetPixelsMin(ptsTemp, 2, offsetX, offsetY);
1789
+ if (offsetX.value[0] < 0) {
1790
+ offsetX.value[0] = offsetX.value[0] - 100;
1791
+ } else {
1792
+ offsetX.value[0] = 0;
1793
+ }
1794
+ //end section
1795
+
1796
+ midPt.x = (pt1.x + pt2.x) / 2;
1797
+ midPt.y = (pt1.y + pt2.y) / 2;
1798
+ dLength = lineutility.CalcDistanceDouble(pt1, pt2);
1799
+ dRadius = dLength / Math.sqrt(2);
1800
+ nQuadrant = lineutility.GetQuadrantDouble(pt1, pt2);
1801
+
1802
+ bolVertical = lineutility.CalcTrueSlopeDouble(pt1, pt2, m);
1803
+ if (bolVertical !== 0 && m.value[0] !== 0) //line not vertical or horizontal
1804
+ {
1805
+ b = pt1.y - m.value[0] * pt1.x;
1806
+ //y intercept of line perpendicular to midPt of pt,p2
1807
+ b1 = midPt.y + (1 / m.value[0]) * midPt.x;
1808
+ //we want to shift the Y axis to the left by offsetX
1809
+ //so we get the new Y intercept at x=offsetX
1810
+ b2 = (-1 / m.value[0]) * offsetX.value[0] + b1;
1811
+ ptYIntercept.x = offsetX.value[0];
1812
+ ptYIntercept.y = b2;
1813
+ switch (nQuadrant) {
1814
+ case 1:
1815
+ case 4: {
1816
+ C = lineutility.ExtendLineDouble(ptYIntercept, midPt, dLength / 2);
1817
+ break;
1818
+ }
1819
+
1820
+ case 2:
1821
+ case 3: {
1822
+ C = lineutility.ExtendLineDouble(ptYIntercept, midPt, -dLength / 2);
1823
+ break;
1824
+ }
1825
+
1826
+ default: {
1827
+ break;
1828
+ }
1829
+
1830
+ }
1831
+ }
1832
+ if (bolVertical !== 0 && m.value[0] === 0) //horizontal line
1833
+ {
1834
+ C.x = midPt.x;
1835
+ if (pt1.x < pt2.x) {
1836
+ C.y = midPt.y + dLength / 2;
1837
+ } else {
1838
+ C.y = midPt.y - dLength / 2;
1839
+ }
1840
+ }
1841
+ if (bolVertical === 0) //vertical line
1842
+ {
1843
+ ptYIntercept.x = offsetX.value[0];
1844
+ ptYIntercept.y = midPt.y;
1845
+ switch (nQuadrant) {
1846
+ case 1:
1847
+ case 4: {
1848
+ C = lineutility.ExtendLineDouble(ptYIntercept, midPt, dLength / 2);
1849
+ break;
1850
+ }
1851
+
1852
+ case 2:
1853
+ case 3: {
1854
+ C = lineutility.ExtendLineDouble(ptYIntercept, midPt, -dLength / 2);
1855
+ break;
1856
+ }
1857
+
1858
+ default: {
1859
+ break;
1860
+ }
1861
+
1862
+ }
1863
+ }
1864
+
1865
+ E = lineutility.ExtendLineDouble(C, pt1, 50);
1866
+ ptsSeize[0] = new POINT2(C);
1867
+ ptsSeize[1] = new POINT2(E);
1868
+ } catch (exc) {
1869
+ if (exc instanceof Error) {
1870
+ ErrorLogger.LogException(lineutility._className, "CalcClockwiseCenterDouble",
1871
+ new RendererException("Failed inside CalcClockwiseCenterDouble", exc));
1872
+ } else {
1873
+ throw exc;
1874
+ }
1875
+ }
1876
+ return dRadius;
1877
+ }
1878
+
1879
+ /**
1880
+ * Computes the points for an arrowhead based on a line segment
1881
+ *
1882
+ * @param startLinePoint segment start point
1883
+ * @param endLinePoint segment end point
1884
+ * @param nBiSector bisecotr in pixels
1885
+ * @param nBase base size in pixels
1886
+ * @param pResultLinePoints OUT - the arrowhead points
1887
+ * @param styl the line style to assign the last aroowhead point
1888
+ */
1889
+ static GetArrowHead4Double(startLinePoint: POINT2,
1890
+ endLinePoint: POINT2,
1891
+ nBiSector: int,
1892
+ nBase: int,
1893
+ pResultLinePoints: POINT2[],
1894
+ styl: int): void {
1895
+ try {
1896
+ //declarations
1897
+ let j: int = 0;
1898
+ let dy: double = (endLinePoint.y - startLinePoint.y) as double;
1899
+ let
1900
+ dx: double = (endLinePoint.x - startLinePoint.x) as double;
1901
+ let
1902
+ dSign: double = 1.0;
1903
+ let
1904
+ AHBY: double = 0;
1905
+ let
1906
+ AHBX: double = 0;
1907
+ let
1908
+ AHBLY: double = 0;
1909
+ let
1910
+ AHBLX: double = 0;
1911
+ let
1912
+ AHBRY: double = 0;
1913
+ let
1914
+ AHBRX: double = 0;
1915
+ let
1916
+ dAngle: double = 0;
1917
+ let
1918
+ dHypotenuse: double = 0;
1919
+
1920
+ let tempLinePoint: POINT2 = new POINT2(startLinePoint);
1921
+ //end declarations
1922
+
1923
+ if (dy === 0) {
1924
+ if (dx > 0) {
1925
+ dAngle = Math.PI;
1926
+ } else {
1927
+ dAngle = 0;
1928
+ }
1929
+ } else {
1930
+ dAngle = Math.atan(dx / dy) + Math.PI / 2;
1931
+ }
1932
+
1933
+ tempLinePoint.style = 0;//PS_SOLID;
1934
+
1935
+ if (dx <= 0.0 && dy <= 0.0) {
1936
+ dSign = -1.0;
1937
+ }
1938
+ if (dx >= 0.0 && dy <= 0.0) {
1939
+ dSign = -1.0;
1940
+ }
1941
+ if (dx <= 0.0 && dy >= 0.0) {
1942
+ dSign = 1.0;
1943
+ }
1944
+ if (dx >= 0.0 && dy >= 0.0) {
1945
+ dSign = 1.0;
1946
+ }
1947
+
1948
+ dHypotenuse = dSign * nBiSector as double;
1949
+
1950
+ //Find x, y for Arrow Head nBase startLinePoint POINT1
1951
+ AHBX = endLinePoint.x as double + dHypotenuse * Math.cos(dAngle);
1952
+ AHBY = endLinePoint.y as double - dHypotenuse * Math.sin(dAngle);
1953
+
1954
+ //Half of the arrow head's length will be 10 units
1955
+ dHypotenuse = dSign * (nBase / 2.0) as double;
1956
+
1957
+ //Find x, y of Arrow Head nBase Left side end POINT1
1958
+ AHBLX = AHBX - dHypotenuse * Math.sin(dAngle);
1959
+ AHBLY = AHBY - dHypotenuse * Math.cos(dAngle);
1960
+
1961
+ //Find x, y of Arrow Head nBase Right side end POINT1
1962
+ AHBRX = AHBX + dHypotenuse * Math.sin(dAngle);
1963
+ AHBRY = AHBY + dHypotenuse * Math.cos(dAngle);
1964
+
1965
+ //replacement, just trying to return the POINT1s
1966
+ tempLinePoint.x = AHBLX as int;
1967
+ tempLinePoint.y = AHBLY as int;
1968
+ pResultLinePoints[0] = new POINT2(tempLinePoint);
1969
+ pResultLinePoints[1] = new POINT2(endLinePoint);
1970
+ tempLinePoint.x = AHBRX as int;
1971
+ tempLinePoint.y = AHBRY as int;
1972
+ pResultLinePoints[2] = new POINT2(tempLinePoint);
1973
+ switch (styl) {
1974
+ case 0: {
1975
+ for (j = 0; j < 2; j++) {
1976
+ pResultLinePoints[j].style = 0;
1977
+ }
1978
+ pResultLinePoints[2].style = 5;
1979
+ break;
1980
+ }
1981
+
1982
+ case 9: {
1983
+ for (j = 0; j < 2; j++) {
1984
+ pResultLinePoints[j].style = 9;
1985
+ }
1986
+ pResultLinePoints[2].style = 10;
1987
+ break;
1988
+ }
1989
+
1990
+ case 18: {
1991
+ for (j = 0; j < 2; j++) {
1992
+ pResultLinePoints[j].style = 18;
1993
+ }
1994
+ pResultLinePoints[2].style = 5;
1995
+ break;
1996
+ }
1997
+
1998
+ default: {
1999
+ for (j = 0; j < 2; j++) {
2000
+ pResultLinePoints[j].style = styl;
2001
+ }
2002
+ pResultLinePoints[2].style = 5;
2003
+ break;
2004
+ }
2005
+
2006
+ }
2007
+ } catch (exc) {
2008
+ if (exc instanceof Error) {
2009
+ ErrorLogger.LogException(lineutility._className, "GetArrowhead4Double",
2010
+ new RendererException("Failed inside GetArrowhead4Double", exc));
2011
+ } else {
2012
+ throw exc;
2013
+ }
2014
+ }
2015
+ }
2016
+
2017
+ /**
2018
+ * Returns the midpoint between two points.
2019
+ *
2020
+ * @param pt0 the first point
2021
+ * @param pt1 the second point
2022
+ * @param styl the style to assign the mid point
2023
+ *
2024
+ * @return the mid point
2025
+ */
2026
+ public static MidPointDouble(pt0: POINT2,
2027
+ pt1: POINT2,
2028
+ styl: int): POINT2 {
2029
+ let ptResult: POINT2 = new POINT2(pt0);
2030
+ try {
2031
+ ptResult.x = (pt0.x + pt1.x) / 2;
2032
+ ptResult.y = (pt0.y + pt1.y) / 2;
2033
+ ptResult.style = styl;
2034
+ } catch (exc) {
2035
+ if (exc instanceof Error) {
2036
+ ErrorLogger.LogException(lineutility._className, "MidPointDouble",
2037
+ new RendererException("Failed inside MidPointDouble", exc));
2038
+ } else {
2039
+ throw exc;
2040
+ }
2041
+ }
2042
+ return ptResult;
2043
+ }
2044
+
2045
+ /**
2046
+ * Rotates an the first vblCounter points in the array about its first point
2047
+ *
2048
+ * @param pLinePoints OUT - the points to rotate
2049
+ * @param vblCounter the number of points to rotate
2050
+ * @param lAngle the angle in degrees to rotate
2051
+ *
2052
+ * @return pLinePoints
2053
+ */
2054
+ protected static RotateGeometryDoubleOrigin(pLinePoints: POINT2[],
2055
+ vblCounter: int,
2056
+ lAngle: int): POINT2[] {
2057
+ try {
2058
+ //declarations
2059
+ let j: int = 0;
2060
+ let dRotate: double = 0;
2061
+ let
2062
+ dTheta: double = 0;
2063
+ let
2064
+ dGamma: double = 0;
2065
+ let
2066
+ x: double = 0;
2067
+ let
2068
+ y: double = 0;
2069
+ //end declarations
2070
+
2071
+ if (lAngle !== 0) {
2072
+ let pdCenter: POINT2 = new POINT2();
2073
+ dRotate = lAngle as double * Math.PI / 180;
2074
+ //pdCenter = CalcCenterPointDouble(pLinePoints,vblCounter);
2075
+ pdCenter = new POINT2(pLinePoints[0]);
2076
+
2077
+ for (j = 0; j < vblCounter; j++) {
2078
+ dGamma = Math.PI + Math.atan((pLinePoints[j].y - pdCenter.y)
2079
+ / (pLinePoints[j].x - pdCenter.x));
2080
+
2081
+ if (pLinePoints[j].x >= pdCenter.x) {
2082
+ dGamma = dGamma + Math.PI;
2083
+ }
2084
+
2085
+ dTheta = dRotate + dGamma;
2086
+ y = lineutility.CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.sin(dTheta);
2087
+ x = lineutility.CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.cos(dTheta);
2088
+ pLinePoints[j].y = pdCenter.y + y;
2089
+ pLinePoints[j].x = pdCenter.x + x;
2090
+ } //end for
2091
+
2092
+ return pLinePoints;
2093
+ } //end if
2094
+ } catch (exc) {
2095
+ if (exc instanceof Error) {
2096
+ ErrorLogger.LogException(lineutility._className, "RotateGeometryDoubleOrigin",
2097
+ new RendererException("Failed inside RotateGeometryDoubleOrigin", exc));
2098
+ } else {
2099
+ throw exc;
2100
+ }
2101
+ }
2102
+ return pLinePoints;
2103
+ } // end function
2104
+
2105
+ /**
2106
+ * Returns a point a distance d pixels perpendicular to the pt0-pt1 line and
2107
+ * going toward pt2
2108
+ *
2109
+ * @param pt0 the first line point
2110
+ * @param pt1 the second line point
2111
+ * @param pt2 the relative line point
2112
+ * @param d the distance in pixels
2113
+ * @param styl the linestyle to assign the computed point
2114
+ *
2115
+ * @return the extended point
2116
+ */
2117
+ public static ExtendTrueLinePerpDouble(pt0: POINT2,
2118
+ pt1: POINT2,
2119
+ pt2: POINT2,
2120
+ d: double,
2121
+ styl: int): POINT2 {
2122
+ let ptResult: POINT2 = new POINT2(pt0);
2123
+ try {
2124
+ let ptYIntercept: POINT2 = new POINT2(pt0);
2125
+ let m: ref<number[]> = new ref();
2126
+ let b: double = 0;
2127
+ let b1: double = 0; //b is the normal Y intercept (at 0)
2128
+ let nTemp: int = 0; //b1 is the y intercept at offsetX
2129
+
2130
+ //must obtain x minimum to get the y-intercept to the left of
2131
+ //the left-most point
2132
+ let offsetX: ref<number[]> = new ref();
2133
+ let offsetY: ref<number[]> = new ref();
2134
+ let pts: POINT2[] = new Array<POINT2>(3);
2135
+ pts[0] = new POINT2(pt0);
2136
+ pts[1] = new POINT2(pt1);
2137
+ pts[2] = new POINT2(pt2);
2138
+ lineutility.GetPixelsMin(pts, 3, offsetX, offsetY);
2139
+
2140
+ if (offsetX.value[0] <= 0) //was < 0
2141
+ {
2142
+ offsetX.value[0] = offsetX.value[0] - 100;
2143
+ } else {
2144
+ offsetX.value[0] = 0;
2145
+ }
2146
+ //end section
2147
+
2148
+ nTemp = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
2149
+ switch (nTemp) {
2150
+ case 0: { //vertical line
2151
+ if (pt0.y < pt1.y) {
2152
+ ptResult.x = pt2.x - d;
2153
+ ptResult.y = pt2.y;
2154
+ } else {
2155
+ ptResult.x = pt2.x + d;
2156
+ ptResult.y = pt2.y;
2157
+ }
2158
+ break;
2159
+ }
2160
+
2161
+ default: { //non-vertical line
2162
+ if (m.value[0] === 0) {
2163
+ ptResult.x = pt2.x;
2164
+ ptResult.y = pt2.y + d;
2165
+ } else {
2166
+ b = pt2.y as double + (1 / m.value[0]) * pt2.x as double;
2167
+ //we need the y-intercept at the -offset
2168
+ b1 = (-1 / m.value[0]) * offsetX.value[0] + b;
2169
+ ptYIntercept.x = offsetX.value[0];
2170
+ ptYIntercept.y = b1;
2171
+ ptResult = lineutility.ExtendLineDouble(ptYIntercept, pt2, d);
2172
+ }
2173
+ break;
2174
+ }
2175
+
2176
+ }
2177
+ ptResult.style = styl;
2178
+ } catch (exc) {
2179
+ if (exc instanceof Error) {
2180
+ ErrorLogger.LogException(lineutility._className, "ExtendTrueLinePerpDouble",
2181
+ new RendererException("Failed inside ExtendTrueLinePerpDouble", exc));
2182
+ } else {
2183
+ throw exc;
2184
+ }
2185
+ }
2186
+ return ptResult;
2187
+ }
2188
+
2189
+ /**
2190
+ * Calculates the intersection of 2 lines pelative to a point. if one of the
2191
+ * lines is vertical use a distance dWidth above or below the line. pass
2192
+ * bolVertical1 = 1, or bolVertical2 = 1 if either line segment is vertical,
2193
+ * else pass 0. return the unique intersection in X,Y pointers. p2 is the
2194
+ * point that connects the 2 line segments to which the intersecting lines
2195
+ * are related, i.e. the intersecting lines are a distance dWidth pixels
2196
+ * above or below p2. uses dWidth and lOrient for cases in which at least
2197
+ * one of the lines is vertical. for normal lines this function assumes the
2198
+ * caller has passed the m, b for the appropriate upper or lower lines to
2199
+ * get the desired intgercept. this function is used for calculating the
2200
+ * upper and lower channel lines for channel types. For lOrient: see
2201
+ * comments in Channels.ConnectTrueDouble2
2202
+ *
2203
+ * @param m1 slope of the first line
2204
+ * @param b1 intercept of the first line
2205
+ * @param m2 slope of the second line
2206
+ * @param b2 y intercept of the second line
2207
+ * @param p2 point that connects the 2 line segments to which the
2208
+ * intersecting lines are related
2209
+ * @param bolVerticalSlope1 1 if first segment is vertical, else 0
2210
+ * @param bolVerticalSlope2 1 if second line segment is vertical, else 0
2211
+ * @param dWidth the distance of the intersecting lines from p2 in pixels
2212
+ * @param lOrient the orientation of the intersecting lines relative to the
2213
+ * segments connecting p2
2214
+ * @param X OUT - object holds the x value of the intersection point
2215
+ * @param Y OUT - object holds the y value of the intersection point
2216
+ */
2217
+ static CalcTrueIntersectDouble(m1: double,
2218
+ b1: double,
2219
+ m2: double,
2220
+ b2: double,
2221
+ p2: POINT2, //can use for vertical lines
2222
+ bolVerticalSlope1: int,
2223
+ bolVerticalSlope2: int,
2224
+ dWidth: double, //use for vertical lines, use + for upper line, - for lower line
2225
+ lOrient: int,
2226
+ X: ref<number[]>, //intersection x value
2227
+ Y: ref<number[]>): int //intersection y value
2228
+ {
2229
+
2230
+ try {
2231
+ //case both lines are vertical
2232
+ let dWidth2: double = Math.abs(dWidth);
2233
+ let b: double = 0;
2234
+ let dx: double = 0;
2235
+ let dy: double = 0;
2236
+ let m: double = 0;
2237
+ X.value = new Array<number>(1);
2238
+ Y.value = new Array<number>(1);
2239
+
2240
+ //cannot get out of having to do this
2241
+ //the problem is caused by inexact slopes which are created by
2242
+ //clsLineUtility.DisplayIntersectPixels. This occurs when setting
2243
+ //pt2 or pt3 with X or Y on the boundary +/-maxPixels
2244
+ //if you try to walk out until you get exactly the same slope
2245
+ //it can be thousands of pixels, so you have to accept an arbitrary
2246
+ //and, unfortuantely, inexact slope
2247
+ if (m1 !== m2 && Math.abs(m1 - m2) <= Number.MIN_VALUE) {
2248
+ m1 = m2;
2249
+ }
2250
+ if (b1 !== b2 && Math.abs(b1 - b2) <= Number.MIN_VALUE) {
2251
+ b1 = b2;
2252
+ }
2253
+
2254
+ //M. Deutch 10-24-11
2255
+ if (b1 === b2 && m1 + b1 === m2 + b2) {
2256
+ m1 = m2;
2257
+ }
2258
+
2259
+ if (bolVerticalSlope1 === 0 && bolVerticalSlope2 === 0) //both lines vertical
2260
+ {
2261
+ switch (lOrient) {
2262
+ case 0: {
2263
+ X.value[0] = p2.x - dWidth2;
2264
+ Y.value[0] = p2.y;
2265
+ break;
2266
+ }
2267
+
2268
+ case 3: {
2269
+ X.value[0] = p2.x + dWidth2;
2270
+ Y.value[0] = p2.y;
2271
+ break;
2272
+ }
2273
+
2274
+ default: { //can never occur
2275
+ X.value[0] = p2.x;
2276
+ Y.value[0] = p2.y;
2277
+ break;
2278
+ }
2279
+
2280
+ }
2281
+ return 1;
2282
+ }
2283
+ if (bolVerticalSlope1 === 0 && bolVerticalSlope2 !== 0) //line1 vertical, line2 is not
2284
+ { //there is a unique intersection
2285
+ switch (lOrient) {
2286
+ case 0: //Line1 above segment1
2287
+ case 1: {
2288
+ X.value[0] = p2.x - dWidth2;
2289
+ Y.value[0] = m2 * X.value[0] + b2;
2290
+ break;
2291
+ }
2292
+
2293
+ case 2: //Line1 below segment1
2294
+ case 3: {
2295
+ X.value[0] = p2.x + dWidth2;
2296
+ Y.value[0] = m2 * X.value[0] + b2;
2297
+ break;
2298
+ }
2299
+
2300
+ default: { //can not occur
2301
+ X.value[0] = p2.x;
2302
+ Y.value[0] = p2.y;
2303
+ break;
2304
+ }
2305
+
2306
+ }
2307
+ return 1;
2308
+ }
2309
+ if (bolVerticalSlope2 === 0 && bolVerticalSlope1 !== 0) //line2 vertical, line1 is not
2310
+ { //there is a unique intersection
2311
+ switch (lOrient) {
2312
+ case 0: //Line1 above segment2
2313
+ case 2: {
2314
+ X.value[0] = p2.x - dWidth2;
2315
+ Y.value[0] = m1 * (X.value[0]) + b1;
2316
+ break;
2317
+ }
2318
+
2319
+ case 1: //Line1 below segment2
2320
+ case 3: {
2321
+ X.value[0] = p2.x + dWidth2;
2322
+ Y.value[0] = m1 * (X.value[0]) + b1;
2323
+ break;
2324
+ }
2325
+
2326
+ default: { //can not occur
2327
+ X.value[0] = p2.x;
2328
+ Y.value[0] = p2.y;
2329
+ break;
2330
+ }
2331
+
2332
+ }
2333
+ return 1;
2334
+ }//end if
2335
+
2336
+ //must deal with this case separately because normal lines use m1-m2 as a denominator
2337
+ //but we've handled all the vertical cases above so can assume it's not vertical
2338
+ //if the b's are different then one is an upper line, the other is a lower, no intersection
2339
+ //m and b will be used to build the perpendicular line thru p2 which we will use to
2340
+ //build the intersection, so must assume slopes are not 0, handle separately
2341
+ if (m1 === m2 && m1 !== 0) {
2342
+ if (b1 === b2) //then the intercept is the point joining the 2 segments
2343
+ {
2344
+ //build the perpendicular line
2345
+ m = -1 / m1;
2346
+ b = p2.y - m * p2.x;
2347
+ X.value[0] = (b2 - b) / (m - m2); //intersect the lines (cannot blow up, m = m2 not possible)
2348
+ Y.value[0] = (m1 * (X.value[0]) + b1);
2349
+ return 1;
2350
+ } else //can not occur
2351
+ {
2352
+ X.value[0] = p2.x;
2353
+ Y.value[0] = p2.y;
2354
+ return 1;
2355
+ }
2356
+ }
2357
+ //slope is zero
2358
+ if (m1 === m2 && m1 === 0) {
2359
+ switch (lOrient) {
2360
+ case 0: //Line1 above the line
2361
+ case 1: { //should never happen
2362
+ X.value[0] = p2.x;
2363
+ Y.value[0] = p2.y - dWidth2;
2364
+ break;
2365
+ }
2366
+
2367
+ case 3: //Line1 below the line
2368
+ case 2: { //should never happen
2369
+ X.value[0] = p2.x;
2370
+ Y.value[0] = p2.y + dWidth2;
2371
+ break;
2372
+ }
2373
+
2374
+ default: { //can not occur
2375
+ X.value[0] = p2.x;
2376
+ Y.value[0] = p2.y;
2377
+ break;
2378
+ }
2379
+
2380
+ }
2381
+ return 1;
2382
+ }
2383
+
2384
+ if (m1 === m2 && b1 === b2 && bolVerticalSlope1 !== 0 && bolVerticalSlope2 !== 0) {
2385
+ switch (lOrient) {
2386
+ case 0: { //Line1 is above the line
2387
+ if (m1 < 0) {
2388
+ dy = m1 * dWidth / Math.sqrt(1 + m1 * m1); //dy is negative
2389
+ dx = dy / m1; //dx is negative
2390
+ X.value[0] = p2.x + dx;
2391
+ Y.value[0] = p2.y + dy;
2392
+ }
2393
+ if (m1 > 0) //slope is positive
2394
+ {
2395
+ dy = -m1 * dWidth / Math.sqrt(1 + m1 * m1); //dy is negative
2396
+ dx = -dy / m1; //dx is positive
2397
+ X.value[0] = p2.x + dx;
2398
+ Y.value[0] = p2.y + dy;
2399
+ }
2400
+ break;
2401
+ }
2402
+
2403
+ case 3: { //Line1 is below the line
2404
+ if (m1 <= 0) {
2405
+ dy = -m1 * dWidth / Math.sqrt(1 + m1 * m1); //dy is positive
2406
+ dx = dy / m1; //dx is positive
2407
+ X.value[0] = p2.x + dx;
2408
+ Y.value[0] = p2.y + dy;
2409
+ } else {
2410
+ dy = m1 * dWidth / Math.sqrt(1 + m1 * m1); //dy is positive
2411
+ dx = -dy / m1; //dx is negative
2412
+ X.value[0] = p2.x + dx;
2413
+ Y.value[0] = p2.y + dy;
2414
+ }
2415
+ break;
2416
+ }
2417
+
2418
+ default: {
2419
+ X.value[0] = p2.x;
2420
+ Y.value[0] = p2.y;
2421
+ break;
2422
+ }
2423
+
2424
+ }
2425
+ return 1;
2426
+ }//end if
2427
+
2428
+ //a normal line. no vertical or identical slopes
2429
+ //if m1=m2 function will not reach this point
2430
+ X.value[0] = (b2 - b1) / (m1 - m2); //intersect the lines
2431
+ Y.value[0] = (m1 * (X.value[0]) + b1);
2432
+ return 1;
2433
+ } catch (exc) {
2434
+ if (exc instanceof Error) {
2435
+ X.value[0] = p2.x;
2436
+ Y.value[0] = p2.y;
2437
+ ErrorLogger.LogException(lineutility._className, "CalcTrueIntersectDouble",
2438
+ new RendererException("Failed inside ExtendTrueIntersectDouble", exc));
2439
+ } else {
2440
+ throw exc;
2441
+ }
2442
+ }
2443
+ return 1;
2444
+ }
2445
+
2446
+ /**
2447
+ * Returns the distance in pixels from x1,y1 to x2,y2
2448
+ *
2449
+ * @param x1 first point x location in pixels
2450
+ * @param y1 first point y location in pixels
2451
+ * @param x2 second point x location in pixels
2452
+ * @param y2 second point y location in pixels
2453
+ *
2454
+ * @return the distance
2455
+ */
2456
+ static CalcDistance2(x1: number,
2457
+ y1: number,
2458
+ x2: number,
2459
+ y2: number): double {
2460
+ let dResult: double = 0;
2461
+ try {
2462
+ dResult = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
2463
+
2464
+ //sanity check
2465
+ //return x or y distance if return value is 0 or infinity
2466
+ let xdist: double = Math.abs(x1 - x2);
2467
+ let ydist: double = Math.abs(y1 - y2);
2468
+ let max: double = xdist;
2469
+ if (ydist > xdist) {
2470
+ max = ydist;
2471
+ }
2472
+ if (dResult === 0 || !Number.isFinite(dResult)) {
2473
+ if (max > 0) {
2474
+ dResult = max;
2475
+ }
2476
+ }
2477
+ } catch (exc) {
2478
+ if (exc instanceof Error) {
2479
+ ErrorLogger.LogException(lineutility._className, "CalcDistance2",
2480
+ new RendererException("Failed inside CalcDistance2", exc));
2481
+ } else {
2482
+ throw exc;
2483
+ }
2484
+ }
2485
+ return dResult;
2486
+ }
2487
+ /**
2488
+ * gets the middle line for Rev B air corridors AC, LLTR, MRR, UAV
2489
+ * Middle line is handled separately now because the line may have been segmented
2490
+ * @param pLinePoints
2491
+ * @return
2492
+ */
2493
+ protected static GetSAAFRMiddleLine(pLinePoints: POINT2[]): POINT2[] {
2494
+ let pts: POINT2[];
2495
+ try {
2496
+ let j: int = 0;
2497
+ let count: int = 0;
2498
+ for (j = 0; j < pLinePoints.length - 1; j++) {
2499
+ if (pLinePoints[j].style > 0) {
2500
+ count++;
2501
+ }
2502
+ }
2503
+ pts = new Array<POINT2>(count * 2);
2504
+ count = 0;
2505
+ let dMRR: double = 0;
2506
+ let firstSegPt: POINT2;
2507
+ let lastSegPt: POINT2 | null = null;
2508
+ let pt0: POINT2;
2509
+ let pt1: POINT2;
2510
+ for (j = 0; j < pLinePoints.length; j++) {
2511
+ if (pLinePoints[j].style >= 0 || j === pLinePoints.length - 1) {
2512
+ if (lastSegPt != null) {
2513
+ firstSegPt = new POINT2(lastSegPt);
2514
+ lastSegPt = new POINT2(pLinePoints[j]);
2515
+ dMRR = firstSegPt.style;
2516
+ pt0 = lineutility.ExtendLine2Double(lastSegPt, firstSegPt, -dMRR, 0);
2517
+ pt1 = lineutility.ExtendLine2Double(firstSegPt, lastSegPt, -dMRR, 5);
2518
+ pts[count++] = pt0;
2519
+ pts[count++] = pt1;
2520
+ }
2521
+ else {
2522
+ lastSegPt = new POINT2(pLinePoints[j]);
2523
+ }
2524
+ }
2525
+ }
2526
+ } catch (exc) {
2527
+ if (exc instanceof Error) {
2528
+ ErrorLogger.LogException(lineutility._className, "GetSAAFRMiddleLine",
2529
+ new RendererException("Failed inside GetSAAFRMiddleLine", exc));
2530
+ } else {
2531
+ throw exc;
2532
+ }
2533
+ }
2534
+ return pts;
2535
+ }
2536
+ /**
2537
+ * Computes the points for a SAAFR segment
2538
+ *
2539
+ * @param pLinePoints OUT - the client points also used for the returned
2540
+ * points
2541
+ * @param lineType the line type
2542
+ * @param dMRR the symbol width
2543
+ */
2544
+ static GetSAAFRSegment(pLinePoints: POINT2[],
2545
+ lineType: int,
2546
+ dMRR: double): void {
2547
+ try {
2548
+ let pt0: POINT2 = new POINT2();
2549
+ let pt1: POINT2 = new POINT2();
2550
+ let pt2: POINT2 = new POINT2();
2551
+ let pt3: POINT2 = new POINT2();
2552
+ let pt4: POINT2 = new POINT2();
2553
+ let pt5: POINT2 = new POINT2();
2554
+ let m: ref<number[]> = new ref();
2555
+ let bolVertical: int = lineutility.CalcTrueSlopeDouble(pLinePoints[0], pLinePoints[1], m);
2556
+ //shortened line
2557
+ //pt1=ExtendLine2Double(pLinePoints[0],pLinePoints[1],-dMRR/2,5);
2558
+ //pt0=ExtendLine2Double(pLinePoints[1],pLinePoints[0],-dMRR/2,0);
2559
+ pt1 = lineutility.ExtendLine2Double(pLinePoints[0], pLinePoints[1], -dMRR, 5);
2560
+ pt0 = lineutility.ExtendLine2Double(pLinePoints[1], pLinePoints[0], -dMRR, 0);
2561
+ if (bolVertical !== 0 && m.value[0] < 1) {
2562
+ //upper line
2563
+ pt2 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 2, dMRR);
2564
+ pt2.style = 0;
2565
+ pt3 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 2, dMRR);
2566
+ pt3.style = 5;
2567
+ //lower line
2568
+ pt4 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 3, dMRR);
2569
+ pt4.style = 0;
2570
+ pt5 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 3, dMRR);
2571
+ pt5.style = 5;
2572
+ } //if( (bolVertical!=0 && m>1) || bolVertical==0)
2573
+ else {
2574
+ //left line
2575
+ pt2 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 0, dMRR);
2576
+ pt2.style = 0;
2577
+ pt3 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 0, dMRR);
2578
+ pt3.style = 5;
2579
+ //right line
2580
+ pt4 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 1, dMRR);
2581
+ pt4.style = 0;
2582
+ pt5 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 1, dMRR);
2583
+ pt5.style = 5;
2584
+ }
2585
+ //load the line points
2586
+ pLinePoints[0] = new POINT2(pt0);
2587
+ pLinePoints[1] = new POINT2(pt1);
2588
+ pLinePoints[2] = new POINT2(pt2);
2589
+ pLinePoints[3] = new POINT2(pt3);
2590
+ pLinePoints[4] = new POINT2(pt4);
2591
+ pLinePoints[5] = new POINT2(pt5);
2592
+ pLinePoints[5].style = 5;
2593
+ pLinePoints[0].style = 5;
2594
+ } catch (exc) {
2595
+ if (exc instanceof Error) {
2596
+ ErrorLogger.LogException(lineutility._className, "GetSAAFRSegment",
2597
+ new RendererException("Failed inside GetSAAFRSegment", exc));
2598
+ } else {
2599
+ throw exc;
2600
+ }
2601
+ }
2602
+ }
2603
+ /**
2604
+ * Called by arraysupport for SAAFR and AC fill shapes
2605
+ * @param pLinePoints
2606
+ * @param dMRR
2607
+ */
2608
+ static GetSAAFRFillSegment(pLinePoints: POINT2[],
2609
+ dMRR: double): void {
2610
+ try {
2611
+ let pt2: POINT2 = new POINT2();
2612
+ let pt3: POINT2 = new POINT2();
2613
+ let pt4: POINT2 = new POINT2();
2614
+ let pt5: POINT2 = new POINT2();
2615
+ let m: ref<number[]> = new ref();
2616
+ let bolVertical: int = lineutility.CalcTrueSlopeDouble(pLinePoints[0], pLinePoints[1], m);
2617
+ if (bolVertical !== 0 && m.value[0] < 1) {
2618
+ //upper line
2619
+ pt2 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 2, dMRR);
2620
+ pt3 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 2, dMRR);
2621
+ //lower line
2622
+ pt4 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 3, dMRR);
2623
+ pt5 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 3, dMRR);
2624
+ } //if( (bolVertical!=0 && m>1) || bolVertical==0)
2625
+ else {
2626
+ //left line
2627
+ pt2 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 0, dMRR);
2628
+ pt3 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 0, dMRR);
2629
+ //right line
2630
+ pt4 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 1, dMRR);
2631
+ pt5 = lineutility.ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 1, dMRR);
2632
+ }
2633
+ //load the line points
2634
+ pLinePoints[0] = new POINT2(pt2);
2635
+ pLinePoints[1] = new POINT2(pt3);
2636
+ pLinePoints[2] = new POINT2(pt5);
2637
+ pLinePoints[3] = new POINT2(pt4);
2638
+ } catch (exc) {
2639
+ if (exc instanceof Error) {
2640
+ ErrorLogger.LogException(lineutility._className, "GetSAAFRFillSegment",
2641
+ new RendererException("Failed inside GetSAAFRFillSegment", exc));
2642
+ } else {
2643
+ throw exc;
2644
+ }
2645
+ }
2646
+ //return;
2647
+ }
2648
+ /**
2649
+ * Computes an arc.
2650
+ *
2651
+ * @param pResultLinePoints OUT - contains center and start point and holds
2652
+ * the result arc points
2653
+ * @param vblCounter the number of client points
2654
+ * @param dRadius the arc radius in pixels
2655
+ * @param linetype the linetype determines start andgle and end angle for
2656
+ * the arc
2657
+ *
2658
+ */
2659
+ static ArcArrayDouble(pResultLinePoints: POINT2[],
2660
+ vblCounter: int,
2661
+ dRadius: double,
2662
+ linetype: int,
2663
+ converter: IPointConversion | null): POINT2[] {
2664
+ try {
2665
+ //declarations
2666
+ let startangle: double = 0;
2667
+ let //start of pArcLinePoints
2668
+ endangle: double = 0;
2669
+ let //end of the pArcLinePoints
2670
+ increment: double = 0;
2671
+ let
2672
+ //m = 0,
2673
+ length: double = 0;
2674
+ let //length of a to e
2675
+ M: double = 0;
2676
+
2677
+ let j: int = 0;
2678
+ let numarcpts: int = 0;
2679
+ let bolVertical: int = 0;
2680
+ let m: ref<number[]> = new ref();
2681
+ //C is the center of the pArcLinePoints derived from a and e
2682
+ let C: POINT2 = new POINT2(pResultLinePoints[0]);
2683
+ let
2684
+ a: POINT2 = new POINT2(pResultLinePoints[1]);
2685
+ let
2686
+ e: POINT2 = new POINT2(pResultLinePoints[0]);
2687
+
2688
+ let pArcLinePoints: POINT2[];
2689
+ //end declarations
2690
+
2691
+ bolVertical = lineutility.CalcTrueSlopeDouble(a, e, m);
2692
+ if (bolVertical !== 0) {
2693
+ M = Math.atan(m.value[0]);
2694
+ } else {
2695
+ if (a.y < e.y) {
2696
+ M = -Math.PI / 2;
2697
+ } else {
2698
+ M = Math.PI / 2;
2699
+ }
2700
+ }
2701
+ if (converter != null) {
2702
+ let pt02d: Point2D = new Point2D(pResultLinePoints[0].x, pResultLinePoints[0].y);
2703
+ let pt12d: Point2D = new Point2D(pResultLinePoints[1].x, pResultLinePoints[1].y);
2704
+ //boolean reverseM=false;
2705
+ pt02d = converter.PixelsToGeo(pt02d);
2706
+ pt12d = converter.PixelsToGeo(pt12d);
2707
+ //M=mdlGeodesic.GetAzimuth(pt02d,pt12d);
2708
+ M = mdlGeodesic.GetAzimuth(new POINT2(pt02d.getX(), pt02d.getY()), new POINT2(pt12d.getX(), pt12d.getY()));
2709
+ M *= (Math.PI / 180);
2710
+ if (M < 0) {
2711
+
2712
+ M += Math.PI;
2713
+ }
2714
+
2715
+ }
2716
+ length = lineutility.CalcDistanceDouble(a, e);
2717
+ if (converter != null) {
2718
+ let pt02d: Point2D = new Point2D(pResultLinePoints[0].x, pResultLinePoints[0].y);
2719
+ let pt12d: Point2D = new Point2D(pResultLinePoints[1].x, pResultLinePoints[1].y);
2720
+ pt02d = converter.PixelsToGeo(pt02d);
2721
+ pt12d = converter.PixelsToGeo(pt12d);
2722
+ //length=mdlGeodesic.geodesic_distance(pt02d,pt12d,null,null);
2723
+ length = mdlGeodesic.geodesic_distance(new POINT2(pt02d.getX(), pt02d.getY()), new POINT2(pt12d.getX(), pt12d.getY()), null, null);
2724
+ }
2725
+ switch (linetype) {
2726
+ case TacticalLines.CLUSTER: {
2727
+ startangle = M - 90 * Math.PI / 180.0;
2728
+ endangle = startangle + 2 * 90 * Math.PI / 180.0;
2729
+ break;
2730
+ }
2731
+
2732
+ case TacticalLines.ISOLATE:
2733
+ case TacticalLines.CORDONKNOCK:
2734
+ case TacticalLines.CORDONSEARCH: {
2735
+ startangle = M;
2736
+ endangle = startangle + 330 * Math.PI / 180;
2737
+ break;
2738
+ }
2739
+
2740
+ case TacticalLines.TURN: {
2741
+ startangle = M;
2742
+ endangle = startangle + 90 * Math.PI / 180;
2743
+ break;
2744
+ }
2745
+
2746
+ case TacticalLines.OCCUPY:
2747
+ case TacticalLines.RETAIN:
2748
+ case TacticalLines.SECURE: {
2749
+ startangle = M;
2750
+ //if(CELineArrayGlobals.Change1==false)
2751
+ endangle = startangle + 338 * Math.PI / 180;
2752
+ //else
2753
+ // endangle=startangle+330*pi/180;
2754
+ break;
2755
+ }
2756
+
2757
+ default: {
2758
+ startangle = 0;
2759
+ endangle = 2 * Math.PI;
2760
+ break;
2761
+ }
2762
+
2763
+ }
2764
+
2765
+ if (a.x < e.x) {
2766
+ switch (linetype) {
2767
+ case TacticalLines.ISOLATE:
2768
+ case TacticalLines.CORDONKNOCK:
2769
+ case TacticalLines.CORDONSEARCH: {
2770
+ startangle = M - Math.PI;
2771
+ endangle = startangle + 330 * Math.PI / 180;
2772
+ break;
2773
+ }
2774
+
2775
+ case TacticalLines.OCCUPY:
2776
+ case TacticalLines.RETAIN:
2777
+ case TacticalLines.SECURE: {
2778
+ startangle = M - Math.PI;
2779
+ //if(CELineArrayGlobals.Change1==false)
2780
+ endangle = startangle + 338 * Math.PI / 180;
2781
+ //else
2782
+ // endangle=startangle+330*pi/180;
2783
+ break;
2784
+ }
2785
+
2786
+ case TacticalLines.TURN: {
2787
+ startangle = M - Math.PI;
2788
+ endangle = startangle + 90 * Math.PI / 180;
2789
+ break;
2790
+ }
2791
+
2792
+ case TacticalLines.CLUSTER: {
2793
+ startangle = M - Math.PI + 90 * Math.PI / 180.0;
2794
+ endangle = startangle - 2 * 90 * Math.PI / 180.0;
2795
+ break;
2796
+ }
2797
+
2798
+ default: {
2799
+ break;
2800
+ }
2801
+
2802
+ }
2803
+ }
2804
+
2805
+ numarcpts = 26;
2806
+ pArcLinePoints = new Array<POINT2>(numarcpts);
2807
+ lineutility.InitializePOINT2Array(pArcLinePoints);
2808
+ increment = (endangle - startangle) / (numarcpts - 1);
2809
+ if (dRadius !== 0 && length !== 0) {
2810
+ C.x = (e.x as double - (dRadius / length)
2811
+ * Math.trunc(a.x as double - e.x as double));
2812
+ C.y = (e.y as double - (dRadius / length)
2813
+ * Math.trunc(a.y as double - e.y as double));
2814
+ }
2815
+ else {
2816
+ C.x = e.x;
2817
+ C.y = e.y;
2818
+ }
2819
+ if (converter != null) {
2820
+ let C2d: Point2D = new Point2D(pResultLinePoints[0].x, pResultLinePoints[0].y);
2821
+ C2d = converter.PixelsToGeo(C2d);
2822
+ let az: double = 0;
2823
+ let ptGeo2d: Point2D;
2824
+ let ptGeo: POINT2;
2825
+ let ptPixels: POINT2;
2826
+ for (j = 0; j < numarcpts; j++) {
2827
+ az = startangle * 180 / Math.PI + j * increment * 180 / Math.PI;
2828
+ //ptGeo=mdlGeodesic.geodesic_coordinate(C2d,length,az);
2829
+ ptGeo = mdlGeodesic.geodesic_coordinate(new POINT2(C2d.getX(), C2d.getY()), length, az);
2830
+ ptGeo2d = new Point2D(ptGeo.x, ptGeo.y);
2831
+ ptGeo2d = converter.GeoToPixels(ptGeo2d);
2832
+ ptPixels = new POINT2(ptGeo2d.getX(), ptGeo2d.getY());
2833
+ pArcLinePoints[j].x = ptPixels.x;
2834
+ pArcLinePoints[j].y = ptPixels.y;
2835
+ }
2836
+ }
2837
+ else {
2838
+ for (j = 0; j < numarcpts; j++) {
2839
+ //pArcLinePoints[j]=pResultLinePoints[0]; //initialize
2840
+ pArcLinePoints[j].x = Math.trunc(dRadius * Math.cos(startangle + j * increment));
2841
+ pArcLinePoints[j].y = Math.trunc(dRadius * Math.sin(startangle + j * increment));
2842
+ }
2843
+
2844
+ for (j = 0; j < numarcpts; j++) {
2845
+ pArcLinePoints[j].x += C.x;
2846
+ pArcLinePoints[j].y += C.y;
2847
+ }
2848
+ }
2849
+ for (j = 0; j < numarcpts; j++) {
2850
+ pResultLinePoints[j] = new POINT2(pArcLinePoints[j]);
2851
+ }
2852
+ } catch (exc) {
2853
+ if (exc instanceof Error) {
2854
+ ErrorLogger.LogException(lineutility._className, "ArcArrayDouble",
2855
+ new RendererException("Failed inside ArcArrayDouble", exc));
2856
+ } else {
2857
+ throw exc;
2858
+ }
2859
+ }
2860
+ return pResultLinePoints;
2861
+ }
2862
+ /**
2863
+ * Gets geodesic circle using the converter
2864
+ * @param Center in pixels
2865
+ * @param pt1 a point on the radius in pixels
2866
+ * @param numpts number of points to return
2867
+ * @param CirclePoints the result points
2868
+ * @param converter
2869
+ */
2870
+ static CalcCircleDouble2(Center: POINT2,
2871
+ pt1: POINT2,
2872
+ numpts: int,
2873
+ CirclePoints: POINT2[],
2874
+ converter: IPointConversion): void {
2875
+ try {
2876
+ let j: int = 0;
2877
+ let increment: double = (Math.PI * 2) / (numpts - 1);
2878
+ let ptCenter2d: Point2D = new Point2D(Center.x, Center.y);
2879
+ ptCenter2d = converter.PixelsToGeo(ptCenter2d);
2880
+ let pt12d: Point2D = new Point2D(pt1.x, pt1.y);
2881
+ pt12d = converter.PixelsToGeo(pt12d);
2882
+ Center = new POINT2(ptCenter2d.getX(), ptCenter2d.getY());
2883
+ pt1 = new POINT2(pt12d.getX(), pt12d.getY());
2884
+ let dist: double = mdlGeodesic.geodesic_distance(Center, pt1, null, null);
2885
+
2886
+ //double dSegmentAngle = 2 * Math.PI / numpts;
2887
+ let az: double = 0;
2888
+ let startangle: double = 0;
2889
+ let endAngle: double = Math.PI * 2;
2890
+ let ptGeo: POINT2;
2891
+ let ptPixels: POINT2;
2892
+ let ptGeo2d: Point2D;
2893
+ for (j = 0; j < numpts - 1; j++) {
2894
+ az = startangle * 180 / Math.PI + j * increment * 180 / Math.PI;
2895
+ //ptGeo=mdlGeodesic.geodesic_coordinate(C2d,length,az);
2896
+ ptGeo = mdlGeodesic.geodesic_coordinate(Center, dist, az);
2897
+ ptGeo2d = new Point2D(ptGeo.x, ptGeo.y);
2898
+ ptGeo2d = converter.GeoToPixels(ptGeo2d);
2899
+ ptPixels = new POINT2(ptGeo2d.getX(), ptGeo2d.getY());
2900
+ CirclePoints[j].x = ptPixels.x;
2901
+ CirclePoints[j].y = ptPixels.y;
2902
+ }
2903
+ CirclePoints[numpts - 1] = new POINT2(CirclePoints[0]);
2904
+
2905
+ } catch (exc) {
2906
+ if (exc instanceof Error) {
2907
+ ErrorLogger.LogException(lineutility._className, "CalcCircleDouble2",
2908
+ new RendererException("Failed inside CalcCircleDouble2", exc));
2909
+ } else {
2910
+ throw exc;
2911
+ }
2912
+ }
2913
+ return;
2914
+ }
2915
+ /**
2916
+ * Computes the points for a circle. Assumes CirclePoints has been allocated
2917
+ * with size numpts.
2918
+ *
2919
+ * @param Center the cicle center
2920
+ * @param radius the circle radius in pixels
2921
+ * @param numpts the number of circle points
2922
+ * @param CirclePoints - OUT - array of circle points
2923
+ * @param styl the style to set the last circle point
2924
+ */
2925
+ static CalcCircleDouble(Center: POINT2,
2926
+ radius: double,
2927
+ numpts: int,
2928
+ CirclePoints: POINT2[],
2929
+ styl: int): void {
2930
+ try {
2931
+ let j: int = 0;
2932
+ let dSegmentAngle: double = 2 * Math.PI / (numpts - 1);
2933
+ let x: double = 0;
2934
+ let y: double = 0;
2935
+ for (j = 0; j < numpts - 1; j++) {
2936
+ x = Center.x + (radius * Math.cos(j as double * dSegmentAngle));
2937
+ y = Center.y + (radius * Math.sin(j as double * dSegmentAngle));
2938
+ CirclePoints[j] = new POINT2(x, y);
2939
+ CirclePoints[j].style = styl;
2940
+ }
2941
+ CirclePoints[numpts - 1] = new POINT2(CirclePoints[0]);
2942
+
2943
+ switch (styl) {
2944
+ case 0: {
2945
+ CirclePoints[numpts - 1].style = 0;
2946
+ break;
2947
+ }
2948
+
2949
+ case 9: {
2950
+ CirclePoints[numpts - 1].style = 10;
2951
+ break;
2952
+ }
2953
+
2954
+ case 11: {
2955
+ CirclePoints[numpts - 1].style = 12;
2956
+ break;
2957
+ }
2958
+
2959
+ default: {
2960
+ CirclePoints[numpts - 1].style = 5;
2961
+ break;
2962
+ }
2963
+
2964
+ }
2965
+ } catch (exc) {
2966
+ if (exc instanceof Error) {
2967
+ ErrorLogger.LogException(lineutility._className, "CalcCircleDouble",
2968
+ new RendererException("Failed inside CalcCircleDouble", exc));
2969
+ } else {
2970
+ throw exc;
2971
+ }
2972
+ }
2973
+ }
2974
+
2975
+ static CalcCircleShape(Center: POINT2,
2976
+ radius: double,
2977
+ numpts: int,
2978
+ CirclePoints: POINT2[],
2979
+ styl: int): Shape2 {
2980
+ let shape: Shape2;
2981
+ if (styl === 9) {
2982
+ shape = new Shape2(Shape2.SHAPE_TYPE_FILL);
2983
+ } else {
2984
+ shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
2985
+ }
2986
+
2987
+ shape.set_Style(styl);
2988
+ try {
2989
+ let j: int = 0;
2990
+ lineutility.CalcCircleDouble(Center, radius, numpts, CirclePoints, styl);
2991
+ shape.moveTo(CirclePoints[0]);
2992
+ for (j = 1; j < numpts; j++) {
2993
+ shape.lineTo(CirclePoints[j]);
2994
+ }
2995
+ } catch (exc) {
2996
+ if (exc instanceof Error) {
2997
+ ErrorLogger.LogException(lineutility._className, "CalcCircleShape",
2998
+ new RendererException("Failed inside CalcCircleShape", exc));
2999
+ } else {
3000
+ throw exc;
3001
+ }
3002
+ }
3003
+ return shape;
3004
+ }
3005
+
3006
+ private static GetSquallCurve(StartPt: POINT2,
3007
+ EndPt: POINT2,
3008
+ pSquallPts: POINT2[],
3009
+ sign: int,
3010
+ amplitude: double,
3011
+ quantity: int): void {
3012
+ try {
3013
+ let dist: double = lineutility.CalcDistanceDouble(StartPt, EndPt);
3014
+ let ptTemp: POINT2 = new POINT2();
3015
+ let j: int = 0;
3016
+ //end declarations
3017
+
3018
+ //get points along the horizontal segment between StartPt and EndPt2;
3019
+ for (j = 0; j < quantity; j++) {
3020
+ ptTemp = lineutility.ExtendLineDouble(EndPt, StartPt, -dist * j as double / quantity as double);
3021
+ pSquallPts[j].x = ptTemp.x;
3022
+ //calculate the sin value along the x axis
3023
+ pSquallPts[j].y = ptTemp.y + amplitude * sign * Math.sin(j as double * 180 / quantity as double * Math.PI / 180);
3024
+ }
3025
+ } catch (exc) {
3026
+ if (exc instanceof Error) {
3027
+ ErrorLogger.LogException(lineutility._className, "GetSquallShape",
3028
+ new RendererException("Failed inside GeSquallShape", exc));
3029
+ } else {
3030
+ throw exc;
3031
+ }
3032
+ }
3033
+ }
3034
+ //caller needs to instantiate sign.value
3035
+ /**
3036
+ * Gets the squall curves for a line segment Assumes pSquallPts has been
3037
+ * allocated the proper number of points.
3038
+ *
3039
+ * @param StartPt segment start point
3040
+ * @param EndPt segment end point
3041
+ * @param pSquallPts OUT - the squall points
3042
+ * @param sign OUT - an object with a member to hold the starting curve sign
3043
+ * for the segment.
3044
+ * @param amplitude the sin curve amplitutde
3045
+ * @param quantity the number of points for each sin curve
3046
+ * @param length the desired length of the curve along the segment for each
3047
+ * sin curve
3048
+ *
3049
+ * @return segment squall points count
3050
+ */
3051
+ static GetSquallSegment(StartPt: POINT2,
3052
+ EndPt: POINT2,
3053
+ pSquallPts: POINT2[],
3054
+ sign: ref<number[]>,
3055
+ amplitude: double,
3056
+ quantity: int,
3057
+ length: double): int {
3058
+ let counter: int = 0;
3059
+ try {
3060
+ let StartCurvePt: POINT2;
3061
+ let EndCurvePt: POINT2; //use these for the curve points
3062
+ let pSquallPts2: POINT2[] = new Array<POINT2>(quantity);
3063
+ let dist: double = lineutility.CalcDistanceDouble(StartPt, EndPt);
3064
+ let numCurves: int = Math.trunc(dist / length as double);
3065
+ let j: int = 0;
3066
+ let k: int = 0;
3067
+ let EndPt2: POINT2 = new POINT2();
3068
+ let angle: double = Math.atan((StartPt.y - EndPt.y) / (StartPt.x - EndPt.x));
3069
+ let lAngle: int = Math.trunc((180 / Math.PI) * angle);
3070
+ lineutility.InitializePOINT2Array(pSquallPts2);
3071
+ //define EndPt2 to be the point dist from StartPt along the x axis
3072
+ if (StartPt.x < EndPt.x) {
3073
+ EndPt2.x = StartPt.x + dist;
3074
+ } else {
3075
+ EndPt2.x = StartPt.x - dist;
3076
+ }
3077
+
3078
+ EndPt2.y = StartPt.y;
3079
+
3080
+ EndCurvePt = StartPt;
3081
+ for (j = 0; j < numCurves; j++) {
3082
+ StartCurvePt = lineutility.ExtendLineDouble(EndPt2, StartPt, - (j * length) as double);
3083
+ EndCurvePt = lineutility.ExtendLineDouble(EndPt2, StartPt, - ((j + 1) * length) as double);
3084
+
3085
+ //get the curve points
3086
+ lineutility.GetSquallCurve(StartCurvePt, EndCurvePt, pSquallPts2, sign.value[0], amplitude, quantity);
3087
+
3088
+ //fill the segment points with the curve points
3089
+ for (k = 0; k < quantity; k++) {
3090
+ //pSquallPts[counter].x=pSquallPts2[k].x;
3091
+ //pSquallPts[counter].y=pSquallPts2[k].y;
3092
+ pSquallPts[counter] = new POINT2(pSquallPts2[k]);
3093
+ counter++;
3094
+ }
3095
+ //reverse the sign
3096
+
3097
+ sign.value[0] = -sign.value[0];
3098
+ }
3099
+ if (numCurves === 0) {
3100
+ pSquallPts[counter] = new POINT2(StartPt);
3101
+ counter++;
3102
+ pSquallPts[counter] = new POINT2(EndPt);
3103
+ counter++;
3104
+ }
3105
+ //the points are along the x axis. Rotate them about the first point as the origin
3106
+ lineutility.RotateGeometryDoubleOrigin(pSquallPts, counter, lAngle);
3107
+ } catch (exc) {
3108
+ if (exc instanceof Error) {
3109
+ ErrorLogger.LogException(lineutility._className, "GetSquallSegment",
3110
+ new RendererException("Failed inside GetSquallSegment", exc));
3111
+ } else {
3112
+ throw exc;
3113
+ }
3114
+ }
3115
+ return counter;
3116
+ }
3117
+
3118
+ //temporarily using 2000 pixels
3119
+ private static PointInBounds(pt: POINT2): int {
3120
+ try {
3121
+ //double maxPixels=CELineArrayGlobals.MaxPixels2;
3122
+ let maxPixels: double = 100000;//was 2000
3123
+ if (Math.abs(pt.x) <= maxPixels && Math.abs(pt.y) <= maxPixels) {
3124
+ return 1;
3125
+ } else {
3126
+ return 0;
3127
+ }
3128
+ } catch (exc) {
3129
+ if (exc instanceof Error) {
3130
+ ErrorLogger.LogException(lineutility._className, "PointInBounds",
3131
+ new RendererException("Failed inside PointInBounds", exc));
3132
+ } else {
3133
+ throw exc;
3134
+ }
3135
+ }
3136
+ return 1;
3137
+ }
3138
+
3139
+ /**
3140
+ * @param pt
3141
+ * @param ul
3142
+ * @param lr
3143
+ * @return
3144
+ */
3145
+ private static PointInBounds2(pt: POINT2, ul: POINT2, lr: POINT2): int {
3146
+ try {
3147
+ let maxX: double = lr.x;
3148
+ let minX: double = ul.x;
3149
+ let maxY: double = lr.y;
3150
+ let minY: double = ul.y;
3151
+ if (pt.x <= maxX && pt.x >= minX && pt.y <= maxY && pt.y >= minY) {
3152
+ return 1;
3153
+ } else {
3154
+ return 0;
3155
+ }
3156
+ } catch (exc) {
3157
+ if (exc instanceof Error) {
3158
+ ErrorLogger.LogException(lineutility._className, "PointInBounds2",
3159
+ new RendererException("Failed inside PointInBounds2", exc));
3160
+ } else {
3161
+ throw exc;
3162
+ }
3163
+ }
3164
+ return 1;
3165
+ }
3166
+
3167
+ /**
3168
+ * Analyzes if line from pt0 to pt 1 intersects a side and returns the
3169
+ * intersection or null assumes pt0 to pt1 is not vertical. the caller will
3170
+ * replace pt0 with the intersection point if it is not null
3171
+ *
3172
+ * @param pt0
3173
+ * @param pt1
3174
+ * @param sidePt0 vertical or horizontal side first point
3175
+ * @param sidePt1
3176
+ * @return null if it does not intersect the side
3177
+ */
3178
+ private static intersectSegment(pt0: POINT2, pt1: POINT2, sidePt0: POINT2, sidePt1: POINT2): POINT2 | null {
3179
+ let pt: POINT2;
3180
+ try {
3181
+ if (pt0.x === pt1.x) {
3182
+ return null;
3183
+ }
3184
+ let m: double = (pt1.y - pt0.y) / (pt1.x - pt0.x);
3185
+ let dx: double = 0;
3186
+ let dy: double = 0;
3187
+ let x: double = 0;
3188
+ let y: double = 0;
3189
+ let upper: POINT2;
3190
+ let lower: POINT2;
3191
+ let left: POINT2;
3192
+ let right: POINT2;
3193
+ let bolVertical: boolean = false;
3194
+ //the side is either vertical or horizontal
3195
+ if (sidePt0.x === sidePt1.x) //vertical side
3196
+ {
3197
+ bolVertical = true;
3198
+ if (sidePt0.y < sidePt1.y) {
3199
+ upper = sidePt0;
3200
+ lower = sidePt1;
3201
+ } else {
3202
+ upper = sidePt1;
3203
+ lower = sidePt0;
3204
+ }
3205
+ } else //horizontal side
3206
+ {
3207
+ if (sidePt0.x < sidePt1.x) {
3208
+ left = sidePt0;
3209
+ right = sidePt1;
3210
+ } else {
3211
+ left = sidePt1;
3212
+ right = sidePt0;
3213
+ }
3214
+ }
3215
+ //travel in the direction from pt0 to pt1 to find the pt0 intersect
3216
+ if (bolVertical) { //the side to intersect is vertical
3217
+ dx = upper.x - pt0.x;
3218
+ dy = m * dx;
3219
+ x = upper.x;
3220
+ y = pt0.y + dy;
3221
+ //the potential intersection point
3222
+ pt = new POINT2(x, y);
3223
+
3224
+ if (pt0.x <= pt.x && pt.x <= pt1.x) //left to right
3225
+ {
3226
+ if (upper.y <= pt.y && pt.y <= lower.y) {
3227
+ return pt;
3228
+ }
3229
+ } else {
3230
+ if (pt0.x >= pt.x && pt.x >= pt1.x) //right to left
3231
+ {
3232
+ if (upper.y <= pt.y && pt.y <= lower.y) {
3233
+ return pt;
3234
+ }
3235
+ }
3236
+ }
3237
+
3238
+ } else //horizontal side
3239
+ {
3240
+ dy = left.y - pt0.y;
3241
+ dx = dy / m;
3242
+ x = pt0.x + dx;
3243
+ y = left.y;
3244
+ //the potential intersection point
3245
+ pt = new POINT2(x, y);
3246
+
3247
+ if (pt0.y <= pt.y && pt.y <= pt1.y) {
3248
+ if (left.x <= pt.x && pt.x <= right.x) {
3249
+ return pt;
3250
+ }
3251
+ } else {
3252
+ if (pt0.y >= pt.y && pt.y >= pt1.y) {
3253
+ if (left.x <= pt.x && pt.x <= right.x) {
3254
+ return pt;
3255
+ }
3256
+ }
3257
+ }
3258
+
3259
+ }
3260
+ } catch (exc) {
3261
+ if (exc instanceof Error) {
3262
+ ErrorLogger.LogException(lineutility._className, "intersectSegment",
3263
+ new RendererException("Failed inside intersectSegment", exc));
3264
+ } else {
3265
+ throw exc;
3266
+ }
3267
+ }
3268
+ return null;
3269
+ }
3270
+
3271
+ /**
3272
+ * side 1 ----- | | side 0 | | side 2 | | ------ side 3 bounds one segment
3273
+ * for autoshapes that need it: bydif, fordif, fix, mnfldfix if null is
3274
+ * returned the client should conect the original line points (i.e. no
3275
+ * jaggies)
3276
+ *
3277
+ * @param pt0
3278
+ * @param pt1
3279
+ * @param ul
3280
+ * @param lr
3281
+ * @return bounded segment or null
3282
+ */
3283
+ public static BoundOneSegment(pt0: POINT2, pt1: POINT2, ul: POINT2, lr: POINT2): POINT2[] | null {
3284
+ let line: POINT2[] = new Array<POINT2>(2);
3285
+ try {
3286
+ if (pt0.y < ul.y && pt1.y < ul.y) {
3287
+ return null;
3288
+ }
3289
+ if (pt0.y > lr.y && pt1.y > lr.y) {
3290
+ return null;
3291
+ }
3292
+ if (pt0.x < ul.x && pt1.x < ul.x) {
3293
+ return null;
3294
+ }
3295
+ if (pt0.x > lr.x && pt1.x > lr.x) {
3296
+ return null;
3297
+ }
3298
+
3299
+ let bolVertical: boolean = false;
3300
+ lineutility.InitializePOINT2Array(line);
3301
+ if (pt0.x === pt1.x) {
3302
+ bolVertical = true;
3303
+ }
3304
+
3305
+ if (bolVertical) {
3306
+ line[0] = new POINT2(pt0);
3307
+ if (line[0].y < ul.y) {
3308
+ line[0].y = ul.y;
3309
+ }
3310
+ if (line[0].y > lr.y) {
3311
+ line[0].y = lr.y;
3312
+ }
3313
+
3314
+ line[1] = new POINT2(pt1);
3315
+ if (line[1].y < ul.y) {
3316
+ line[1].y = ul.y;
3317
+ }
3318
+ if (line[1].y > lr.y) {
3319
+ line[1].y = lr.y;
3320
+ }
3321
+
3322
+ return line;
3323
+ }
3324
+
3325
+ let dx: double = 0;
3326
+ let dy: double = 0;
3327
+ let x: double = 0;
3328
+ let y: double = 0;
3329
+ let m: double = (pt1.y - pt0.y) / (pt1.x - pt0.x);
3330
+ let side0Intersect: boolean = false;
3331
+ let
3332
+ side1Intersect: boolean = false;
3333
+ let
3334
+ side2Intersect: boolean = false;
3335
+ let
3336
+ side3Intersect: boolean = false;
3337
+ //travel in the direction from pt0 to pt1 to find pt0 intersect
3338
+ let ur: POINT2 = new POINT2(lr.x, ul.y);
3339
+ let ll: POINT2 = new POINT2(ul.x, lr.y);
3340
+
3341
+ let pt0Intersect: POINT2;
3342
+ if (lineutility.PointInBounds2(pt0, ul, lr) === 1) {
3343
+ pt0Intersect = pt0;
3344
+ }
3345
+ if (pt0Intersect == null) {
3346
+ pt0Intersect = lineutility.intersectSegment(pt0, pt1, ll, ul); //interesect side 0
3347
+ side0Intersect = true;
3348
+ }
3349
+ if (pt0Intersect == null) {
3350
+ pt0Intersect = lineutility.intersectSegment(pt0, pt1, ul, ur); //interesect side 1
3351
+ side1Intersect = true;
3352
+ }
3353
+ if (pt0Intersect == null) {
3354
+ pt0Intersect = lineutility.intersectSegment(pt0, pt1, ur, lr); //interesect side 2
3355
+ side2Intersect = true;
3356
+ }
3357
+ if (pt0Intersect == null) {
3358
+ pt0Intersect = lineutility.intersectSegment(pt0, pt1, ll, lr); //interesect side 3
3359
+ side3Intersect = true;
3360
+ }
3361
+
3362
+ //travel in the direction from pt1 to pt0 to find pt1 intersect
3363
+ let pt1Intersect: POINT2;
3364
+ if (lineutility.PointInBounds2(pt1, ul, lr) === 1) {
3365
+ pt1Intersect = pt1;
3366
+ }
3367
+ if (pt1Intersect == null && side0Intersect === false) {
3368
+ pt1Intersect = lineutility.intersectSegment(pt1, pt0, ll, ul); //interesect side 0
3369
+ }
3370
+ if (pt1Intersect == null && side1Intersect === false) {
3371
+ pt1Intersect = lineutility.intersectSegment(pt1, pt0, ul, ur); //interesect side 1
3372
+ }
3373
+ if (pt1Intersect == null && side2Intersect === false) {
3374
+ pt1Intersect = lineutility.intersectSegment(pt1, pt0, ur, lr); //interesect side 2
3375
+ }
3376
+ if (pt1Intersect == null && side3Intersect === false) {
3377
+ pt1Intersect = lineutility.intersectSegment(pt1, pt0, ll, lr); //interesect side 3
3378
+ }
3379
+
3380
+ if (pt0Intersect != null && pt1Intersect != null) {
3381
+ line[0] = pt0Intersect;
3382
+ line[1] = pt1Intersect;
3383
+ //return line;
3384
+ } else {
3385
+ line = null;
3386
+ }
3387
+ } catch (exc) {
3388
+ if (exc instanceof Error) {
3389
+ ErrorLogger.LogException(lineutility._className, "BoundOneSegment",
3390
+ new RendererException("Failed inside BoundOneSegment", exc));
3391
+ } else {
3392
+ throw exc;
3393
+ }
3394
+ }
3395
+ return line;
3396
+ }
3397
+
3398
+ private static DisplayIntersectPixels(pt0: POINT2,
3399
+ pt1: POINT2,
3400
+ pt2x: ref<number[]>,
3401
+ pt2y: ref<number[]>,
3402
+ pt3x: ref<number[]>,
3403
+ pt3y: ref<number[]>): int //POINT2 ul,
3404
+ //POINT2 lr)
3405
+ {
3406
+ let nResult: int = -1;
3407
+ try {
3408
+ //declarations
3409
+ let X: double = 0;
3410
+ let Y: double = 0;
3411
+ let m: ref<number[]> = new ref();
3412
+ //double maxPixels=CELineArrayGlobals.MaxPixels2;
3413
+ let maxPixels: double = 2000;
3414
+ //double maxX=lr.x,minX=ul.x,maxY=lr.y,minY=ul.y;
3415
+
3416
+ let bol0Inside: int = 0;
3417
+ let bol1Inside: int = 0;
3418
+ let bolVertical: int = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
3419
+ let b: double = pt0.y - m.value[0] * pt0.x; //the y intercept for the segment line
3420
+ let pt2: POINT2;
3421
+ let pt3: POINT2;
3422
+ //end declarations
3423
+
3424
+ pt2x.value = new Array<number>(1);
3425
+ pt2y.value = new Array<number>(1);
3426
+ pt3x.value = new Array<number>(1);
3427
+ pt3y.value = new Array<number>(1);
3428
+ pt2 = new POINT2(pt0);
3429
+ pt3 = new POINT2(pt1);
3430
+
3431
+ //diagnostic
3432
+ if (pt0.x <= maxPixels && pt0.x >= -maxPixels
3433
+ && pt0.y <= maxPixels && pt0.y >= -maxPixels) {
3434
+ bol0Inside = 1;
3435
+ }
3436
+ if (pt1.x <= maxPixels && pt1.x >= -maxPixels
3437
+ && pt1.y <= maxPixels && pt1.y >= -maxPixels) {
3438
+ bol1Inside = 1;
3439
+ }
3440
+ //if both points are inside the area then use the whole segment
3441
+ if (bol0Inside === 1 && bol1Inside === 1) {
3442
+ return 0;
3443
+ }
3444
+ //if at leat one of the points is inside the area then use some of the segment
3445
+ if (bol0Inside === 1 || bol1Inside === 1) {
3446
+ nResult = 1;
3447
+ }
3448
+
3449
+ //segment is not vertical
3450
+ if (bolVertical !== 0) {
3451
+ //analysis for side 0, get the intersection for either point if it exists
3452
+ //diagnostic
3453
+ X = -maxPixels;
3454
+ //X=minX;
3455
+
3456
+ Y = m.value[0] * X + b;
3457
+ if (pt0.x < -maxPixels && -maxPixels < pt1.x) //pt0 is outside the area
3458
+ {
3459
+ if (-maxPixels <= Y && Y <= maxPixels) //intersection is on side 0
3460
+ //if(minY<=Y && Y<=maxY) //intersection is on side 0
3461
+ {
3462
+ pt2.x = X;
3463
+ pt2.y = Y;
3464
+ nResult = 1; //use at least some of the pixels
3465
+ }
3466
+ }
3467
+ if (pt1.x < -maxPixels && -maxPixels < pt0.x) //pt1 is outside the area
3468
+ //if(pt1.x<minX && minX<pt0.x) //pt1 is outside the area
3469
+ {
3470
+ if (-maxPixels <= Y && Y <= maxPixels) //intersection is on side 0
3471
+ {
3472
+ pt3.x = X;
3473
+ pt3.y = Y;
3474
+ nResult = 1; //use at least some of the pixels
3475
+ }
3476
+ }
3477
+
3478
+ //analysis for side 1, get the intersection for either point if it exists
3479
+ Y = -maxPixels;
3480
+ if (m.value[0] !== 0) {
3481
+ X = (Y - b) / m.value[0];
3482
+ if (pt0.y < -maxPixels && -maxPixels < pt1.y) //pt0 is outside the area
3483
+ {
3484
+ if (-maxPixels <= X && X <= maxPixels) //intersection is on side 1
3485
+ {
3486
+ pt2.x = X;
3487
+ pt2.y = Y;
3488
+ nResult = 1; //use at least some of the pixels
3489
+ }
3490
+ }
3491
+ if (pt1.y <= -maxPixels && -maxPixels <= pt0.y) //pt1 is outside the area
3492
+ {
3493
+ if (-maxPixels < X && X < maxPixels) //intersection is on the boundary
3494
+ {
3495
+ pt3.x = X;
3496
+ pt3.y = Y;
3497
+ nResult = 1; //use at least some of the pixels
3498
+ }
3499
+ }
3500
+ }
3501
+ //analysis for side 2, get the intersection for either point if it exists
3502
+ X = maxPixels;
3503
+ Y = m.value[0] * X + b;
3504
+ if (pt0.x < maxPixels && maxPixels < pt1.x) //pt1 is outside the area
3505
+ {
3506
+ if (-maxPixels <= Y && Y <= maxPixels) //intersection is on the boundary
3507
+ {
3508
+ pt3.x = X;
3509
+ pt3.y = Y;
3510
+ nResult = 1; //use at least some of the pixels
3511
+ }
3512
+ }
3513
+ if (pt1.x < maxPixels && maxPixels < pt0.x) //pt0 is outside the area
3514
+ {
3515
+ if (-maxPixels <= Y && Y <= maxPixels) //intersection is on the boundary
3516
+ {
3517
+ pt2.x = X;
3518
+ pt2.y = Y;
3519
+ nResult = 1; //use at least some of the pixels
3520
+ }
3521
+ }
3522
+
3523
+ //analysis for side 3, get the intersection for either point if it exists
3524
+ Y = maxPixels;
3525
+ if (m.value[0] !== 0) {
3526
+ X = (Y - b) / m.value[0];
3527
+ if (pt0.y < maxPixels && maxPixels < pt1.y) //pt1 is outside the area
3528
+ {
3529
+ if (-maxPixels <= X && X <= maxPixels) //intersection is on the boundary
3530
+ {
3531
+ pt3.x = X;
3532
+ pt3.y = Y;
3533
+ nResult = 1; //use at least some of the pixels
3534
+ }
3535
+ }
3536
+ if (pt1.y < maxPixels && maxPixels < pt0.y) //pt0 is outside the area
3537
+ {
3538
+ if (-maxPixels <= X && X <= maxPixels) //intersection is on the boundary
3539
+ {
3540
+ pt2.x = X;
3541
+ pt2.y = Y;
3542
+ nResult = 1; //use at least some of the pixels
3543
+ }
3544
+ }
3545
+ }
3546
+ }
3547
+
3548
+ //segment is vertical
3549
+ if (bolVertical === 0) {
3550
+ //analysis for side 1
3551
+ X = pt0.x;
3552
+ Y = -maxPixels;
3553
+ if (-maxPixels < pt0.x && pt0.x < maxPixels) {
3554
+ if (pt0.y <= -maxPixels && -maxPixels <= pt1.y) //pt0 outside the area
3555
+ {
3556
+ pt2.x = X;
3557
+ pt2.y = Y;
3558
+ nResult = 1; //use at least some of the pixels
3559
+ }
3560
+ if (pt1.y <= -maxPixels && -maxPixels <= pt0.y) //pt1 outside the area
3561
+ {
3562
+ pt3.x = X;
3563
+ pt3.y = Y;
3564
+ nResult = 1; //use at least some of the pixels
3565
+ }
3566
+ }
3567
+
3568
+ //analysis for side 3
3569
+ X = pt0.x;
3570
+ Y = maxPixels;
3571
+ if (-maxPixels < pt0.x && pt0.x < maxPixels) {
3572
+ if (pt0.y <= maxPixels && maxPixels <= pt1.y) //pt1 outside the area
3573
+ {
3574
+ pt3.x = X;
3575
+ pt3.y = Y;
3576
+ nResult = 1; //use at least some of the pixels
3577
+ }
3578
+ if (pt1.y <= maxPixels && maxPixels <= pt0.y) //pt0 outside the area
3579
+ {
3580
+ pt2.x = X;
3581
+ pt2.y = Y;
3582
+ nResult = 1; //use at least some of the pixels
3583
+ }
3584
+ }
3585
+ }
3586
+
3587
+ pt2x.value[0] = pt2.x;
3588
+ pt2y.value[0] = pt2.y;
3589
+ pt3x.value[0] = pt3.x;
3590
+ pt3y.value[0] = pt3.y;
3591
+ } catch (exc) {
3592
+ if (exc instanceof Error) {
3593
+ ErrorLogger.LogException(lineutility._className, "DisplayIntersectPixels",
3594
+ new RendererException("Failed inside DisplayIntersectPixels", exc));
3595
+ } else {
3596
+ throw exc;
3597
+ }
3598
+ }
3599
+ return nResult;
3600
+ }
3601
+ /**
3602
+ * Computes Ditch spikes for the ATDITCH line types. This function uses
3603
+ * linestyles provided by the caller to skip segments.
3604
+ *
3605
+ * @param pLinePoints OUT - the client points also used for the return
3606
+ * points
3607
+ * @param nOldCounter the number of client points
3608
+ * @param bWayIs the parallel line to use (0) for inner or outer spikes
3609
+ *
3610
+ * @return the symbol point count
3611
+ */
3612
+ static GetDitchSpikeDouble(tg: TGLight, pLinePoints: POINT2[],
3613
+ nOldCounter: int,
3614
+ bWayIs: int): int {
3615
+ let nSpikeCounter: int = 0;
3616
+ try {
3617
+ //declarations
3618
+ let linetype: int = tg.get_LineType();
3619
+ let nNumberOfSegments: int = 0;
3620
+ let
3621
+ lCircleCounter: int = 0;
3622
+ let
3623
+ bolVertical: int = 0;
3624
+ let
3625
+ nTemp: int = 0;
3626
+ let
3627
+ i: int = 0;
3628
+ let
3629
+ j: int = 0;
3630
+ let dPrinter: double = 1.0;
3631
+ let dIntLocation1x: double = 0;
3632
+ let
3633
+ dIntLocation2x: double = 0;
3634
+ let
3635
+ dIntLocation1y: double = 0;
3636
+ let
3637
+ dIntLocation2y: double = 0;
3638
+ let
3639
+ r: double = 0;
3640
+ let
3641
+ s: double = 0;
3642
+ let
3643
+ use: double = 0;
3644
+ let
3645
+ length: double = 0;
3646
+ let
3647
+ k: double = 0;
3648
+ let
3649
+ bint: double = 0;
3650
+ let pdAnswer: ref<number[]> = new ref();//new double[6];
3651
+ let m: ref<number[]> = new ref();
3652
+
3653
+ let UpperLinePoint: POINT2 = new POINT2(pLinePoints[0]);
3654
+ let
3655
+ Lower1LinePoint: POINT2 = new POINT2(pLinePoints[0]);
3656
+ let
3657
+ Lower2LinePoint: POINT2 = new POINT2(pLinePoints[0]);
3658
+ let
3659
+ a: POINT2 = new POINT2(pLinePoints[0]);
3660
+ let
3661
+ b: POINT2 = new POINT2(pLinePoints[0]);
3662
+ let pCirclePoints: POINT2[] = new Array<POINT2>(pLinePoints.length);
3663
+ let averagePoint: POINT2 = new POINT2();
3664
+ let lastAveragePoint: POINT2 = new POINT2();
3665
+ let pTempLinePoints: POINT2[];
3666
+ //end declarations
3667
+
3668
+ pTempLinePoints = new Array<POINT2>(nOldCounter);
3669
+ for (j = 0; j < nOldCounter; j++) {
3670
+ pTempLinePoints[j] = new POINT2(pLinePoints[j]);
3671
+ }
3672
+
3673
+ let basePoints: Array<POINT2> = new Array();
3674
+
3675
+ lineutility.InitializePOINT2Array(pCirclePoints);
3676
+ nSpikeCounter = nOldCounter;
3677
+ let spikeLength: double = arraysupport.getScaledSize(12, tg.get_LineThickness(), tg.get_patternScale());
3678
+ let spikeHeight: double = spikeLength * 1.25;
3679
+ let minLength: double = 2 * spikeLength;
3680
+ for (i = 0; i < nOldCounter - 1; i++) {
3681
+ if (linetype === TacticalLines.ATDITCHM && i === 0) {
3682
+ let radius: double = arraysupport.getScaledSize(4, tg.get_LineThickness(), tg.get_patternScale());
3683
+ minLength = spikeLength * 2.5 + radius * 2;
3684
+ }
3685
+
3686
+ nTemp = lineutility.CalcTrueLinesDouble((spikeHeight * dPrinter), pLinePoints[i], pLinePoints[i + 1], pdAnswer);
3687
+ r = pdAnswer.value[3];
3688
+ s = pdAnswer.value[5];
3689
+ length = lineutility.CalcDistanceDouble(pLinePoints[i], pLinePoints[i + 1]);
3690
+ bolVertical = lineutility.CalcTrueSlopeDouble(pLinePoints[i], pLinePoints[i + 1], m);
3691
+ nNumberOfSegments = Math.trunc((length - 1) / (spikeLength * dPrinter));
3692
+
3693
+ if (length > minLength * dPrinter) { //minLength was 24
3694
+ if (bWayIs !== 0) {
3695
+ if (pLinePoints[i].x <= pLinePoints[i + 1].x) {
3696
+ use = r;
3697
+ }
3698
+ if (pLinePoints[i].x >= pLinePoints[i + 1].x) {
3699
+ use = s;
3700
+ }
3701
+ } //end if
3702
+ else {
3703
+ if (pLinePoints[i].x <= pLinePoints[i + 1].x) {
3704
+ use = s;
3705
+ }
3706
+ if (pLinePoints[i].x >= pLinePoints[i + 1].x) {
3707
+ use = r;
3708
+ }
3709
+ } //end else
3710
+
3711
+ for (j = 1; j <= nNumberOfSegments; j++) {
3712
+ k = j as double;
3713
+ a = new POINT2(pLinePoints[i]);
3714
+ b = new POINT2(pLinePoints[i + 1]);
3715
+
3716
+ if (j > 1) {
3717
+ dIntLocation1x = dIntLocation2x;
3718
+ } else {
3719
+ dIntLocation1x
3720
+ = pLinePoints[i].x as double + ((k * spikeLength - spikeLength) * dPrinter / length)
3721
+ * (pLinePoints[i + 1].x - pLinePoints[i].x) as double;
3722
+ }
3723
+
3724
+ if (j > 1) //added M. Deutch 2-23-99
3725
+ {
3726
+ dIntLocation1y = dIntLocation2y;
3727
+ } else {
3728
+ dIntLocation1y
3729
+ = pLinePoints[i].y as double + ((k * spikeLength - spikeLength / 2) * dPrinter / length)
3730
+ * (pLinePoints[i + 1].y - pLinePoints[i].y) as double;
3731
+ }
3732
+
3733
+ dIntLocation2x = pLinePoints[i].x as double
3734
+ + ((k * spikeLength + spikeLength / 2) * dPrinter / length)
3735
+ * (pLinePoints[i + 1].x
3736
+ - pLinePoints[i].x) as double;
3737
+
3738
+ dIntLocation2y = pLinePoints[i].y as double
3739
+ + ((k * spikeLength + spikeLength / 2) * dPrinter / length)
3740
+ * (pLinePoints[i + 1].y
3741
+ - pLinePoints[i].y) as double;
3742
+
3743
+ if (m.value[0] !== 0 && bolVertical !== 0) {
3744
+ bint = (dIntLocation1y + dIntLocation2y) / 2.0
3745
+ + (1 / m.value[0]) * (dIntLocation1x + dIntLocation2x) / 2.0;
3746
+ //independent of direction
3747
+ UpperLinePoint = lineutility.CalcTrueIntersectDouble2(m.value[0], use, -1 / m.value[0], bint, 1, 1, pLinePoints[0].x, pLinePoints[0].y);
3748
+ }
3749
+
3750
+ if (bolVertical === 0) //vertical segment
3751
+ {
3752
+ if (dIntLocation1y < dIntLocation2y) {
3753
+ UpperLinePoint.y = dIntLocation1y as int + Math.trunc(length / nNumberOfSegments / 2);
3754
+ } else {
3755
+ UpperLinePoint.y = dIntLocation1y as int - Math.trunc(length / nNumberOfSegments / 2);
3756
+ }
3757
+ if (pLinePoints[i].y < pLinePoints[i + 1].y) {
3758
+ UpperLinePoint.x = dIntLocation1x as int + Math.trunc(length / nNumberOfSegments);
3759
+ } else {
3760
+ UpperLinePoint.x = dIntLocation1x as int - Math.trunc(length / nNumberOfSegments);
3761
+ }
3762
+ }
3763
+ if (m.value[0] === 0 && bolVertical !== 0) {
3764
+ if (dIntLocation1x < dIntLocation2x) {
3765
+ UpperLinePoint.x = dIntLocation1x as int + Math.trunc(length / nNumberOfSegments / 2);
3766
+ } else {
3767
+ UpperLinePoint.x = dIntLocation1x as int - Math.trunc(length / nNumberOfSegments / 2);
3768
+ }
3769
+ if (pLinePoints[i + 1].x < pLinePoints[i].x) {
3770
+ UpperLinePoint.y = dIntLocation1y as int + Math.trunc(length / nNumberOfSegments);
3771
+ } else {
3772
+ UpperLinePoint.y = dIntLocation1y as int - Math.trunc(length / nNumberOfSegments);
3773
+ }
3774
+ }
3775
+ //end section
3776
+
3777
+ Lower1LinePoint.x = dIntLocation1x;
3778
+ Lower1LinePoint.y = dIntLocation1y;
3779
+ Lower2LinePoint.x = dIntLocation2x;
3780
+ Lower2LinePoint.y = dIntLocation2y;
3781
+
3782
+ pLinePoints[nSpikeCounter] = new POINT2(Lower1LinePoint);
3783
+ if (linetype === TacticalLines.ATDITCHC || linetype === TacticalLines.ATDITCHM) {
3784
+ pLinePoints[nSpikeCounter].style = 9;
3785
+ }
3786
+ if (j % 2 === 1 && linetype === TacticalLines.ATDITCHM)//diagnostic 1-8-13
3787
+ {
3788
+ pLinePoints[nSpikeCounter].style = 5;
3789
+ }
3790
+
3791
+ nSpikeCounter++;
3792
+
3793
+ pLinePoints[nSpikeCounter] = new POINT2(UpperLinePoint);
3794
+ if (linetype === TacticalLines.ATDITCHC || linetype === TacticalLines.ATDITCHM) {
3795
+ pLinePoints[nSpikeCounter].style = 9;
3796
+ }
3797
+ if (j % 2 === 1 && linetype === TacticalLines.ATDITCHM)//diagnostic 1-8-13
3798
+ {
3799
+ pLinePoints[nSpikeCounter].style = 5;
3800
+ }
3801
+
3802
+ nSpikeCounter++;
3803
+
3804
+ pLinePoints[nSpikeCounter] = new POINT2(Lower2LinePoint);
3805
+ if (linetype === TacticalLines.ATDITCHC || linetype === TacticalLines.ATDITCHM) {
3806
+ pLinePoints[nSpikeCounter].style = 10;
3807
+ }
3808
+ if (j % 2 === 1 && linetype === TacticalLines.ATDITCHM)//diagnostic 1-8-13
3809
+ {
3810
+ pLinePoints[nSpikeCounter].style = 5;
3811
+ }
3812
+
3813
+ nSpikeCounter++;
3814
+
3815
+ if (linetype === TacticalLines.ATDITCHM) {
3816
+ if (j % 2 === 0) {
3817
+ averagePoint = lineutility.MidPointDouble(Lower1LinePoint, Lower2LinePoint, 0);
3818
+ averagePoint = lineutility.MidPointDouble(averagePoint, UpperLinePoint, 0);
3819
+ } else {
3820
+ if (j === 1) {
3821
+ averagePoint = lineutility.ExtendLineDouble(Lower2LinePoint, Lower1LinePoint, 5);
3822
+ averagePoint = lineutility.MidPointDouble(averagePoint, UpperLinePoint, 0);
3823
+ }
3824
+ }
3825
+
3826
+ }
3827
+ //end section
3828
+ if (j > 1 && j < nNumberOfSegments) {
3829
+ basePoints.push(new POINT2(Lower1LinePoint));
3830
+ //if(j==nNumberOfSegments-1)
3831
+ // basePoints[basePoints.length-1].style=5;
3832
+ } else {
3833
+ if (j === 1) {
3834
+ basePoints.push(new POINT2(pLinePoints[i]));
3835
+ } else {
3836
+ if (j === nNumberOfSegments) {
3837
+ basePoints.push(new POINT2(pLinePoints[i + 1]));
3838
+ basePoints[basePoints.length - 1].style = 5;
3839
+ }
3840
+ }
3841
+
3842
+ }
3843
+
3844
+ if (linetype === TacticalLines.ATDITCHM && j > 1) {
3845
+ if (j % 2 === 0) {
3846
+ pCirclePoints[lCircleCounter] = lineutility.MidPointDouble(averagePoint, lastAveragePoint, 20);
3847
+ lCircleCounter++;
3848
+ }
3849
+ //end section
3850
+ }
3851
+ if (j < nNumberOfSegments && linetype === TacticalLines.ATDITCHM) {
3852
+ if (j === 1 || j % 2 === 0) {
3853
+ //LastUpperLinePoint = new POINT2(UpperLinePoint);
3854
+ lastAveragePoint = new POINT2(averagePoint);
3855
+ }
3856
+ //end section
3857
+ }
3858
+ }//end for j<numberOfsegments
3859
+ } //end if length big enough
3860
+ else {
3861
+ //diagnostic
3862
+ pLinePoints[nSpikeCounter].x = pLinePoints[i].x;
3863
+ pLinePoints[nSpikeCounter].y = pLinePoints[i].y;
3864
+ pLinePoints[nSpikeCounter].style = 0;
3865
+ nSpikeCounter++;
3866
+ pLinePoints[nSpikeCounter].x = pLinePoints[i + 1].x;
3867
+ pLinePoints[nSpikeCounter].y = pLinePoints[i + 1].y;
3868
+ pLinePoints[nSpikeCounter].style = 5;
3869
+ nSpikeCounter++;
3870
+ }
3871
+ }
3872
+
3873
+ for (j = 0; j < nOldCounter; j++) //reverse the first nOldCounter points for
3874
+ {
3875
+ pLinePoints[j] = new POINT2(pTempLinePoints[nOldCounter - j - 1]); //purpose of drawing
3876
+ pLinePoints[j].style = 5;
3877
+ }
3878
+
3879
+ if (pLinePoints[nSpikeCounter - 1].style === 0) {
3880
+ pLinePoints[nSpikeCounter - 1].style = 5;
3881
+ }
3882
+ let t: int = basePoints.length;
3883
+ //for (j = nSpikeCounter; j < nSpikeCounter + basePoints.length; j++)
3884
+ for (j = nSpikeCounter; j < nSpikeCounter + t; j++) {
3885
+ pLinePoints[j] = new POINT2(basePoints[j - nSpikeCounter]);
3886
+ //if(linetype == TacticalLines.ATDITCHM && pLinePoints[j].style != 5)
3887
+ if (pLinePoints[j].style !== 5) {
3888
+ pLinePoints[j].style = 0;
3889
+ }
3890
+ }
3891
+ nSpikeCounter += basePoints.length;
3892
+
3893
+ if (linetype === TacticalLines.ATDITCHM as int) {
3894
+ pLinePoints[nSpikeCounter - 1].style = 5;//was 10
3895
+ for (j = nSpikeCounter; j < nSpikeCounter + lCircleCounter; j++) {
3896
+ pLinePoints[j] = new POINT2(pCirclePoints[j - nSpikeCounter]);
3897
+ pLinePoints[j].style = 20;
3898
+ }
3899
+ nSpikeCounter += lCircleCounter;
3900
+ }
3901
+
3902
+ } catch (exc) {
3903
+ if (exc instanceof Error) {
3904
+ ErrorLogger.LogException(lineutility._className, "GetDitchSpikeDouble",
3905
+ new RendererException("Failed inside GetDitchSpikeDouble", exc));
3906
+ } else {
3907
+ throw exc;
3908
+ }
3909
+ }
3910
+ return nSpikeCounter;
3911
+ }
3912
+
3913
+ /**
3914
+ * Moves pixels if points are identical, used for the channel types
3915
+ *
3916
+ * @param pLinePoints OUT - client points also for returned points
3917
+ */
3918
+ static MoveChannelPixels(pLinePoints: POINT2[]): void {
3919
+ try {
3920
+ if (pLinePoints == null || pLinePoints.length <= 0) {
3921
+ return;
3922
+ }
3923
+
3924
+ let pixels: number[] = new Array<number>(pLinePoints.length * 2);
3925
+ let bolNoRepeats: boolean;
3926
+ let j: int = 0;
3927
+ let k: int = 0;
3928
+ let x1: double = 0;
3929
+ let y1: double = 0;
3930
+ let x2: double = 0;
3931
+ let y2: double = 0;
3932
+ let count: int = pLinePoints.length;
3933
+ //stuff pixels
3934
+ for (j = 0; j < count; j++) {
3935
+ pixels[k++] = pLinePoints[j].x;
3936
+ pixels[k++] = pLinePoints[j].y;
3937
+ }
3938
+
3939
+ bolNoRepeats = false;
3940
+ do {
3941
+ bolNoRepeats = true;
3942
+ for (j = 0; j < count - 1; j++) {
3943
+ x1 = pixels[2 * j];
3944
+ y1 = pixels[2 * j + 1];
3945
+ x2 = pixels[2 * j + 2];
3946
+ y2 = pixels[2 * j + 3];
3947
+ if (x1 === x2 && y1 === y2) //it's the same point
3948
+ {
3949
+ bolNoRepeats = false;
3950
+ pixels[2 * j + 2] = x2 + 1; //move the point
3951
+ break;
3952
+ }
3953
+ }
3954
+ } while (bolNoRepeats === false);
3955
+ //stuff pLinePoints
3956
+ k = 0;
3957
+ for (j = 0; j < count; j++) {
3958
+ pLinePoints[j].x = pixels[k++];
3959
+ pLinePoints[j].y = pixels[k++];
3960
+ }
3961
+ } catch (exc) {
3962
+ if (exc instanceof Error) {
3963
+ ErrorLogger.LogException(lineutility._className, "MoveChannelPixels",
3964
+ new RendererException("Failed inside MoveChannelPixels", exc));
3965
+ } else {
3966
+ throw exc;
3967
+ }
3968
+ }
3969
+ }
3970
+
3971
+ /**
3972
+ * Single Concertina cannot have horizontal first segment
3973
+ *
3974
+ * @param linetype
3975
+ * @param pLinePoints
3976
+ */
3977
+ static moveSingleCPixels(linetype: int, pLinePoints: POINT2[]): void {
3978
+ try {
3979
+ switch (linetype) {
3980
+ case TacticalLines.SINGLEC: {
3981
+ break;
3982
+ }
3983
+
3984
+ default: {
3985
+ return;
3986
+ }
3987
+
3988
+ }
3989
+ if (pLinePoints.length > 1) {
3990
+ if (pLinePoints[1].y === pLinePoints[0].y) {
3991
+ pLinePoints[1].y++;
3992
+ }
3993
+ }
3994
+ } catch (exc) {
3995
+ if (exc instanceof Error) {
3996
+ ErrorLogger.LogException(lineutility._className, "MoveSingleCPixels",
3997
+ new RendererException("Failed inside MoveSingleCPixels", exc));
3998
+ } else {
3999
+ throw exc;
4000
+ }
4001
+ }
4002
+ }
4003
+
4004
+ /**
4005
+ * Rotates an the first vblCounter points in the array about its first point
4006
+ *
4007
+ * @param pLinePoints OUT - the points to rotate
4008
+ * @param vblCounter the number of points to rotate
4009
+ * @param lAngle the angle in degrees to rotate
4010
+ */
4011
+ static RotateGeometryDouble(pLinePoints: POINT2[],
4012
+ vblCounter: int,
4013
+ lAngle: double): void {
4014
+ try {
4015
+ let j: int = 0;
4016
+ let dRotate: double = 0;
4017
+ let
4018
+ dTheta: double = 0;
4019
+ let
4020
+ dGamma: double = 0;
4021
+ let
4022
+ x: double = 0;
4023
+ let
4024
+ y: double = 0;
4025
+
4026
+ if (lAngle !== 0) //if the angle is 0 no rotation occurs
4027
+ {
4028
+ let pdCenter: POINT2;
4029
+ dRotate = lAngle * Math.PI / 180;
4030
+ pdCenter = lineutility.CalcCenterPointDouble(pLinePoints, vblCounter);
4031
+
4032
+ for (j = 0; j < vblCounter; j++) {
4033
+ //added if/else to get rid of divide by zero error 5/12/04 M. Deutch
4034
+ if (pLinePoints[j].x === pdCenter.x) {
4035
+ if ((pLinePoints[j].y > pdCenter.y)) {
4036
+ dGamma = Math.PI + Math.PI / 2;
4037
+ } else {
4038
+ dGamma = Math.PI / 2;
4039
+ }
4040
+ } else {
4041
+ dGamma = Math.PI + Math.atan((pLinePoints[j].y - pdCenter.y)
4042
+ / (pLinePoints[j].x - pdCenter.x));
4043
+ }
4044
+
4045
+ if (pLinePoints[j].x as double >= pdCenter.x) {
4046
+ dGamma = dGamma + Math.PI;
4047
+ }
4048
+
4049
+ dTheta = dRotate + dGamma;
4050
+ y = lineutility.CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.sin(dTheta);
4051
+ x = lineutility.CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.cos(dTheta);
4052
+ pLinePoints[j].y = pdCenter.y + y;
4053
+ pLinePoints[j].x = pdCenter.x + x;
4054
+ } //end for
4055
+
4056
+ return;
4057
+ } //end if
4058
+ } catch (exc) {
4059
+ if (exc instanceof Error) {
4060
+ ErrorLogger.LogException(lineutility._className, "RotateGeometryDouble",
4061
+ new RendererException("Failed inside RotateGeometryDouble", exc));
4062
+ } else {
4063
+ throw exc;
4064
+ }
4065
+ }
4066
+ } // end
4067
+
4068
+ /**
4069
+ * Returns the point perpendicular to the line (pt0 to pt1) at the midpoint
4070
+ * the same distance from (and on the same side of) the the line as
4071
+ * ptRelative.
4072
+ *
4073
+ * @param pt0 the first point
4074
+ * @param pt1 the second point
4075
+ * @param ptRelative the point to use for computing the return point
4076
+ *
4077
+ * @return the point perpendicular to the line at the midpoint
4078
+ */
4079
+ static PointRelativeToLine(pt0: POINT2,
4080
+ pt1: POINT2,
4081
+ ptRelative: POINT2): POINT2;
4082
+
4083
+ /**
4084
+ * Returns the point perpendicular to the line (pt0 to pt1) at atPoint the
4085
+ * same distance from (and on the same side of) the the line as ptRelative.
4086
+ *
4087
+ * @param pt0 the first point
4088
+ * @param pt1 the second point
4089
+ * @param atPoint the point on the line at which to compute the extended
4090
+ * point
4091
+ * @param ptRelative the point to use for computing the return point
4092
+ *
4093
+ * @return the point perpendicular to the line at ptRelative
4094
+ */
4095
+ static PointRelativeToLine(pt0: POINT2,
4096
+ pt1: POINT2,
4097
+ atPoint: POINT2,
4098
+ ptRelative: POINT2): POINT2;
4099
+ static PointRelativeToLine(...args: unknown[]): POINT2 {
4100
+ switch (args.length) {
4101
+ case 3: {
4102
+ const [pt0, pt1, ptRelative] = args as [POINT2, POINT2, POINT2];
4103
+
4104
+
4105
+ let ptResult: POINT2 = new POINT2(pt0);
4106
+ try {
4107
+ let bolVertical: int = 0;
4108
+ let m: ref<number[]> = new ref();
4109
+ let midPt: POINT2 = lineutility.MidPointDouble(pt0, pt1, 0);
4110
+ let b1: double = 0;
4111
+ let b2: double = 0;
4112
+ //end declarations
4113
+
4114
+ bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
4115
+ if (bolVertical === 0) //line is vertical
4116
+ {
4117
+ ptResult.x = ptRelative.x;
4118
+ ptResult.y = midPt.y;
4119
+ }
4120
+ if (bolVertical !== 0 && m.value[0] === 0) {
4121
+ ptResult.x = midPt.x;
4122
+ ptResult.y = ptRelative.y;
4123
+ }
4124
+ if (bolVertical !== 0 && m.value[0] !== 0) {
4125
+ b1 = midPt.y + (1 / m.value[0]) * midPt.x; //the line perp to midPt
4126
+ b2 = ptRelative.y - m.value[0] * ptRelative.x; //the line ptRelative with the slope of pt1-pt2
4127
+ ptResult = lineutility.CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0);
4128
+ }
4129
+ } catch (exc) {
4130
+ if (exc instanceof Error) {
4131
+ ErrorLogger.LogException(lineutility._className, "PointRelativeToLine",
4132
+ new RendererException("Failed inside PointRelativeToLine", exc));
4133
+ } else {
4134
+ throw exc;
4135
+ }
4136
+ }
4137
+ return ptResult;
4138
+
4139
+
4140
+ break;
4141
+ }
4142
+
4143
+ case 4: {
4144
+ const [pt0, pt1, atPoint, ptRelative] = args as [POINT2, POINT2, POINT2, POINT2];
4145
+
4146
+
4147
+ let ptResult: POINT2 = new POINT2(pt0);
4148
+ try {
4149
+ let bolVertical: int = 0;
4150
+ let m: ref<number[]> = new ref();
4151
+ let b1: double = 0;
4152
+ let b2: double = 0;
4153
+
4154
+ bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
4155
+ if (bolVertical === 0) //line is vertical
4156
+ {
4157
+ ptResult.x = ptRelative.x;
4158
+ ptResult.y = atPoint.y;
4159
+ }
4160
+ if (bolVertical !== 0 && m.value[0] === 0) {
4161
+ ptResult.x = atPoint.x;
4162
+ ptResult.y = ptRelative.y;
4163
+ }
4164
+ if (bolVertical !== 0 && m.value[0] !== 0) {
4165
+ b1 = atPoint.y + (1 / m.value[0]) * atPoint.x; //the line perp to midPt
4166
+ b2 = ptRelative.y - m.value[0] * ptRelative.x; //the line ptRelative with the slope of pt1-pt2
4167
+ ptResult = lineutility.CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0);
4168
+ }
4169
+ } catch (exc) {
4170
+ if (exc instanceof Error) {
4171
+ ErrorLogger.LogException(lineutility._className, "PointRelativeToLine",
4172
+ new RendererException("Failed inside PointRelativeToLine", exc));
4173
+ } else {
4174
+ throw exc;
4175
+ }
4176
+ }
4177
+ return ptResult;
4178
+
4179
+
4180
+ break;
4181
+ }
4182
+
4183
+ default: {
4184
+ throw Error(`Invalid number of arguments`);
4185
+ }
4186
+ }
4187
+ }
4188
+
4189
+
4190
+ /**
4191
+ * shift the control point to match the shift that occurs in
4192
+ * Channels.GetAXADDouble for CATKBYFIRE. This is because the rotary feature
4193
+ * arrow tip must align with the anchor point
4194
+ *
4195
+ * @param linetype
4196
+ * @param pLinePoints the anchor points including the control point
4197
+ * @param dist the minimum required distance from the front of the rotary
4198
+ * arrow
4199
+ */
4200
+ public static adjustCATKBYFIREControlPoint(linetype: int,
4201
+ pLinePoints: Array<POINT2>,
4202
+ dist: double): void {
4203
+ try {
4204
+ if (linetype !== TacticalLines.CATKBYFIRE) {
4205
+ return;
4206
+ }
4207
+
4208
+ let dist2: double = lineutility.CalcDistanceDouble(pLinePoints[0], pLinePoints[1]);
4209
+ if (dist2 <= dist) {
4210
+ return;
4211
+ }
4212
+
4213
+ let pt: POINT2;
4214
+ let count: int = pLinePoints.length;
4215
+ let pt0: POINT2 = new POINT2(pLinePoints[0]);
4216
+ let pt1: POINT2 = new POINT2(pLinePoints[1]);
4217
+ let controlPt: POINT2 = new POINT2(pLinePoints[count - 1]);
4218
+ let pt4: POINT2 = lineutility.PointRelativeToLine(pt0, pt1, pt1, controlPt);
4219
+ pt = lineutility.ExtendLineDouble(pt4, controlPt, dist);
4220
+ pLinePoints[count - 1] = pt;
4221
+ } catch (exc) {
4222
+ if (exc instanceof Error) {
4223
+ ErrorLogger.LogException(lineutility._className, "adjustCATKBYFIREControlPoint",
4224
+ new RendererException("Failed inside adjustCATKBYFIREControlPoint", exc));
4225
+ } else {
4226
+ throw exc;
4227
+ }
4228
+ }
4229
+ }
4230
+
4231
+ /**
4232
+ * Returns in pt2 and pt3 the line segment parallel to segment pt0-pt1 which
4233
+ * would contain ptRelative. pt2 corresponds to pt0 and pt3 corresponds to
4234
+ * pt1.
4235
+ *
4236
+ * @param pt0 first line point
4237
+ * @param pt1 second line point
4238
+ * @param ptRelative relative line point
4239
+ * @param pt2 OUT - first computed relative line point
4240
+ * @param pt3 OUT - second computed relative line point
4241
+ */
4242
+ public static LineRelativeToLine(pt0: POINT2,
4243
+ pt1: POINT2,
4244
+ ptRelative: POINT2,
4245
+ pt2: POINT2,
4246
+ pt3: POINT2): void {
4247
+ try {
4248
+ let bolVertical: int = 0;
4249
+ let m: ref<number[]> = new ref();
4250
+ let b1: double = 0;
4251
+ let b2: double = 0;
4252
+ let pt2Temp: POINT2;
4253
+ let pt3Temp: POINT2;
4254
+
4255
+ bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
4256
+ if (bolVertical === 0) //line is vertical
4257
+ {
4258
+ pt2.x = ptRelative.x;
4259
+ pt2.y = pt0.y;
4260
+ pt3.x = ptRelative.x;
4261
+ pt3.y = pt1.y;
4262
+ }
4263
+ if (bolVertical !== 0 && m.value[0] === 0) //line is horizontal
4264
+ {
4265
+ pt2.x = pt0.x;
4266
+ pt2.y = ptRelative.y;
4267
+ pt3.x = pt1.x;
4268
+ pt3.y = ptRelative.y;
4269
+ }
4270
+ if (bolVertical !== 0 && m.value[0] !== 0) {
4271
+ b1 = pt0.y + (1 / m.value[0]) * pt0.x; //the line perp to pt0
4272
+ b2 = ptRelative.y - m.value[0] * ptRelative.x; //the line the ptRelative with the slope of pt0-pt1
4273
+ pt2Temp = lineutility.CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0);
4274
+
4275
+ b1 = pt1.y + (1 / m.value[0]) * pt1.x; //the line perp to pt1
4276
+ //b2=ptRelative.y-m*ptRelative.x; //the line the ptRelative with the slope of pt0-pt1
4277
+ pt3Temp = lineutility.CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0);
4278
+
4279
+ pt2.x = pt2Temp.x;
4280
+ pt2.y = pt2Temp.y;
4281
+ pt3.x = pt3Temp.x;
4282
+ pt3.y = pt3Temp.y;
4283
+ }
4284
+ } catch (exc) {
4285
+ if (exc instanceof Error) {
4286
+ ErrorLogger.LogException(lineutility._className, "LineRelativeToLine",
4287
+ new RendererException("Failed inside LineRelativeToLine", exc));
4288
+ } else {
4289
+ throw exc;
4290
+ }
4291
+ }
4292
+ }
4293
+
4294
+ private static CalcMBR(pLinePoints: POINT2[],
4295
+ numpts: int,
4296
+ ulx: ref<number[]>,
4297
+ uly: ref<number[]>,
4298
+ lrx: ref<number[]>,
4299
+ lry: ref<number[]>): void {
4300
+ try {
4301
+ let j: int = 0;
4302
+ //initialize the MBR
4303
+ ulx.value = new Array<number>(1);
4304
+ uly.value = new Array<number>(1);
4305
+ lrx.value = new Array<number>(1);
4306
+ lry.value = new Array<number>(1);
4307
+ ulx.value[0] = Number.MAX_VALUE;//was 99999
4308
+ uly.value[0] = Number.MAX_VALUE;//was 99999
4309
+ lrx.value[0] = -Number.MAX_VALUE;//was -99999
4310
+ lry.value[0] = -Number.MAX_VALUE;//was -99999
4311
+ for (j = 0; j < numpts; j++) {
4312
+ if (pLinePoints[j].x > lrx.value[0]) {
4313
+ lrx.value[0] = pLinePoints[j].x;
4314
+ }
4315
+ if (pLinePoints[j].y > lry.value[0]) {
4316
+ lry.value[0] = pLinePoints[j].y;
4317
+ }
4318
+ if (pLinePoints[j].x < ulx.value[0]) {
4319
+ ulx.value[0] = pLinePoints[j].x;
4320
+ }
4321
+ if (pLinePoints[j].y < uly.value[0]) {
4322
+ uly.value[0] = pLinePoints[j].y;
4323
+ }
4324
+ }
4325
+ } catch (exc) {
4326
+ if (exc instanceof Error) {
4327
+ ErrorLogger.LogException(lineutility._className, "CalcMBR",
4328
+ new RendererException("Failed inside CalcMBR", exc));
4329
+ } else {
4330
+ throw exc;
4331
+ }
4332
+ }
4333
+ return;
4334
+ }
4335
+
4336
+ public static CalcMBRPoints(pLinePoints: POINT2[],
4337
+ numpts: int,
4338
+ ul: POINT2,
4339
+ lr: POINT2): void {
4340
+ try {
4341
+ let j: int = 0;
4342
+ ul.x = Number.MAX_VALUE;
4343
+ ul.y = Number.MAX_VALUE;
4344
+ lr.x = -Number.MAX_VALUE;
4345
+ lr.y = -Number.MAX_VALUE;
4346
+ for (j = 0; j < numpts; j++) {
4347
+ if (pLinePoints[j].x > lr.x) {
4348
+ lr.x = pLinePoints[j].x;
4349
+ }
4350
+ if (pLinePoints[j].y > lr.y) {
4351
+ lr.y = pLinePoints[j].y;
4352
+ }
4353
+ if (pLinePoints[j].x < ul.x) {
4354
+ ul.x = pLinePoints[j].x;
4355
+ }
4356
+ if (pLinePoints[j].y < ul.y) {
4357
+ ul.y = pLinePoints[j].y;
4358
+ }
4359
+ }
4360
+ } catch (exc) {
4361
+ if (exc instanceof Error) {
4362
+ ErrorLogger.LogException(lineutility._className, "CalcMBRPoints",
4363
+ new RendererException("Failed inside CalcMBRPoints", exc));
4364
+ } else {
4365
+ throw exc;
4366
+ }
4367
+ }
4368
+ }
4369
+
4370
+ /**
4371
+ * Computes the distance in pixels from upper left to lower right of the
4372
+ * minimum bounding rectangle for the first numpts of pLinePoints
4373
+ *
4374
+ * @param pLinePoints the inpupt point array
4375
+ * @param numpts the number of points to use
4376
+ *
4377
+ * @return the distance in pixels
4378
+ */
4379
+ static MBRDistance(pLinePoints: POINT2[],
4380
+ numpts: int): double {
4381
+ let result: double = 0;
4382
+ try {
4383
+ let ulx: ref<number[]> = new ref();
4384
+ let uly: ref<number[]> = new ref();
4385
+ let lrx: ref<number[]> = new ref();
4386
+ let lry: ref<number[]> = new ref();
4387
+ lineutility.CalcMBR(pLinePoints, numpts, ulx, uly, lrx, lry);
4388
+ result = Math.sqrt((lrx.value[0] - ulx.value[0]) * (lrx.value[0] - ulx.value[0]) + (lry.value[0] - uly.value[0]) * (lry.value[0] - uly.value[0]));
4389
+ //sanity check
4390
+
4391
+ //return x or y distance if returnValue is 0 or infinity
4392
+ let xdist: double = Math.abs(lrx.value[0] - ulx.value[0]);
4393
+ let ydist: double = Math.abs(lry.value[0] - uly.value[0]);
4394
+ let max: double = xdist;
4395
+ if (ydist > xdist) {
4396
+ max = ydist;
4397
+ }
4398
+
4399
+ if (result === 0 || !Number.isFinite(result)) {
4400
+ if (max > 0) {
4401
+ result = max;
4402
+ }
4403
+ }
4404
+
4405
+ } catch (exc) {
4406
+ if (exc instanceof Error) {
4407
+ ErrorLogger.LogException(lineutility._className, "MBRDistance",
4408
+ new RendererException("Failed inside MBRDistance", exc));
4409
+ } else {
4410
+ throw exc;
4411
+ }
4412
+ }
4413
+ return result;
4414
+ }
4415
+
4416
+ /**
4417
+ * Swaps two points.
4418
+ *
4419
+ * @param pt1 OUT - first point
4420
+ * @param pt2 OUT - second point
4421
+ *
4422
+ */
4423
+ static Reverse2Points(pt1: POINT2, pt2: POINT2): void {
4424
+ try {
4425
+ let tempPt: POINT2 = new POINT2();
4426
+ //store pt1
4427
+ tempPt.x = pt1.x;
4428
+ tempPt.y = pt1.y;
4429
+ pt1.x = pt2.x;
4430
+ pt1.y = pt2.y;
4431
+ pt2.x = tempPt.x;
4432
+ pt2.y = tempPt.y;
4433
+ } catch (exc) {
4434
+ if (exc instanceof Error) {
4435
+ ErrorLogger.LogException(lineutility._className, "Reverse2Points",
4436
+ new RendererException("Failed inside Reverse2Points", exc));
4437
+ } else {
4438
+ throw exc;
4439
+ }
4440
+ }
4441
+ }
4442
+ /**
4443
+ * Creates a GeneralPath from a Path2D
4444
+ *
4445
+ * @param shape
4446
+ * @return
4447
+ */
4448
+ public static createStrokedShape(shape: Shape): Shape {
4449
+ let newshape: GeneralPath = new GeneralPath(); // Start with an empty shape
4450
+ try {
4451
+ // Iterate through the specified shape, perturb its coordinates, and
4452
+ // use them to build up the new shape.
4453
+ let coords: number[] = new Array<number>(6);
4454
+ for (let i: PathIterator = shape.getPathIterator(null); !i.isDone(); i.next()) {
4455
+ let type: int = i.currentSegment(coords);
4456
+ switch (type) {
4457
+ case IPathIterator.SEG_MOVETO: {
4458
+ //perturb(coords, 2);
4459
+ newshape.moveTo(coords[0], coords[1]);
4460
+ break;
4461
+ }
4462
+
4463
+ case IPathIterator.SEG_LINETO: {
4464
+ //perturb(coords, 2);
4465
+ newshape.lineTo(coords[0], coords[1]);
4466
+ break;
4467
+ }
4468
+
4469
+ case IPathIterator.SEG_QUADTO: {
4470
+ //perturb(coords, 4);
4471
+ newshape.quadTo(coords[0], coords[1], coords[2], coords[3]);
4472
+ break;
4473
+ }
4474
+
4475
+ case IPathIterator.SEG_CUBICTO: {
4476
+ //perturb(coords, 6);
4477
+ newshape.curveTo(coords[0], coords[1], coords[2], coords[3],
4478
+ coords[4], coords[5]);
4479
+ break;
4480
+ }
4481
+
4482
+ case IPathIterator.SEG_CLOSE: {
4483
+ newshape.closePath();
4484
+ break;
4485
+ }
4486
+ }
4487
+ }
4488
+ } catch (exc) {
4489
+ if (exc instanceof Error) {
4490
+ ErrorLogger.LogException(lineutility._className, "createStrokedShape",
4491
+ new RendererException("Failed inside createStrokedShape", exc));
4492
+ } else {
4493
+ throw exc;
4494
+ }
4495
+ }
4496
+ return newshape;
4497
+ }
4498
+ //These functions were added to create a minimum bounding polygon
4499
+ /**
4500
+ * @deprecated Returns the determinant of the point matrix This determinant
4501
+ * tells how far p3 is from vector p1p2 and on which side it is
4502
+ * @param p1
4503
+ * @param p2
4504
+ * @param p3
4505
+ * @return
4506
+ */
4507
+ private static distance(p1: Point, p2: Point, p3: Point): int {
4508
+ try {
4509
+ let x1: int = p1.x;
4510
+ let x2: int = p2.x;
4511
+ let x3: int = p3.x;
4512
+ let y1: int = p1.y;
4513
+ let y2: int = p2.y;
4514
+ let y3: int = p3.y;
4515
+ return x1 * y2 + x3 * y1 + x2 * y3 - x3 * y2 - x2 * y1 - x1 * y3;
4516
+ } catch (exc) {
4517
+ if (exc instanceof Error) {
4518
+ ErrorLogger.LogException(lineutility._className, "distance",
4519
+ new RendererException("Failed inside distance", exc));
4520
+ } else {
4521
+ throw exc;
4522
+ }
4523
+ }
4524
+ return 0;
4525
+ }
4526
+
4527
+ /**
4528
+ * @deprecated Returns the determinant of the point matrix This determinant
4529
+ * tells how far p3 is from vector p1p2 and on which side it is
4530
+ * @param p1
4531
+ * @param p2
4532
+ * @param p3
4533
+ * @return
4534
+ */
4535
+ private static distance2(p1: POINT2, p2: POINT2, p3: POINT2): double {
4536
+ try {
4537
+ let x1: double = p1.x;
4538
+ let x2: double = p2.x;
4539
+ let x3: double = p3.x;
4540
+ let y1: double = p1.y;
4541
+ let y2: double = p2.y;
4542
+ let y3: double = p3.y;
4543
+ return x1 * y2 + x3 * y1 + x2 * y3 - x3 * y2 - x2 * y1 - x1 * y3;
4544
+ } catch (exc) {
4545
+ if (exc instanceof Error) {
4546
+ ErrorLogger.LogException(lineutility._className, "distance2",
4547
+ new RendererException("Failed inside distance2", exc));
4548
+ } else {
4549
+ throw exc;
4550
+ }
4551
+ }
4552
+ return 0;
4553
+ }
4554
+ //Returns the points of convex hull in the correct order
4555
+ /**
4556
+ * @deprecated @param array
4557
+ * @return
4558
+ */
4559
+ static cHull(array: Array<Point>): Array<Point>;
4560
+
4561
+ /**
4562
+ * @deprecated @param points
4563
+ * @param l
4564
+ * @param r
4565
+ * @param path
4566
+ */
4567
+ static cHull(points: Array<Point>, l: Point, r: Point, path: Array<Point>): void;
4568
+ static cHull(...args: unknown[]): Array<Point> | void | null {
4569
+ switch (args.length) {
4570
+ case 1: {
4571
+ const [array] = args as [Array<Point>];
4572
+
4573
+
4574
+ let size: int = array.length;
4575
+ if (size < 2) {
4576
+ return null;
4577
+ }
4578
+
4579
+ let l: Point = array[0];
4580
+ let r: Point = array[size - 1];
4581
+ let path: Array<Point> = new Array<Point>();
4582
+ path.push(l);
4583
+ lineutility.cHull(array, l, r, path);
4584
+ path.push(r);
4585
+ lineutility.cHull(array, r, l, path);
4586
+ return path;
4587
+
4588
+
4589
+ break;
4590
+ }
4591
+
4592
+ case 4: {
4593
+ const [points, l, r, path] = args as [Array<Point>, Point, Point, Array<Point>];
4594
+
4595
+
4596
+
4597
+ if (points.length < 3) {
4598
+ return;
4599
+ }
4600
+
4601
+ let maxDist: int = 0;
4602
+ let tmp: int = 0;
4603
+ let p: Point;
4604
+
4605
+ for (let pt of points) {
4606
+ if (pt !== l && pt !== r) {
4607
+ tmp = lineutility.distance(l, r, pt);
4608
+
4609
+ if (tmp > maxDist) {
4610
+ maxDist = tmp;
4611
+ p = pt;
4612
+ }
4613
+ }
4614
+ }
4615
+
4616
+ let left: Array<Point> = new Array<Point>();
4617
+ let right: Array<Point> = new Array<Point>();
4618
+ left.push(l);
4619
+ right.push(p);
4620
+
4621
+ for (let pt of points) {
4622
+ if (lineutility.distance(l, p, pt) > 0) {
4623
+ left.push(pt);
4624
+ } else {
4625
+ if (lineutility.distance(p, r, pt) > 0) {
4626
+ right.push(pt);
4627
+ }
4628
+ }
4629
+
4630
+ }
4631
+
4632
+ left.push(p);
4633
+ right.push(r);
4634
+ lineutility.cHull(left, l, p, path);
4635
+ path.push(p);
4636
+ lineutility.cHull(right, p, r, path);
4637
+
4638
+
4639
+ break;
4640
+ }
4641
+
4642
+ default: {
4643
+ throw Error(`Invalid number of arguments`);
4644
+ }
4645
+ }
4646
+ }
4647
+
4648
+
4649
+ /**
4650
+ * @deprecated @param array
4651
+ * @return
4652
+ */
4653
+ static cHull2(array: Array<POINT2>): Array<POINT2>;
4654
+
4655
+ /**
4656
+ * @deprecated @param points
4657
+ * @param l
4658
+ * @param r
4659
+ * @param path
4660
+ */
4661
+ static cHull2(points: Array<POINT2>, l: POINT2, r: POINT2, path: Array<POINT2>): void;
4662
+ static cHull2(...args: unknown[]): Array<POINT2> | void | null {
4663
+ switch (args.length) {
4664
+ case 1: {
4665
+ const [array] = args as [Array<POINT2>];
4666
+
4667
+
4668
+ try {
4669
+ let size: int = array.length;
4670
+ if (size < 2) {
4671
+ return null;
4672
+ }
4673
+
4674
+ let l: POINT2 = array[0];
4675
+ let r: POINT2 = array[size - 1];
4676
+ let path: Array<POINT2> = new Array<POINT2>();
4677
+ path.push(l);
4678
+ lineutility.cHull2(array, l, r, path);
4679
+ path.push(r);
4680
+ lineutility.cHull2(array, r, l, path);
4681
+ return path;
4682
+ } catch (exc) {
4683
+ if (exc instanceof Error) {
4684
+ ErrorLogger.LogException(lineutility._className, "cHull2",
4685
+ new RendererException("Failed inside cHull2", exc));
4686
+ } else {
4687
+ throw exc;
4688
+ }
4689
+ }
4690
+ return null;
4691
+
4692
+
4693
+ break;
4694
+ }
4695
+
4696
+ case 4: {
4697
+ const [points, l, r, path] = args as [Array<POINT2>, POINT2, POINT2, Array<POINT2>];
4698
+
4699
+
4700
+
4701
+ if (points.length < 3) {
4702
+ return;
4703
+ }
4704
+
4705
+ let maxDist: double = 0;
4706
+ let tmp: double = 0;
4707
+ let p: POINT2;
4708
+
4709
+ for (let pt of points) {
4710
+ if (pt !== l && pt !== r) {
4711
+ tmp = lineutility.distance2(l, r, pt);
4712
+
4713
+ if (tmp > maxDist) {
4714
+ maxDist = tmp;
4715
+ p = pt;
4716
+ }
4717
+ }
4718
+ }
4719
+
4720
+ let left: Array<POINT2> = new Array<POINT2>();
4721
+ let right: Array<POINT2> = new Array<POINT2>();
4722
+ left.push(l);
4723
+ right.push(p);
4724
+
4725
+ for (let pt of points) {
4726
+ if (lineutility.distance2(l, p, pt) > 0) {
4727
+ left.push(pt);
4728
+ } else {
4729
+ if (lineutility.distance2(p, r, pt) > 0) {
4730
+ right.push(pt);
4731
+ }
4732
+ }
4733
+
4734
+ }
4735
+
4736
+ left.push(p);
4737
+ right.push(r);
4738
+ lineutility.cHull2(left, l, p, path);
4739
+ path.push(p);
4740
+ lineutility.cHull2(right, p, r, path);
4741
+
4742
+
4743
+ break;
4744
+ }
4745
+
4746
+ default: {
4747
+ throw Error(`Invalid number of arguments`);
4748
+ }
4749
+ }
4750
+ }
4751
+
4752
+
4753
+ public static getExteriorPoints(pLinePoints: POINT2[],
4754
+ vblCounter: int,
4755
+ lineType: int,
4756
+ interior: boolean
4757
+ ): void {
4758
+ let j: int = 0;
4759
+ let index: int = 0;
4760
+ let pt0: POINT2;
4761
+ let pt1: POINT2;
4762
+ let pt2: POINT2;
4763
+ let m01: ref<number[]> = new ref();
4764
+ let m12: ref<number[]> = new ref();
4765
+ let direction: int = 0;
4766
+ let intersectPt: POINT2;
4767
+ //ref<double[]> m1 = new ref(), m2 = new ref();
4768
+ let intersectPoints: Array<POINT2> = new Array();
4769
+ let b01: double = 0;
4770
+ let b12: double = 0; //the y intercepts for the lines corresponding to m1,m2
4771
+ let dist: double = pLinePoints[0].style;
4772
+ for (j = 0; j < vblCounter; j++) {
4773
+ if (j === 0 || j === vblCounter - 1) {
4774
+ pt0 = new POINT2(pLinePoints[vblCounter - 2]);
4775
+ pt1 = new POINT2(pLinePoints[0]);
4776
+ pt2 = new POINT2(pLinePoints[1]);
4777
+ } else {
4778
+ pt0 = new POINT2(pLinePoints[j - 1]);
4779
+ pt1 = new POINT2(pLinePoints[j]);
4780
+ pt2 = new POINT2(pLinePoints[j + 1]);
4781
+ }
4782
+ if (pt1.style > 0) {
4783
+ dist = pt1.style;
4784
+ }
4785
+ //the exterior/interior points
4786
+ let pt00: POINT2;
4787
+ let pt01: POINT2;
4788
+ let pt10: POINT2;
4789
+ let pt11: POINT2;
4790
+
4791
+ index = j - 1;
4792
+ if (index < 0) {
4793
+ index = vblCounter - 1;
4794
+ }
4795
+ let pts: POINT2[] = new Array<POINT2>(pLinePoints.length);
4796
+ let n: int = pLinePoints.length;
4797
+ //for (int k = 0; k < pLinePoints.length; k++)
4798
+ for (let k: int = 0; k < n; k++) {
4799
+ pts[k] = pLinePoints[k];
4800
+ }
4801
+
4802
+ direction = arraysupport.GetInsideOutsideDouble2(pt0, pt1, pts, vblCounter, index, lineType);
4803
+ //reverse the direction if these are interior points
4804
+ if (interior === true) {
4805
+ switch (direction) {
4806
+ case 0: {
4807
+ direction = 1;
4808
+ break;
4809
+ }
4810
+
4811
+ case 1: {
4812
+ direction = 0;
4813
+ break;
4814
+ }
4815
+
4816
+ case 2: {
4817
+ direction = 3;
4818
+ break;
4819
+ }
4820
+
4821
+ case 3: {
4822
+ direction = 2;
4823
+ break;
4824
+ }
4825
+
4826
+ default: {
4827
+ break;
4828
+ }
4829
+
4830
+ }
4831
+ }
4832
+ //pt00-pt01 will be the interior line inside line pt0-pt1
4833
+ //pt00 is inside pt0, pt01 is inside pt1
4834
+ pt00 = lineutility.ExtendDirectedLine(pt0, pt1, pt0, direction, dist);
4835
+ pt01 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, direction, dist);
4836
+
4837
+ //pt10-pt11 will be the interior line inside line pt1-pt2
4838
+ //pt10 is inside pt1, pt11 is inside pt2
4839
+ index = j;
4840
+ if (j === vblCounter - 1) {
4841
+ index = 0;
4842
+ }
4843
+ direction = arraysupport.GetInsideOutsideDouble2(pt1, pt2, pts as POINT2[], vblCounter, index, lineType);
4844
+ //reverse the direction if these are interior points
4845
+ if (interior === true) {
4846
+ switch (direction) {
4847
+ case 0: {
4848
+ direction = 1;
4849
+ break;
4850
+ }
4851
+
4852
+ case 1: {
4853
+ direction = 0;
4854
+ break;
4855
+ }
4856
+
4857
+ case 2: {
4858
+ direction = 3;
4859
+ break;
4860
+ }
4861
+
4862
+ case 3: {
4863
+ direction = 2;
4864
+ break;
4865
+ }
4866
+
4867
+ default: {
4868
+ break;
4869
+ }
4870
+
4871
+ }
4872
+ }
4873
+ pt10 = lineutility.ExtendDirectedLine(pt1, pt2, pt1, direction, dist);
4874
+ pt11 = lineutility.ExtendDirectedLine(pt1, pt2, pt2, direction, dist);
4875
+ //intersectPt=new POINT2(null);
4876
+ //get the intersection of pt01-p00 and pt10-pt11
4877
+ //so it it is the interior intersection of pt0-pt1 and pt1-pt2
4878
+
4879
+ //first handle the case of vertical lines.
4880
+ if (pt0.x === pt1.x && pt1.x === pt2.x) {
4881
+ intersectPt = new POINT2(pt01);
4882
+ intersectPoints.push(intersectPt);
4883
+ continue;
4884
+ }
4885
+ //it's the same situation if the slopes are identical,
4886
+ //simply use pt01 or pt10 since they already uniquely define the intesection
4887
+ lineutility.CalcTrueSlopeDouble2(pt00, pt01, m01);
4888
+ lineutility.CalcTrueSlopeDouble2(pt10, pt11, m12);
4889
+ //if(m01.dbl==m12.dbl)
4890
+ if (m01.value[0] === m12.value[0]) {
4891
+ intersectPt = new POINT2(pt01);
4892
+ intersectPoints.push(intersectPt);
4893
+ continue;
4894
+ }
4895
+ //now we are assuming a non-trivial intersection
4896
+ //calculate the y-intercepts using y=mx+b (use b=y-mx)
4897
+ b01 = pt01.y - m01.value[0] * pt01.x;
4898
+ b12 = pt11.y - m12.value[0] * pt11.x;
4899
+ intersectPt = lineutility.CalcTrueIntersectDouble2(m01.value[0], b01, m12.value[0], b12, 1, 1, 0, 0);
4900
+ intersectPoints.push(intersectPt);
4901
+ }//end for
4902
+ let n: int = intersectPoints.length;
4903
+ //for (j = 0; j < intersectPoints.length; j++)
4904
+ for (j = 0; j < n; j++) {
4905
+ pLinePoints[j] = intersectPoints[j];
4906
+ }
4907
+ }
4908
+ public static getDeepCopy(pts: Array<POINT2>): Array<POINT2> {
4909
+ let deepCopy: Array<POINT2>;
4910
+ try {
4911
+ if (pts == null || pts.length === 0) {
4912
+
4913
+ return pts;
4914
+ }
4915
+
4916
+ deepCopy = new Array();
4917
+ let j: int = 0;
4918
+ let pt: POINT2;
4919
+ for (j = 0; j < pts.length; j++) {
4920
+ pt = new POINT2(pts[j].x, pts[j].y, pts[j].style);
4921
+ deepCopy.push(pt);
4922
+ }
4923
+ } catch (exc) {
4924
+ if (exc instanceof Error) {
4925
+ ErrorLogger.LogException(lineutility._className, "getDeepCopy",
4926
+ new RendererException("Failed inside getDeepCopy", exc));
4927
+ } else {
4928
+ throw exc;
4929
+ }
4930
+ }
4931
+ return deepCopy;
4932
+ }
4933
+
4934
+ }//end lineutility