geometrix 0.5.10 → 0.5.12
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/dist/index.d.ts +505 -0
- package/dist/index.js +3848 -0
- package/package.json +7 -1
- package/.eslintignore +0 -17
- package/.eslintrc.cjs +0 -24
- package/.prettierignore +0 -15
- package/.prettierrc +0 -8
- package/src/aaExportContent.ts +0 -213
- package/src/aaExportFile.ts +0 -141
- package/src/aaParamGeom.ts +0 -62
- package/src/angle_utils.test.ts +0 -83
- package/src/angle_utils.ts +0 -98
- package/src/arc_to_stroke.ts +0 -73
- package/src/canvas_utils.test.ts +0 -28
- package/src/canvas_utils.ts +0 -159
- package/src/contour.test.ts +0 -37
- package/src/contour.ts +0 -806
- package/src/designParams.ts +0 -178
- package/src/figure.test.ts +0 -21
- package/src/figure.ts +0 -400
- package/src/index.ts +0 -16
- package/src/line.test.ts +0 -78
- package/src/line.ts +0 -359
- package/src/paramFile.ts +0 -52
- package/src/point.test.ts +0 -36
- package/src/point.ts +0 -246
- package/src/prepare_pax.ts +0 -102
- package/src/segment.test.ts +0 -26
- package/src/segment.ts +0 -701
- package/src/sub_design.ts +0 -16
- package/src/triangle_utils.test.ts +0 -38
- package/src/triangle_utils.ts +0 -112
- package/src/vector.test.ts +0 -28
- package/src/vector.ts +0 -122
- package/src/volume.ts +0 -50
- package/src/write_dxf.ts +0 -100
- package/src/write_openjscad.ts +0 -284
- package/src/write_openscad.ts +0 -305
- package/src/write_pax.ts +0 -73
- package/src/write_svg.ts +0 -101
- package/svg/any_triangle.svg +0 -156
- package/svg/arc_definition.svg +0 -506
- package/svg/construct_corner_rounded_ext_arc_ext_arc.svg +0 -378
- package/svg/construct_corner_rounded_int_arc_ext_arc.svg +0 -359
- package/svg/construct_corner_rounded_int_arc_int_arc.svg +0 -356
- package/svg/construct_corner_rounded_stroke_ext_arc.svg +0 -374
- package/svg/construct_corner_rounded_stroke_ext_arc_obtuse.svg +0 -370
- package/svg/construct_corner_rounded_stroke_ext_arc_obtuse_method2.svg +0 -311
- package/svg/construct_corner_rounded_stroke_int_arc.svg +0 -364
- package/svg/construct_corner_rounded_stroke_int_arc_obtuse.svg +0 -358
- package/svg/construct_corner_rounded_stroke_int_arc_obtuse_method2.svg +0 -237
- package/svg/construct_corner_rounded_stroke_stroke.svg +0 -280
- package/svg/construct_corner_wideacc.svg +0 -286
- package/svg/construct_corner_widened.svg +0 -278
- package/svg/construction_of_line_intersection_1.svg +0 -187
- package/svg/construction_of_line_intersection_2.svg +0 -189
- package/svg/contour_arc_definition_options.svg +0 -324
- package/svg/contour_point_absolute_relative.svg +0 -258
- package/svg/contour_tangential_two_arcs.svg +0 -531
- package/svg/contour_tangential_two_arcs_impossible_case.svg +0 -175
- package/svg/contour_tangential_two_arcs_requirements.svg +0 -364
- package/svg/corner_rounded_ext_arc_ext_arc.svg +0 -281
- package/svg/corner_rounded_int_arc_ext_arc.svg +0 -281
- package/svg/corner_rounded_int_arc_int_arc.svg +0 -279
- package/svg/corner_rounded_stroke_ext_arc.svg +0 -218
- package/svg/corner_rounded_stroke_int_arc.svg +0 -225
- package/svg/corner_rounded_stroke_stroke.svg +0 -174
- package/svg/geom_dev.svg +0 -14708
- package/svg/geom_modules.svg +0 -246
- package/svg/geom_user.svg +0 -58
- package/svg/line_axis_x_cases.svg +0 -1408
- package/svg/line_axis_y_cases.svg +0 -1369
- package/svg/line_distanceOrig.svg +0 -318
- package/svg/line_getAxisXIntersection.svg +0 -262
- package/svg/line_getAxisXIntersection_2.svg +0 -244
- package/svg/line_getAxisYIntersection.svg +0 -304
- package/svg/line_getAxisYIntersection_2.svg +0 -285
- package/svg/line_getAxisYIntersection_3.svg +0 -277
- package/svg/line_intersection.svg +0 -346
- package/svg/line_projectPoint.svg +0 -311
- package/svg/point_1.svg +0 -243
- package/svg/point_2.svg +0 -409
- package/svg/point_3.svg +0 -298
- package/svg/point_4.svg +0 -272
- package/svg/point_5.svg +0 -356
- package/svg/right_triangle.svg +0 -194
- package/svg/vector_definition.svg +0 -130
- package/tsconfig.json +0 -13
- package/vitest.config.ts +0 -7
package/src/contour.ts
DELETED
|
@@ -1,806 +0,0 @@
|
|
|
1
|
-
// contour.ts
|
|
2
|
-
// contour.ts deals with open and closed path composed of segments and arcs
|
|
3
|
-
// contour.ts depends on point.ts, line.ts, vector.ts and segment.ts
|
|
4
|
-
// contour.ts is used by figure.ts
|
|
5
|
-
|
|
6
|
-
import type { tCanvasAdjust } from './canvas_utils';
|
|
7
|
-
//import type { tPolar } from './point';
|
|
8
|
-
//import { colorCanvasPoint } from '$lib/style/colors.scss';
|
|
9
|
-
import {
|
|
10
|
-
//degToRad,
|
|
11
|
-
//radToDeg,
|
|
12
|
-
roundZero,
|
|
13
|
-
//withinZero2Pi,
|
|
14
|
-
withinPiPi,
|
|
15
|
-
//withinZeroPi,
|
|
16
|
-
//withinHPiHPi,
|
|
17
|
-
ffix
|
|
18
|
-
} from './angle_utils';
|
|
19
|
-
import { colors, point2canvas, radius2canvas } from './canvas_utils';
|
|
20
|
-
//import {
|
|
21
|
-
// //rightTriLaFromLbLc,
|
|
22
|
-
// rightTriLbFromLaLc
|
|
23
|
-
// //lcFromLaLbAc,
|
|
24
|
-
// //aCFromLaLbLc,
|
|
25
|
-
// //aCFromAaAb,
|
|
26
|
-
// //lbFromLaAaAb,
|
|
27
|
-
// //aBFromLaLbAa
|
|
28
|
-
//} from './triangle_utils';
|
|
29
|
-
import { point, Point } from './point';
|
|
30
|
-
import { line, Line, bisector, circleCenter } from './line';
|
|
31
|
-
//import { vector, Vector } from './vector';
|
|
32
|
-
import * as segLib from './segment';
|
|
33
|
-
import { svgPath, svgCircleString } from './write_svg';
|
|
34
|
-
import type { DxfSeg } from './write_dxf';
|
|
35
|
-
import { dxfSegLine, dxfSegArc, dxfSegCircle } from './write_dxf';
|
|
36
|
-
import type { tPaxContourPath, tPaxContourCircle, tPaxContour } from './prepare_pax';
|
|
37
|
-
import { paxPath, paxCircle } from './prepare_pax';
|
|
38
|
-
|
|
39
|
-
/* AContour abstract class */
|
|
40
|
-
|
|
41
|
-
abstract class AContour {
|
|
42
|
-
abstract circle: boolean;
|
|
43
|
-
abstract imposedColor: string;
|
|
44
|
-
abstract draw(ctx: CanvasRenderingContext2D, cAdjust: tCanvasAdjust, color: string): void;
|
|
45
|
-
abstract extractSkeleton(): AContour;
|
|
46
|
-
abstract generateContour(): AContour;
|
|
47
|
-
abstract generatePoints(): Point[];
|
|
48
|
-
abstract generateLines(): Line[];
|
|
49
|
-
abstract check(): string;
|
|
50
|
-
abstract toSvg(yCeiling: number, color?: string): string;
|
|
51
|
-
abstract toDxfSeg(): DxfSeg[];
|
|
52
|
-
abstract toPax(): tPaxContour;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/* Contour class */
|
|
56
|
-
|
|
57
|
-
class Contour extends AContour {
|
|
58
|
-
circle = false;
|
|
59
|
-
segments: segLib.Segment1[];
|
|
60
|
-
points: Point[];
|
|
61
|
-
debugPoints: Point[];
|
|
62
|
-
debugLines: Line[];
|
|
63
|
-
lastPoint: Point;
|
|
64
|
-
imposedColor: string;
|
|
65
|
-
constructor(ix: number, iy: number, icolor = '') {
|
|
66
|
-
super();
|
|
67
|
-
this.segments = [new segLib.Segment1(segLib.SegEnum.eStart, ix, iy, 0)];
|
|
68
|
-
this.points = [];
|
|
69
|
-
this.debugPoints = [];
|
|
70
|
-
this.debugLines = [];
|
|
71
|
-
this.lastPoint = point(ix, iy);
|
|
72
|
-
this.imposedColor = icolor;
|
|
73
|
-
}
|
|
74
|
-
setLastPoint(ix: number, iy: number) {
|
|
75
|
-
this.lastPoint = point(ix, iy);
|
|
76
|
-
}
|
|
77
|
-
getLastPoint(): Point {
|
|
78
|
-
return this.lastPoint;
|
|
79
|
-
}
|
|
80
|
-
addPointA(ax: number, ay: number): Contour {
|
|
81
|
-
if (this.points.length > 2) {
|
|
82
|
-
throw `err311: contour add too much point ${ax} ${ay}`;
|
|
83
|
-
}
|
|
84
|
-
this.points.push(point(ax, ay));
|
|
85
|
-
return this;
|
|
86
|
-
}
|
|
87
|
-
addPointAP(aa: number, al: number): Contour {
|
|
88
|
-
const p1 = point(0, 0).translatePolar(aa, al);
|
|
89
|
-
this.addPointA(p1.cx, p1.cy);
|
|
90
|
-
return this;
|
|
91
|
-
}
|
|
92
|
-
addPointR(rx: number, ry: number): Contour {
|
|
93
|
-
const plast = this.getLastPoint();
|
|
94
|
-
const p1 = plast.translate(rx, ry);
|
|
95
|
-
this.addPointA(p1.cx, p1.cy);
|
|
96
|
-
return this;
|
|
97
|
-
}
|
|
98
|
-
addPointRP(ra: number, rl: number): Contour {
|
|
99
|
-
const plast = this.getLastPoint();
|
|
100
|
-
const p1 = plast.translatePolar(ra, rl);
|
|
101
|
-
this.addPointA(p1.cx, p1.cy);
|
|
102
|
-
return this;
|
|
103
|
-
}
|
|
104
|
-
addSeg(iSeg: segLib.Segment1): Contour {
|
|
105
|
-
this.segments.push(iSeg);
|
|
106
|
-
return this;
|
|
107
|
-
}
|
|
108
|
-
addSegStroke(): Contour {
|
|
109
|
-
if (this.points.length !== 1) {
|
|
110
|
-
throw `err554: contour addSegStroke with unexpected points.length ${this.points.length}`;
|
|
111
|
-
}
|
|
112
|
-
const p1 = this.points.pop();
|
|
113
|
-
if (p1 !== undefined) {
|
|
114
|
-
const seg = new segLib.Segment1(segLib.SegEnum.eStroke, p1.cx, p1.cy, 0);
|
|
115
|
-
if (!p1.isEqual(this.getLastPoint())) {
|
|
116
|
-
this.addSeg(seg);
|
|
117
|
-
this.setLastPoint(p1.cx, p1.cy);
|
|
118
|
-
}
|
|
119
|
-
// else no warning in order to avoid warning in gears
|
|
120
|
-
} else {
|
|
121
|
-
throw `err284: contour p1 is undefined`;
|
|
122
|
-
}
|
|
123
|
-
return this;
|
|
124
|
-
}
|
|
125
|
-
addSegStrokeA(ax: number, ay: number): Contour {
|
|
126
|
-
this.addPointA(ax, ay).addSegStroke();
|
|
127
|
-
return this;
|
|
128
|
-
}
|
|
129
|
-
addSegStrokeAP(aa: number, al: number): Contour {
|
|
130
|
-
this.addPointAP(aa, al).addSegStroke();
|
|
131
|
-
return this;
|
|
132
|
-
}
|
|
133
|
-
addSegStrokeR(rx: number, ry: number): Contour {
|
|
134
|
-
this.addPointR(rx, ry).addSegStroke();
|
|
135
|
-
return this;
|
|
136
|
-
}
|
|
137
|
-
addSegStrokeRP(ra: number, rl: number): Contour {
|
|
138
|
-
this.addPointRP(ra, rl).addSegStroke();
|
|
139
|
-
return this;
|
|
140
|
-
}
|
|
141
|
-
addSegArc(iRadius: number, iLarge: boolean, iCcw: boolean): Contour {
|
|
142
|
-
if (this.points.length !== 1) {
|
|
143
|
-
throw `err954: contour addSegArc with unexpected points.length ${this.points.length}`;
|
|
144
|
-
}
|
|
145
|
-
const p1 = this.points.pop();
|
|
146
|
-
if (p1 !== undefined) {
|
|
147
|
-
const seg = new segLib.Segment1(
|
|
148
|
-
segLib.SegEnum.eArc,
|
|
149
|
-
p1.cx,
|
|
150
|
-
p1.cy,
|
|
151
|
-
iRadius,
|
|
152
|
-
iLarge,
|
|
153
|
-
iCcw
|
|
154
|
-
);
|
|
155
|
-
if (!p1.isEqual(this.getLastPoint())) {
|
|
156
|
-
this.addSeg(seg);
|
|
157
|
-
this.setLastPoint(p1.cx, p1.cy);
|
|
158
|
-
} else {
|
|
159
|
-
console.log(
|
|
160
|
-
`warn144: addSegArc last and new point identical ${ffix(p1.cx)} ${ffix(p1.cy)}`
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
//this.debugPoints.push(p1);
|
|
164
|
-
} else {
|
|
165
|
-
throw `err482: contour p1 is undefined`;
|
|
166
|
-
}
|
|
167
|
-
return this;
|
|
168
|
-
}
|
|
169
|
-
addSegArc2(): Contour {
|
|
170
|
-
if (this.points.length !== 2) {
|
|
171
|
-
throw `err958: contour addSegArc2 with unexpected points.length ${this.points.length}`;
|
|
172
|
-
}
|
|
173
|
-
const p2 = this.points.pop();
|
|
174
|
-
const p1 = this.points.pop();
|
|
175
|
-
if (p1 !== undefined && p2 !== undefined) {
|
|
176
|
-
const p0 = this.getLastPoint();
|
|
177
|
-
const p3 = circleCenter(p0, p1, p2);
|
|
178
|
-
const radius = p3.distanceToPoint(p0);
|
|
179
|
-
const p0p2middle = p0.middlePoint(p2);
|
|
180
|
-
const a0 = p0p2middle.angleToPoint(p0);
|
|
181
|
-
const a1 = p0p2middle.angleToPoint(p1);
|
|
182
|
-
const a3 = p0p2middle.angleToPoint(p3);
|
|
183
|
-
const a01 = withinPiPi(a1 - a0);
|
|
184
|
-
const a03 = withinPiPi(a3 - a0);
|
|
185
|
-
let large = false;
|
|
186
|
-
let ccw = false;
|
|
187
|
-
if (Math.sign(a03) * Math.sign(a01) > 0) {
|
|
188
|
-
large = true;
|
|
189
|
-
}
|
|
190
|
-
if (Math.sign(a01) > 0) {
|
|
191
|
-
ccw = true;
|
|
192
|
-
}
|
|
193
|
-
//console.log(`dbg437: ${radius.toFixed(2)} ${large} ${ccw}`);
|
|
194
|
-
this.addPointA(p2.cx, p2.cy).addSegArc(radius, large, ccw);
|
|
195
|
-
this.debugPoints.push(p1);
|
|
196
|
-
//this.debugPoints.push(p2);
|
|
197
|
-
} else {
|
|
198
|
-
throw `err488: contour p1 or p2 or seg is undefined`;
|
|
199
|
-
}
|
|
200
|
-
return this;
|
|
201
|
-
}
|
|
202
|
-
addSegArc3(iTangentAngle1: number, firstNlast: boolean): Contour {
|
|
203
|
-
if (this.points.length !== 1) {
|
|
204
|
-
throw `err914: contour addSegArc3 with unexpected points.length ${this.points.length}`;
|
|
205
|
-
}
|
|
206
|
-
const p1 = this.points.pop();
|
|
207
|
-
if (p1 !== undefined) {
|
|
208
|
-
const p0 = this.getLastPoint();
|
|
209
|
-
const lbi = bisector(p0, p1);
|
|
210
|
-
let pref = p1;
|
|
211
|
-
if (firstNlast) {
|
|
212
|
-
pref = p0;
|
|
213
|
-
}
|
|
214
|
-
const lradial = line(pref.cx, pref.cy, iTangentAngle1 + Math.PI / 2);
|
|
215
|
-
const pArcCenter = lbi.intersection(lradial);
|
|
216
|
-
const radius = pArcCenter.distanceToPoint(p0);
|
|
217
|
-
const pmid = p0.middlePoint(p1);
|
|
218
|
-
const amid = pref.angleToPoint(pmid);
|
|
219
|
-
const aref = withinPiPi(iTangentAngle1 - amid);
|
|
220
|
-
let large = false;
|
|
221
|
-
if (Math.abs(aref) > Math.PI / 2) {
|
|
222
|
-
large = true;
|
|
223
|
-
}
|
|
224
|
-
let ccw = false;
|
|
225
|
-
if (aref < 0) {
|
|
226
|
-
ccw = true;
|
|
227
|
-
}
|
|
228
|
-
if (!firstNlast) {
|
|
229
|
-
ccw = !ccw;
|
|
230
|
-
}
|
|
231
|
-
this.addPointA(p1.cx, p1.cy).addSegArc(radius, large, ccw);
|
|
232
|
-
this.debugPoints.push(pmid);
|
|
233
|
-
this.debugPoints.push(pArcCenter);
|
|
234
|
-
} else {
|
|
235
|
-
throw `err282: contour p1 is undefined`;
|
|
236
|
-
}
|
|
237
|
-
return this;
|
|
238
|
-
}
|
|
239
|
-
addSeg2Arcs(ita1: number, ita2: number): Contour {
|
|
240
|
-
if (this.points.length !== 1) {
|
|
241
|
-
throw `err214: contour addSeg2Arcs with unexpected points.length ${this.points.length}`;
|
|
242
|
-
}
|
|
243
|
-
const p1 = this.points.pop();
|
|
244
|
-
if (p1 !== undefined) {
|
|
245
|
-
const p0 = this.getLastPoint();
|
|
246
|
-
const l01 = p0.distanceToPoint(p1);
|
|
247
|
-
const a01 = p0.angleToPoint(p1);
|
|
248
|
-
const a10 = p1.angleToPoint(p0);
|
|
249
|
-
const au = withinPiPi(ita1 - a01);
|
|
250
|
-
const av = -1 * withinPiPi(ita2 - a10);
|
|
251
|
-
//console.log(`dbg998: addSeg2Arcs au ${au} av ${av}`);
|
|
252
|
-
if (Math.abs(au) >= Math.PI / 2) {
|
|
253
|
-
throw `err545: addSeg2Arcs with too large au ${au}`;
|
|
254
|
-
}
|
|
255
|
-
if (Math.abs(av) >= Math.PI / 2) {
|
|
256
|
-
throw `err546: addSeg2Arcs with too large av ${av}`;
|
|
257
|
-
}
|
|
258
|
-
if (roundZero(au) === 0) {
|
|
259
|
-
throw `err765: addSeg2Arcs with almost zero au ${au}`;
|
|
260
|
-
}
|
|
261
|
-
if (roundZero(av) === 0) {
|
|
262
|
-
throw `err766: addSeg2Arcs with almost zero av ${av}`;
|
|
263
|
-
}
|
|
264
|
-
if (Math.sign(au) * Math.sign(av) < 1) {
|
|
265
|
-
throw `err767: addSeg2Arcs with au/av bad orientation ${au} ${av}`;
|
|
266
|
-
}
|
|
267
|
-
// l01=BH+HC
|
|
268
|
-
// HG=BH*tan(au/2)=HC*tan(av/2)
|
|
269
|
-
// l01=HG*(1/tan(au/2)+1/tan(av/2))
|
|
270
|
-
// l01*tan(au/2)*tan(av/2)=HG*tan(av/2)+HG*tan(au/2)
|
|
271
|
-
// HG=l01*tan(au/2)*tan(av/2)/(tan(av/2)+tan(au/2))
|
|
272
|
-
// trigonometry half-angle formula: tan(a/2)=(1-cos(a))/sin(a)
|
|
273
|
-
// trigonometry tan(a+b)=(tan(a)+tan(b))/(1-tan(a)*tan(b))
|
|
274
|
-
const tanu2 = Math.tan(au / 2);
|
|
275
|
-
const tanv2 = Math.tan(av / 2);
|
|
276
|
-
//const lHG = (l01 * tanu2 * tanv2) / (tanv2 + tanu2); // only for console.log()
|
|
277
|
-
//const lBH = lHG/tanu2;
|
|
278
|
-
const lBH = (l01 * tanv2) / (tanv2 + tanu2);
|
|
279
|
-
// cos(PI/2-au)=sin(u)=lBH/lJB
|
|
280
|
-
// lJB=lBH/sin(au)
|
|
281
|
-
const lJB = Math.abs(lBH / Math.sin(au));
|
|
282
|
-
//const lJH = lBH / Math.cotan(au);
|
|
283
|
-
const lBG = lBH / Math.cos(au / 2);
|
|
284
|
-
const lHC = (l01 * tanu2) / (tanv2 + tanu2);
|
|
285
|
-
const lIC = Math.abs(lHC / Math.sin(av));
|
|
286
|
-
//const lCG = lHC / Math.cos(av / 2); // only for console.log()
|
|
287
|
-
const p2 = p0.translatePolar(a01 + au / 2, lBG);
|
|
288
|
-
let ccw = false;
|
|
289
|
-
if (Math.sign(au) < 0) {
|
|
290
|
-
ccw = true;
|
|
291
|
-
}
|
|
292
|
-
//console.log(`dbg401: addSeg2Arcs l01 ${l01} lHG ${lHG}`);
|
|
293
|
-
//console.log(`dbg409: addSeg2Arcs lBH ${lBH} lBG ${lBG} lJB ${lJB}`);
|
|
294
|
-
//console.log(`dbg408: addSeg2Arcs lHC ${lHC} lCG ${lCG} lIC ${lIC}`);
|
|
295
|
-
this.addPointA(p2.cx, p2.cy).addSegArc(lJB, false, ccw);
|
|
296
|
-
this.addPointA(p1.cx, p1.cy).addSegArc(lIC, false, ccw);
|
|
297
|
-
//this.debugPoints.push(p2);
|
|
298
|
-
this.debugPoints.push(p0.translatePolar(a01, lBH)); // H
|
|
299
|
-
this.debugPoints.push(p0.translatePolar(a01 + au - (Math.sign(au) * Math.PI) / 2, lJB)); // J
|
|
300
|
-
//this.debugPoints.push(p1.translatePolar(a10, lHC)); // H
|
|
301
|
-
this.debugPoints.push(p1.translatePolar(a10 - av + (Math.sign(au) * Math.PI) / 2, lIC)); // I
|
|
302
|
-
} else {
|
|
303
|
-
throw `err182: contour p1 is undefined`;
|
|
304
|
-
}
|
|
305
|
-
return this;
|
|
306
|
-
}
|
|
307
|
-
addCornerPointed(): Contour {
|
|
308
|
-
const seg = new segLib.Segment1(segLib.SegEnum.ePointed, 0, 0, 0);
|
|
309
|
-
this.addSeg(seg);
|
|
310
|
-
return this;
|
|
311
|
-
}
|
|
312
|
-
addCornerRounded(iRadius: number): Contour {
|
|
313
|
-
const seg = new segLib.Segment1(segLib.SegEnum.eRounded, 0, 0, iRadius);
|
|
314
|
-
this.addSeg(seg);
|
|
315
|
-
return this;
|
|
316
|
-
}
|
|
317
|
-
addCornerWidened(iRadius: number): Contour {
|
|
318
|
-
const seg = new segLib.Segment1(segLib.SegEnum.eWidened, 0, 0, iRadius);
|
|
319
|
-
this.addSeg(seg);
|
|
320
|
-
return this;
|
|
321
|
-
}
|
|
322
|
-
addCornerWideAcc(iRadius: number): Contour {
|
|
323
|
-
const seg = new segLib.Segment1(segLib.SegEnum.eWideAcc, 0, 0, iRadius);
|
|
324
|
-
this.addSeg(seg);
|
|
325
|
-
return this;
|
|
326
|
-
}
|
|
327
|
-
closeSegStroke(): Contour {
|
|
328
|
-
const px = this.segments[0].px;
|
|
329
|
-
const py = this.segments[0].py;
|
|
330
|
-
this.addSegStrokeA(px, py);
|
|
331
|
-
return this;
|
|
332
|
-
}
|
|
333
|
-
closeSegArc(iRadius: number, iLarge: boolean, iCcw: boolean): Contour {
|
|
334
|
-
const px = this.segments[0].px;
|
|
335
|
-
const py = this.segments[0].py;
|
|
336
|
-
this.addPointA(px, py).addSegArc(iRadius, iLarge, iCcw);
|
|
337
|
-
return this;
|
|
338
|
-
}
|
|
339
|
-
clone(): Contour {
|
|
340
|
-
const rctr = new Contour(this.segments[0].px, this.segments[0].py);
|
|
341
|
-
for (const seg of this.segments) {
|
|
342
|
-
const nseg = seg.clone();
|
|
343
|
-
if (nseg.sType !== segLib.SegEnum.eStart) {
|
|
344
|
-
rctr.addSeg(nseg);
|
|
345
|
-
if (segLib.isSeg(nseg.sType)) {
|
|
346
|
-
rctr.setLastPoint(nseg.px, nseg.py);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
return rctr;
|
|
351
|
-
}
|
|
352
|
-
translate(ix: number, iy: number): Contour {
|
|
353
|
-
const p0x = this.segments[0].px + ix;
|
|
354
|
-
const p0y = this.segments[0].py + iy;
|
|
355
|
-
const rctr = new Contour(p0x, p0y);
|
|
356
|
-
for (const seg of this.segments) {
|
|
357
|
-
const nseg = seg.clone();
|
|
358
|
-
if (segLib.isSeg(seg.sType)) {
|
|
359
|
-
nseg.px += ix;
|
|
360
|
-
nseg.py += iy;
|
|
361
|
-
}
|
|
362
|
-
if (nseg.sType !== segLib.SegEnum.eStart) {
|
|
363
|
-
rctr.addSeg(nseg);
|
|
364
|
-
if (segLib.isSeg(nseg.sType)) {
|
|
365
|
-
rctr.setLastPoint(nseg.px, nseg.py);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
return rctr;
|
|
370
|
-
}
|
|
371
|
-
translatePolar(ia: number, il: number): Contour {
|
|
372
|
-
return this.translate(il * Math.cos(ia), il * Math.sin(ia));
|
|
373
|
-
}
|
|
374
|
-
rotate(ix: number, iy: number, ia: number): Contour {
|
|
375
|
-
const ic = point(ix, iy);
|
|
376
|
-
const pStart = point(this.segments[0].px, this.segments[0].py);
|
|
377
|
-
const pStartRot = pStart.rotate(ic, ia);
|
|
378
|
-
const rctr = new Contour(pStartRot.cx, pStartRot.cy);
|
|
379
|
-
for (const seg of this.segments) {
|
|
380
|
-
const nseg = seg.clone();
|
|
381
|
-
if (segLib.isSeg(seg.sType)) {
|
|
382
|
-
const pt = point(nseg.px, nseg.py);
|
|
383
|
-
const ptRot = pt.rotate(ic, ia);
|
|
384
|
-
nseg.px = ptRot.cx;
|
|
385
|
-
nseg.py = ptRot.cy;
|
|
386
|
-
}
|
|
387
|
-
if (nseg.sType !== segLib.SegEnum.eStart) {
|
|
388
|
-
rctr.addSeg(nseg);
|
|
389
|
-
if (segLib.isSeg(nseg.sType)) {
|
|
390
|
-
rctr.setLastPoint(nseg.px, nseg.py);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
return rctr;
|
|
395
|
-
}
|
|
396
|
-
scale(ix: number, iy: number, ir: number, scaleCorner = false): Contour {
|
|
397
|
-
const ic = point(ix, iy);
|
|
398
|
-
const pStart = point(this.segments[0].px, this.segments[0].py);
|
|
399
|
-
const pStartScale = pStart.scale(ic, ir);
|
|
400
|
-
const rctr = new Contour(pStartScale.cx, pStartScale.cy);
|
|
401
|
-
for (const seg of this.segments) {
|
|
402
|
-
const nseg = seg.clone();
|
|
403
|
-
if (segLib.isSeg(seg.sType)) {
|
|
404
|
-
const pt = point(nseg.px, nseg.py);
|
|
405
|
-
const ptScale = pt.scale(ic, ir);
|
|
406
|
-
nseg.px = ptScale.cx;
|
|
407
|
-
nseg.py = ptScale.cy;
|
|
408
|
-
}
|
|
409
|
-
if (seg.sType === segLib.SegEnum.eArc) {
|
|
410
|
-
nseg.radius *= ir;
|
|
411
|
-
}
|
|
412
|
-
if (segLib.isActiveCorner(seg.sType) && scaleCorner) {
|
|
413
|
-
nseg.radius *= ir;
|
|
414
|
-
}
|
|
415
|
-
if (nseg.sType !== segLib.SegEnum.eStart) {
|
|
416
|
-
rctr.addSeg(nseg);
|
|
417
|
-
if (segLib.isSeg(nseg.sType)) {
|
|
418
|
-
rctr.setLastPoint(nseg.px, nseg.py);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
return rctr;
|
|
423
|
-
}
|
|
424
|
-
addPartial(iContour: Contour): Contour {
|
|
425
|
-
if (this.points.length > 0) {
|
|
426
|
-
throw `err911: addPartial, points should be used ${this.points.length}`;
|
|
427
|
-
}
|
|
428
|
-
for (const seg of iContour.segments) {
|
|
429
|
-
if (seg.sType !== segLib.SegEnum.eStart) {
|
|
430
|
-
this.addSeg(seg);
|
|
431
|
-
if (segLib.isSeg(seg.sType)) {
|
|
432
|
-
this.setLastPoint(seg.px, seg.py);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
return this;
|
|
437
|
-
}
|
|
438
|
-
draw(ctx: CanvasRenderingContext2D, cAdjust: tCanvasAdjust, color: string = colors.contour) {
|
|
439
|
-
const theColor = this.imposedColor === '' ? color : this.imposedColor;
|
|
440
|
-
let px1 = 0;
|
|
441
|
-
let py1 = 0;
|
|
442
|
-
for (const seg of this.segments) {
|
|
443
|
-
if (seg.sType === segLib.SegEnum.eStroke) {
|
|
444
|
-
const [cx1, cy1] = point2canvas(px1, py1, cAdjust);
|
|
445
|
-
const [cx2, cy2] = point2canvas(seg.px, seg.py, cAdjust);
|
|
446
|
-
ctx.beginPath();
|
|
447
|
-
ctx.moveTo(cx1, cy1);
|
|
448
|
-
ctx.lineTo(cx2, cy2);
|
|
449
|
-
ctx.strokeStyle = theColor;
|
|
450
|
-
ctx.stroke();
|
|
451
|
-
}
|
|
452
|
-
if (seg.sType === segLib.SegEnum.eArc) {
|
|
453
|
-
try {
|
|
454
|
-
const seg2 = segLib.arcSeg1To2(px1, py1, seg);
|
|
455
|
-
const [cx3, cy3] = point2canvas(seg2.pc.cx, seg2.pc.cy, cAdjust);
|
|
456
|
-
const cRadius = radius2canvas(seg.radius, cAdjust);
|
|
457
|
-
ctx.beginPath();
|
|
458
|
-
ctx.arc(cx3, cy3, cRadius, -seg2.a1, -seg2.a2, seg.arcCcw);
|
|
459
|
-
ctx.strokeStyle = theColor;
|
|
460
|
-
ctx.stroke();
|
|
461
|
-
} catch (emsg) {
|
|
462
|
-
console.log('err413: ' + (emsg as string));
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
if (segLib.isAddPoint(seg.sType)) {
|
|
466
|
-
px1 = seg.px;
|
|
467
|
-
py1 = seg.py;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
extractSkeleton(): Contour {
|
|
472
|
-
const seg0 = this.segments[0];
|
|
473
|
-
const rContour = new Contour(seg0.px, seg0.py);
|
|
474
|
-
for (const seg of this.segments) {
|
|
475
|
-
if (segLib.isSeg(seg.sType)) {
|
|
476
|
-
rContour.addSeg(seg);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
return rContour;
|
|
480
|
-
}
|
|
481
|
-
generateContour(): Contour {
|
|
482
|
-
segLib.gSegDbg.clearPoints();
|
|
483
|
-
segLib.gSegDbg.clearLines();
|
|
484
|
-
const segStack: segLib.Segment2[] = [];
|
|
485
|
-
const segStackEnd: segLib.Segment2[] = [];
|
|
486
|
-
let coType = 0;
|
|
487
|
-
let px1 = 0;
|
|
488
|
-
let py1 = 0;
|
|
489
|
-
for (const seg of this.segments) {
|
|
490
|
-
if (seg.sType === segLib.SegEnum.eStroke) {
|
|
491
|
-
const p1 = point(px1, py1);
|
|
492
|
-
const p2 = point(seg.px, seg.py);
|
|
493
|
-
const p0 = point(0, 0);
|
|
494
|
-
segStack.push(new segLib.Segment2(seg.sType, p1, p2, p0, 0, 0, 0, false));
|
|
495
|
-
coType = 1;
|
|
496
|
-
}
|
|
497
|
-
if (seg.sType === segLib.SegEnum.eArc) {
|
|
498
|
-
const seg2 = segLib.arcSeg1To2(px1, py1, seg);
|
|
499
|
-
segStack.push(seg2);
|
|
500
|
-
coType = 1;
|
|
501
|
-
}
|
|
502
|
-
const segz1 = segStack.at(-1);
|
|
503
|
-
const segz2 = segStack.at(-2);
|
|
504
|
-
if (segz1 !== undefined && segz2 !== undefined) {
|
|
505
|
-
if (segLib.isSeg(segz1.sType) && segLib.isCorner(segz2.sType)) {
|
|
506
|
-
const s3 = segStack.pop();
|
|
507
|
-
const s2 = segStack.pop();
|
|
508
|
-
const s1 = segStack.pop();
|
|
509
|
-
if (s1 !== undefined && s2 !== undefined && s3 !== undefined) {
|
|
510
|
-
const segs = segLib.makeCorner(s1, s2, s3);
|
|
511
|
-
segStack.push(...segs);
|
|
512
|
-
} else {
|
|
513
|
-
throw `err603: contour generateContour internal error`;
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
if (segLib.isCorner(seg.sType)) {
|
|
518
|
-
if (coType === 2) {
|
|
519
|
-
throw `err419: generateContour with two consecutive corners ${seg.sType}`;
|
|
520
|
-
}
|
|
521
|
-
if (coType === 0 && segLib.isActiveCorner(seg.sType) && seg.radius > 0) {
|
|
522
|
-
const p0 = point(0, 0);
|
|
523
|
-
segStackEnd.push(
|
|
524
|
-
new segLib.Segment2(seg.sType, p0, p0, p0, seg.radius, 0, 0, false)
|
|
525
|
-
);
|
|
526
|
-
}
|
|
527
|
-
if (coType === 1 && segLib.isActiveCorner(seg.sType) && seg.radius > 0) {
|
|
528
|
-
const p0 = point(0, 0);
|
|
529
|
-
segStack.push(
|
|
530
|
-
new segLib.Segment2(seg.sType, p0, p0, p0, seg.radius, 0, 0, false)
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
coType = 2;
|
|
534
|
-
}
|
|
535
|
-
if (segLib.isAddPoint(seg.sType)) {
|
|
536
|
-
px1 = seg.px;
|
|
537
|
-
py1 = seg.py;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
if (segStackEnd.length > 0) {
|
|
541
|
-
if (coType === 1) {
|
|
542
|
-
segStack.push(...segStackEnd);
|
|
543
|
-
} else {
|
|
544
|
-
throw `err397: contour generateContour Corners defined at end and begining`;
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
const segz1 = segStack.at(-1);
|
|
548
|
-
if (segz1 !== undefined) {
|
|
549
|
-
if (segLib.isCorner(segz1.sType)) {
|
|
550
|
-
const s3 = segStack[0];
|
|
551
|
-
const s2 = segStack.pop();
|
|
552
|
-
const s1 = segStack.pop();
|
|
553
|
-
if (s1 !== undefined && s2 !== undefined && s3 !== undefined) {
|
|
554
|
-
const segs = segLib.makeCorner(s1, s2, s3);
|
|
555
|
-
segStack.push(...segs.slice(0, -1));
|
|
556
|
-
const s4 = segs.at(-1);
|
|
557
|
-
if (s4 !== undefined) {
|
|
558
|
-
segStack[0] = s4;
|
|
559
|
-
} else {
|
|
560
|
-
throw `err606: contour generateContour internal error`;
|
|
561
|
-
}
|
|
562
|
-
} else {
|
|
563
|
-
throw `err602: contour generateContour internal error`;
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
const seg0 = segStack[0];
|
|
568
|
-
const rContour = new Contour(seg0.p1.cx, seg0.p1.cy, this.imposedColor);
|
|
569
|
-
rContour.debugPoints.push(...segLib.gSegDbg.getPoints());
|
|
570
|
-
rContour.debugLines.push(...segLib.gSegDbg.getLines());
|
|
571
|
-
//console.log(`dbg290: ${segLib.gSegDbg.debugPoints.length}`);
|
|
572
|
-
for (const seg2 of segStack) {
|
|
573
|
-
if (seg2.sType === segLib.SegEnum.eStroke) {
|
|
574
|
-
rContour.addSegStrokeA(seg2.p2.cx, seg2.p2.cy);
|
|
575
|
-
} else if (seg2.sType === segLib.SegEnum.eArc) {
|
|
576
|
-
const seg1 = segLib.arcSeg2To1(seg2);
|
|
577
|
-
rContour
|
|
578
|
-
.addPointA(seg2.p2.cx, seg2.p2.cy)
|
|
579
|
-
.addSegArc(seg1.radius, seg1.arcLarge, seg1.arcCcw);
|
|
580
|
-
} else {
|
|
581
|
-
throw `err986: contour generateContour unexpected in seg2 Enum ${seg2.sType}`;
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
return rContour;
|
|
585
|
-
}
|
|
586
|
-
generatePoints(): Point[] {
|
|
587
|
-
const rPoints = [];
|
|
588
|
-
rPoints.push(...this.debugPoints);
|
|
589
|
-
const seg0 = this.segments[0];
|
|
590
|
-
rPoints.push(point(seg0.px, seg0.py));
|
|
591
|
-
let px1 = 0;
|
|
592
|
-
let py1 = 0;
|
|
593
|
-
for (const seg of this.segments) {
|
|
594
|
-
if (seg.sType === segLib.SegEnum.eArc) {
|
|
595
|
-
try {
|
|
596
|
-
const seg2 = segLib.arcSeg1To2(px1, py1, seg);
|
|
597
|
-
const p3 = point(seg2.pc.cx, seg2.pc.cy);
|
|
598
|
-
const a12h = withinPiPi((seg2.a2 - seg2.a1) / 2);
|
|
599
|
-
let a3 = seg2.a1 + a12h;
|
|
600
|
-
if (
|
|
601
|
-
(Math.sign(a12h) > 0 && !seg.arcCcw) ||
|
|
602
|
-
(Math.sign(a12h) < 0 && seg.arcCcw)
|
|
603
|
-
) {
|
|
604
|
-
a3 += Math.PI;
|
|
605
|
-
}
|
|
606
|
-
const p4 = p3.translatePolar(a3, seg.radius);
|
|
607
|
-
rPoints.push(p4);
|
|
608
|
-
} catch (emsg) {
|
|
609
|
-
console.log('err453: ' + (emsg as string));
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
if (segLib.isAddPoint(seg.sType)) {
|
|
613
|
-
px1 = seg.px;
|
|
614
|
-
py1 = seg.py;
|
|
615
|
-
rPoints.push(point(px1, py1));
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
return rPoints;
|
|
619
|
-
}
|
|
620
|
-
generateLines(): Line[] {
|
|
621
|
-
const rLines = [];
|
|
622
|
-
rLines.push(...this.debugLines);
|
|
623
|
-
return rLines;
|
|
624
|
-
}
|
|
625
|
-
checkContour(ctr: Contour) {
|
|
626
|
-
if (ctr.segments[0].sType !== segLib.SegEnum.eStart) {
|
|
627
|
-
throw `err412: contour check first seg is not eStart ${ctr.segments[0].sType}`;
|
|
628
|
-
}
|
|
629
|
-
let px1 = 0;
|
|
630
|
-
let py1 = 0;
|
|
631
|
-
for (const seg of ctr.segments) {
|
|
632
|
-
if (seg.sType === segLib.SegEnum.eArc) {
|
|
633
|
-
try {
|
|
634
|
-
segLib.arcSeg1To2(px1, py1, seg);
|
|
635
|
-
} catch (emsg) {
|
|
636
|
-
throw `err778: ${emsg as string}`;
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
if (segLib.isAddPoint(seg.sType)) {
|
|
640
|
-
px1 = seg.px;
|
|
641
|
-
py1 = seg.py;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
const px0 = ctr.segments[0].px;
|
|
645
|
-
const py0 = ctr.segments[0].py;
|
|
646
|
-
if (roundZero(px1 - px0) !== 0 || roundZero(py1 - py0) !== 0) {
|
|
647
|
-
throw `err414: contour check, contour is not closed px ${px0} ${px1} py ${px0} ${py0}`;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
check(): string {
|
|
651
|
-
segLib.gSegDbg.clearMsg();
|
|
652
|
-
this.checkContour(this);
|
|
653
|
-
const ctrG = this.generateContour();
|
|
654
|
-
this.checkContour(ctrG);
|
|
655
|
-
return segLib.gSegDbg.getMsg();
|
|
656
|
-
}
|
|
657
|
-
toSvg(yCeiling: number, color = ''): string {
|
|
658
|
-
const sPath = svgPath();
|
|
659
|
-
for (const seg of this.segments) {
|
|
660
|
-
if (seg.sType === segLib.SegEnum.eStart) {
|
|
661
|
-
sPath.addStart(seg.px, yCeiling - seg.py);
|
|
662
|
-
} else if (seg.sType === segLib.SegEnum.eStroke) {
|
|
663
|
-
sPath.addStroke(seg.px, yCeiling - seg.py);
|
|
664
|
-
} else if (seg.sType === segLib.SegEnum.eArc) {
|
|
665
|
-
sPath.addArc(seg.px, yCeiling - seg.py, seg.radius, seg.arcLarge, !seg.arcCcw);
|
|
666
|
-
} else {
|
|
667
|
-
console.log(`err631: contour.toSvg has unknown segment type ${seg.sType}`);
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
const rSvg = sPath.stringify(color);
|
|
671
|
-
return rSvg;
|
|
672
|
-
}
|
|
673
|
-
toDxfSeg(): DxfSeg[] {
|
|
674
|
-
const rDxfSeg: DxfSeg[] = [];
|
|
675
|
-
let px1 = 0;
|
|
676
|
-
let py1 = 0;
|
|
677
|
-
for (const seg of this.segments) {
|
|
678
|
-
if (seg.sType === segLib.SegEnum.eStroke) {
|
|
679
|
-
rDxfSeg.push(dxfSegLine(px1, py1, seg.px, seg.py));
|
|
680
|
-
} else if (seg.sType === segLib.SegEnum.eArc) {
|
|
681
|
-
try {
|
|
682
|
-
const seg2 = segLib.arcSeg1To2(px1, py1, seg);
|
|
683
|
-
rDxfSeg.push(
|
|
684
|
-
dxfSegArc(seg2.pc.cx, seg2.pc.cy, seg.radius, seg2.a1, seg2.a2, seg2.arcCcw)
|
|
685
|
-
);
|
|
686
|
-
} catch (emsg) {
|
|
687
|
-
console.log('err413: ' + (emsg as string));
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
if (segLib.isAddPoint(seg.sType)) {
|
|
691
|
-
px1 = seg.px;
|
|
692
|
-
py1 = seg.py;
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
return rDxfSeg;
|
|
696
|
-
}
|
|
697
|
-
toPax(): tPaxContourPath {
|
|
698
|
-
const pPath = paxPath();
|
|
699
|
-
for (const seg of this.segments) {
|
|
700
|
-
if (seg.sType === segLib.SegEnum.eStart) {
|
|
701
|
-
pPath.addStart(seg.px, seg.py);
|
|
702
|
-
} else if (seg.sType === segLib.SegEnum.eStroke) {
|
|
703
|
-
pPath.addStroke(seg.px, seg.py);
|
|
704
|
-
} else if (seg.sType === segLib.SegEnum.eArc) {
|
|
705
|
-
pPath.addArc(seg.px, seg.py, seg.radius, seg.arcLarge, seg.arcCcw);
|
|
706
|
-
} else {
|
|
707
|
-
console.log(`err709: contour.toPax has unknown segment type ${seg.sType}`);
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
const rPaxC = pPath.toJson();
|
|
711
|
-
return rPaxC;
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
/* ContourCircle class */
|
|
716
|
-
|
|
717
|
-
class ContourCircle extends AContour {
|
|
718
|
-
circle = true;
|
|
719
|
-
px: number;
|
|
720
|
-
py: number;
|
|
721
|
-
radius: number;
|
|
722
|
-
imposedColor: string;
|
|
723
|
-
constructor(ix: number, iy: number, iRadius: number, icolor = '') {
|
|
724
|
-
super();
|
|
725
|
-
this.px = ix;
|
|
726
|
-
this.py = iy;
|
|
727
|
-
this.radius = iRadius;
|
|
728
|
-
this.imposedColor = icolor;
|
|
729
|
-
}
|
|
730
|
-
clone(): ContourCircle {
|
|
731
|
-
const rctr = new ContourCircle(this.px, this.py, this.radius, this.imposedColor);
|
|
732
|
-
return rctr;
|
|
733
|
-
}
|
|
734
|
-
translate(ix: number, iy: number): ContourCircle {
|
|
735
|
-
const rctr = new ContourCircle(this.px + ix, this.py + iy, this.radius, this.imposedColor);
|
|
736
|
-
return rctr;
|
|
737
|
-
}
|
|
738
|
-
translatePolar(ia: number, il: number): ContourCircle {
|
|
739
|
-
return this.translate(il * Math.cos(ia), il * Math.sin(ia));
|
|
740
|
-
}
|
|
741
|
-
rotate(ix: number, iy: number, ia: number): ContourCircle {
|
|
742
|
-
const ic = point(ix, iy);
|
|
743
|
-
const nCenter = point(this.px, this.py).rotate(ic, ia);
|
|
744
|
-
const rctr = new ContourCircle(nCenter.cx, nCenter.cy, this.radius, this.imposedColor);
|
|
745
|
-
return rctr;
|
|
746
|
-
}
|
|
747
|
-
draw(ctx: CanvasRenderingContext2D, cAdjust: tCanvasAdjust, color: string = colors.contour) {
|
|
748
|
-
const [cx3, cy3] = point2canvas(this.px, this.py, cAdjust);
|
|
749
|
-
const cRadius = radius2canvas(this.radius, cAdjust);
|
|
750
|
-
const theColor = this.imposedColor === '' ? color : this.imposedColor;
|
|
751
|
-
ctx.beginPath();
|
|
752
|
-
ctx.arc(cx3, cy3, cRadius, 0, 2 * Math.PI, true);
|
|
753
|
-
ctx.strokeStyle = theColor;
|
|
754
|
-
ctx.stroke();
|
|
755
|
-
}
|
|
756
|
-
extractSkeleton(): ContourCircle {
|
|
757
|
-
const rContour = new ContourCircle(this.px, this.py, this.radius);
|
|
758
|
-
return rContour;
|
|
759
|
-
}
|
|
760
|
-
generateContour(): ContourCircle {
|
|
761
|
-
const rContour = new ContourCircle(this.px, this.py, this.radius, this.imposedColor);
|
|
762
|
-
return rContour;
|
|
763
|
-
}
|
|
764
|
-
generatePoints(): Point[] {
|
|
765
|
-
const rPoints = [];
|
|
766
|
-
const p1 = point(this.px, this.py);
|
|
767
|
-
rPoints.push(p1);
|
|
768
|
-
for (let i = 0; i < 4; i++) {
|
|
769
|
-
const p2 = p1.translatePolar((i * Math.PI) / 2, this.radius);
|
|
770
|
-
rPoints.push(p2);
|
|
771
|
-
}
|
|
772
|
-
return rPoints;
|
|
773
|
-
}
|
|
774
|
-
generateLines(): Line[] {
|
|
775
|
-
return [];
|
|
776
|
-
}
|
|
777
|
-
check(): string {
|
|
778
|
-
return '';
|
|
779
|
-
}
|
|
780
|
-
toSvg(yCeiling: number, color = ''): string {
|
|
781
|
-
const rSvg = svgCircleString(this.px, yCeiling - this.py, this.radius, color);
|
|
782
|
-
return rSvg;
|
|
783
|
-
}
|
|
784
|
-
toDxfSeg(): DxfSeg[] {
|
|
785
|
-
const rDxfSeg: DxfSeg[] = [];
|
|
786
|
-
rDxfSeg.push(dxfSegCircle(this.px, this.py, this.radius));
|
|
787
|
-
return rDxfSeg;
|
|
788
|
-
}
|
|
789
|
-
toPax(): tPaxContourCircle {
|
|
790
|
-
const rPaxC = paxCircle(this.px, this.py, this.radius);
|
|
791
|
-
return rPaxC;
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
// instantiation functions
|
|
796
|
-
function contour(ix: number, iy: number, icolor = ''): Contour {
|
|
797
|
-
return new Contour(ix, iy, icolor);
|
|
798
|
-
}
|
|
799
|
-
function contourCircle(ix: number, iy: number, iRadius: number, icolor = ''): ContourCircle {
|
|
800
|
-
return new ContourCircle(ix, iy, iRadius, icolor);
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
type tContour = Contour | ContourCircle;
|
|
804
|
-
|
|
805
|
-
export type { tContour };
|
|
806
|
-
export { Contour, ContourCircle, contour, contourCircle };
|