@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.
- package/LICENSE +201 -0
- package/README.md +57 -0
- package/buildNode.bat +2 -0
- package/buildWeb.bat +2 -0
- package/dist/C5Ren.d.ts +6970 -0
- package/dist/C5Ren.js +2 -0
- package/dist/C5Ren.js.map +1 -0
- package/dist/LICENSE +201 -0
- package/dist/README.md +57 -0
- package/dist/armyc2.c5isr.renderer-mil-sym-ts-web-2.2.0.tgz +0 -0
- package/dist/manifest.json +4 -0
- package/dist/package.json +16 -0
- package/index.ts +169 -0
- package/package.bak +50 -0
- package/package.json +40 -0
- package/package.node.json +43 -0
- package/package.pack.json +19 -0
- package/package.packWeb.json +16 -0
- package/package.web.json +40 -0
- package/src/main/ts/android/graphics/Bitmap.ts +7 -0
- package/src/main/ts/android/graphics/Paint.ts +26 -0
- package/src/main/ts/android/graphics/Path.ts +78 -0
- package/src/main/ts/android/graphics/PointF.ts +14 -0
- package/src/main/ts/android/graphics/Rect.ts +18 -0
- package/src/main/ts/android/graphics/RectF.ts +50 -0
- package/src/main/ts/android/graphics/Region.ts +36 -0
- package/src/main/ts/android/graphics/Typeface.ts +11 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/BasicShapes.ts +99 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/CChannelPoints2.ts +34 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/CELineArray.ts +193 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/Channels.ts +2971 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/DISMSupport.ts +4008 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/POINT2.ts +93 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/Shape2.ts +89 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/TacticalLines.ts +515 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/arraysupport.ts +5403 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/countsupport.ts +1084 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/flot.ts +2173 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/lineutility.ts +4934 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/ref.ts +7 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/Modifier2.ts +5601 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/P1.ts +14 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/TGLight.ts +648 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsChannelUtility.ts +647 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsMETOC.ts +2994 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsUtility.ts +2663 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/mdlGeodesic.ts +669 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipPolygon2.ts +971 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipQuad.ts +871 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer.ts +3507 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer2.ts +500 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtility.ts +1089 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityCPOF.ts +2656 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityGE.ts +1419 -0
- package/src/main/ts/armyc2/c5isr/data/genc.json +1407 -0
- package/src/main/ts/armyc2/c5isr/data/msd.json +17311 -0
- package/src/main/ts/armyc2/c5isr/data/mse.json +18500 -0
- package/src/main/ts/armyc2/c5isr/data/svgd.json +31214 -0
- package/src/main/ts/armyc2/c5isr/data/svge.json +30558 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/AffineTransform.ts +10 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Area.ts +437 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/BasicStroke.ts +429 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/BasicTypes.ts +7 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/BufferedImage.ts +35 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Font.ts +111 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/FontMetrics.ts +29 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/FontRenderContext.ts +18 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/GeneralPath.ts +211 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Graphics2D.ts +80 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/IPathIterator.ts +33 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/ImageIO.ts +16 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Line2D.ts +726 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/PathIterator.ts +141 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Point.ts +112 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Point2D.ts +261 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Polygon.ts +391 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle.ts +567 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle2D.ts +445 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Shape.ts +31 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Stroke.ts +18 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/TextLayout.ts +45 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/TexturePaint.ts +25 -0
- package/src/main/ts/armyc2/c5isr/renderer/IIconRenderer.ts +15 -0
- package/src/main/ts/armyc2/c5isr/renderer/IconRenderer.ts +22 -0
- package/src/main/ts/armyc2/c5isr/renderer/MilStdIconRenderer.ts +269 -0
- package/src/main/ts/armyc2/c5isr/renderer/ModifierRenderer.ts +9882 -0
- package/src/main/ts/armyc2/c5isr/renderer/PatternFillRenderer.ts +146 -0
- package/src/main/ts/armyc2/c5isr/renderer/SinglePointSVGRenderer.ts +1265 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/arc.ts +64 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/bcurve.ts +95 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/ellipse.ts +93 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/line.ts +114 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/path.ts +555 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/pathiterator.ts +62 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/point.ts +120 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/rectangle.ts +431 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/roundedrectangle.ts +99 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/types.ts +25 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/utilities.ts +203 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/AffiliationColors.ts +104 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/Color.ts +481 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/DistanceUnit.ts +40 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/DrawRules.ts +1323 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/EntityCode.ts +51 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/ErrorLogger.ts +736 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/GENCLookup.ts +106 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/GeoPixelConversion3D.ts +84 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/IMultiPointRenderer.ts +87 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/IPointConversion.ts +34 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/ImageInfo.ts +324 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUCache.ts +127 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUEntry.ts +18 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/LogLevel.ts +111 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MODrawRules.ts +219 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MSInfo.ts +1008 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MSLookup.ts +882 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdAttributes.ts +380 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdSymbol.ts +797 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/Modifiers.ts +1699 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversion.ts +178 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversionDummy.ts +45 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConverter3D.ts +126 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/RectUtilities.ts +118 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererException.ts +11 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererSettings.ts +1201 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererUtilities.ts +591 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGInfo.ts +29 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGLookup.ts +753 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGSymbolInfo.ts +137 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGTextInfo.ts +438 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEvent.ts +19 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEventListener.ts +10 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsEventListener.ts +5 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/Shape2SVG.ts +404 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeInfo.ts +525 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeUtilities.ts +55 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolDimensionInfo.ts +36 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolID.ts +1055 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolUtilities.ts +2085 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/TextInfo.ts +157 -0
- package/src/main/ts/armyc2/c5isr/web/render/GeoPixelConversion.ts +86 -0
- package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandler.ts +3798 -0
- package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandlerSVG.ts +412 -0
- package/src/main/ts/armyc2/c5isr/web/render/PointConverter.ts +124 -0
- package/src/main/ts/armyc2/c5isr/web/render/SymbolModifiers.ts +26 -0
- package/src/main/ts/armyc2/c5isr/web/render/WebRenderer.ts +677 -0
- package/src/main/ts/armyc2/c5isr/web/render/utilities/JavaRendererUtilities.ts +484 -0
- package/src/main/ts/armyc2/c5isr/web/render/utilities/LineInfo.ts +62 -0
- package/src/main/ts/armyc2/c5isr/web/render/utilities/SymbolInfo.ts +46 -0
- package/src/main/ts/armyc2/c5isr/web/render/utilities/TextInfo.ts +51 -0
- package/src/main/ts/org/gavaghan/geodesy/Angle.ts +31 -0
- package/src/main/ts/org/gavaghan/geodesy/Ellipsoid.ts +71 -0
- package/src/main/ts/org/gavaghan/geodesy/GeodeticCalculator.ts +200 -0
- package/src/main/ts/org/gavaghan/geodesy/GeodeticCurve.ts +55 -0
- package/src/main/ts/org/gavaghan/geodesy/GeodeticMeasurement.ts +68 -0
- package/src/main/ts/org/gavaghan/geodesy/GlobalCoordinates.ts +103 -0
- package/src/main/ts/org/gavaghan/geodesy/GlobalPosition.ts +90 -0
- package/test/ExportSPImages.js +692 -0
- package/test/MPWW.html +556 -0
- package/test/MPWorker.js +318 -0
- package/test/SPWorker.js +233 -0
- package/test/SVGWW.html +363 -0
- package/test/singlePointTester3.html +751 -0
- package/tsconfig.json +54 -0
- package/typedoc.json +30 -0
- package/updateVersion.js +21 -0
- package/webpack.config.js +34 -0
- package/webpackn.config.js +28 -0
- package/webpackr.config.js +47 -0
- 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
|