@design-core/core 0.0.1 → 0.0.3
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/.eslintrc.json +14 -7
- package/.github/workflows/DesignCoreQA.yml +3 -1
- package/README.md +11 -4
- package/TODO.md +19 -0
- package/core/core/core.js +49 -42
- package/core/designCore.js +61 -2
- package/core/dimensions/alignedDimension.js +142 -0
- package/core/dimensions/angularDimension.js +550 -0
- package/core/dimensions/baseCircularDimension.js +244 -0
- package/core/dimensions/baseDimension.js +558 -0
- package/core/dimensions/baseLinearDimension.js +371 -0
- package/core/dimensions/diametricDimension.js +82 -0
- package/core/dimensions/dimension.js +298 -0
- package/core/dimensions/linearDimension.js +29 -0
- package/core/dimensions/radialDimension.js +78 -0
- package/core/dimensions/rotatedDimension.js +167 -0
- package/core/entities/arc.js +314 -60
- package/core/entities/arctext.js +642 -0
- package/core/entities/basePolyline.js +553 -94
- package/core/entities/circle.js +181 -54
- package/core/entities/entity.js +154 -74
- package/core/entities/hatch.js +807 -0
- package/core/entities/insert.js +200 -39
- package/core/entities/line.js +196 -134
- package/core/entities/lwpolyline.js +21 -44
- package/core/entities/point.js +194 -29
- package/core/entities/polyline.js +54 -7
- package/core/entities/rectangle.js +43 -13
- package/core/entities/solid.js +43 -6
- package/core/entities/text.js +324 -181
- package/core/lib/boundingBox.js +73 -13
- package/core/lib/canvas.js +256 -65
- package/core/lib/clipboard.js +198 -0
- package/core/lib/colour.js +144 -0
- package/core/lib/colours.js +367 -301
- package/core/lib/commandLine.js +16 -28
- package/core/lib/commandManager.js +115 -58
- package/core/lib/constants.js +23 -0
- package/core/lib/dxf/dxf.js +249 -34
- package/core/lib/dxf/dxfFile.js +23 -38
- package/core/lib/dxf/dxfIterator.js +17 -5
- package/core/lib/dxf/dxfRead.js +23 -7
- package/core/lib/dxf/dxfWrite.js +39 -129
- package/core/lib/dxf/handleManager.js +97 -0
- package/core/lib/dxf/sections/blocks.js +16 -2
- package/core/lib/dxf/sections/entities.js +17 -3
- package/core/lib/dxf/sections/header.js +10 -1
- package/core/lib/dxf/sections/objects.js +36 -0
- package/core/lib/dxf/sections/section.js +43 -5
- package/core/lib/dxf/sections/tables.js +17 -3
- package/core/lib/entityManager.js +178 -0
- package/core/lib/fileio.js +14 -4
- package/core/lib/headers.js +229 -0
- package/core/lib/input.js +46 -0
- package/core/lib/inputManager.js +199 -194
- package/core/lib/intersect.js +341 -468
- package/core/lib/logging.js +25 -1
- package/core/lib/matrix.js +6 -8
- package/core/lib/mouse.js +24 -79
- package/core/lib/patterns.js +690 -0
- package/core/lib/promptOptions.js +133 -0
- package/core/lib/scene.js +71 -174
- package/core/lib/selectionManager.js +74 -48
- package/core/lib/selectionWindow.js +24 -10
- package/core/lib/settings.js +18 -11
- package/core/lib/snapping.js +129 -21
- package/core/lib/stateManager.js +288 -0
- package/core/lib/strings.js +57 -5
- package/core/lib/utils.js +95 -11
- package/core/objects/dictionary.js +43 -0
- package/core/objects/dictionaryManager.js +80 -0
- package/core/properties/dimType.js +117 -0
- package/core/properties/flags.js +66 -0
- package/core/properties/property.js +26 -0
- package/core/properties/propertyManager.js +65 -19
- package/core/tables/appId.js +31 -0
- package/core/tables/appIdManager.js +44 -0
- package/core/tables/block.js +323 -0
- package/core/tables/blockManager.js +48 -0
- package/core/tables/blockRecord.js +29 -0
- package/core/tables/blockRecordManager.js +37 -0
- package/core/tables/dimStyle.js +627 -0
- package/core/tables/dimStyleManager.js +187 -0
- package/core/tables/endblk.js +28 -0
- package/core/tables/layer.js +219 -0
- package/core/tables/layerManager.js +47 -0
- package/core/tables/ltype.js +85 -0
- package/core/tables/ltypeManager.js +65 -0
- package/core/tables/style.js +145 -0
- package/core/tables/styleManager.js +55 -0
- package/core/tables/styleManagerBase.js +110 -0
- package/core/tables/tableManagerBase.js +354 -0
- package/core/tables/ucs.js +28 -0
- package/core/tables/ucsManager.js +44 -0
- package/core/tables/view.js +28 -0
- package/core/tables/viewManager.js +44 -0
- package/core/tables/vport.js +70 -0
- package/core/tables/vportManager.js +65 -0
- package/core/tools/chamfer.js +343 -0
- package/core/tools/chamferFilletBase.js +162 -0
- package/core/tools/copy.js +68 -40
- package/core/tools/copybase.js +65 -0
- package/core/tools/copyclip.js +59 -0
- package/core/tools/cornerEntity.js +138 -0
- package/core/tools/cutclip.js +72 -0
- package/core/tools/distance.js +37 -9
- package/core/tools/erase.js +43 -13
- package/core/tools/explode.js +117 -0
- package/core/tools/extend.js +71 -32
- package/core/tools/fillet.js +336 -0
- package/core/tools/identify.js +33 -6
- package/core/tools/matchProp.js +106 -0
- package/core/tools/mirror.js +141 -0
- package/core/tools/move.js +65 -32
- package/core/tools/offset.js +321 -0
- package/core/tools/pan.js +54 -0
- package/core/tools/pasteclip.js +93 -0
- package/core/tools/purge.js +90 -0
- package/core/tools/rotate.js +105 -70
- package/core/tools/scale.js +166 -0
- package/core/tools/tool.js +14 -4
- package/core/tools/trim.js +71 -32
- package/core/tools/zoom.js +152 -0
- package/package.json +3 -305
- package/test/dimensions/alignedDimension.test.js +211 -0
- package/test/dimensions/angularDimension.test.js +243 -0
- package/test/dimensions/baseDimension.test.js +239 -0
- package/test/dimensions/diametricDimension.test.js +203 -0
- package/test/dimensions/dimension.test.js +102 -0
- package/test/dimensions/radialDimension.test.js +203 -0
- package/test/dimensions/rotatedDimension.test.js +224 -0
- package/test/entities/arc.test.js +463 -41
- package/test/entities/arctext.test.js +329 -0
- package/test/entities/basePolyline.test.js +459 -10
- package/test/entities/circle.test.js +312 -7
- package/test/entities/entity.test.js +28 -9
- package/test/entities/hatch.test.js +606 -0
- package/test/entities/insert.test.js +90 -0
- package/test/entities/line.test.js +182 -6
- package/test/entities/point.test.js +375 -37
- package/test/entities/solid.test.js +156 -0
- package/test/entities/text.test.js +533 -7
- package/test/integration/exportIntegration.reference.dxf +1706 -0
- package/test/integration/exportIntegration.test.js +186 -0
- package/test/integration/importExportIntegration.test.js +126 -0
- package/test/integration/intersectionIntegration.test.js +880 -0
- package/test/integration/userInputIntegration.reference.dxf +1410 -0
- package/test/integration/userInputIntegration.test.js +269 -0
- package/test/lib/boundingBox.test.js +26 -2
- package/test/lib/canvas.test.js +613 -5
- package/test/lib/clipboard.test.js +70 -0
- package/test/lib/colour.test.js +114 -0
- package/test/lib/colours.test.js +63 -18
- package/test/lib/commandLine.test.js +159 -22
- package/test/lib/commandManager.test.js +4 -4
- package/test/lib/constants.test.js +9 -0
- package/test/lib/dxf/dxfFile.test.js +6 -2
- package/test/lib/dxf/dxfIterator.test.js +1 -1
- package/test/lib/dxf/dxfWrite.test.js +173 -0
- package/test/lib/dxf/handleManager.test.js +137 -0
- package/test/lib/dxf/sections/blocks.test.js +5 -5
- package/test/lib/dxf/sections/entities.test.js +4 -4
- package/test/lib/dxf/sections/header.test.js +18 -4
- package/test/lib/dxf/sections/objects.test.js +132 -0
- package/test/lib/dxf/sections/section.test.js +29 -29
- package/test/lib/dxf/sections/tables.test.js +3 -3
- package/test/lib/entityManager.test.js +163 -0
- package/test/lib/headers.test.js +233 -0
- package/test/lib/inputManager.test.js +1144 -5
- package/test/lib/intersect.test.js +454 -331
- package/test/lib/logging.test.js +1 -1
- package/test/lib/matrix.test.js +1 -1
- package/test/lib/mouse.test.js +327 -4
- package/test/lib/patterns.test.js +105 -0
- package/test/lib/promptOptions.test.js +179 -0
- package/test/lib/scene.test.js +16 -52
- package/test/lib/selectionManager.test.js +17 -5
- package/test/lib/settings.test.js +111 -5
- package/test/lib/snapping.test.js +142 -4
- package/test/lib/stateManager.test.js +155 -0
- package/test/lib/utils.test.js +81 -1
- package/test/objects/dictionary.test.js +81 -0
- package/test/objects/dictionaryManager.test.js +34 -0
- package/test/properties/dimType.test.js +62 -0
- package/test/properties/flags.test.js +164 -0
- package/test/properties/property.test.js +13 -0
- package/test/properties/propertyManager.test.js +10 -11
- package/test/tables/appId.test.js +46 -0
- package/test/tables/appIdManager.test.js +72 -0
- package/test/tables/block.test.js +157 -0
- package/test/tables/blockManager.test.js +52 -0
- package/test/tables/blockRecord.test.js +39 -0
- package/test/tables/blockRecordManager.test.js +60 -0
- package/test/tables/dimstyle.test.js +72 -0
- package/test/tables/endblk.test.js +30 -0
- package/test/tables/layer.test.js +95 -0
- package/test/tables/layerManager.test.js +172 -0
- package/test/{styles → tables}/ltype.test.js +7 -7
- package/test/{styles → tables}/ltypeManager.test.js +2 -2
- package/test/tables/style.test.js +44 -0
- package/test/tables/stylemanagerbase.test.js +220 -0
- package/test/tables/tableManagerBase.test.js +194 -0
- package/test/tables/ucs.test.js +37 -0
- package/test/tables/ucsManager.test.js +48 -0
- package/test/tables/view.test.js +37 -0
- package/test/tables/viewManager.test.js +48 -0
- package/test/tables/vport.test.js +117 -0
- package/test/tables/vportManager.test.js +54 -0
- package/test/test-helpers/test-helpers.js +66 -0
- package/test/tools/chamfer.test.js +970 -0
- package/test/tools/chamferFilletBase.test.js +446 -0
- package/test/tools/copy.test.js +22 -14
- package/test/tools/copybase.test.js +93 -0
- package/test/tools/copyclip.test.js +92 -0
- package/test/tools/cornerEntity.test.js +201 -0
- package/test/tools/cutclip.test.js +94 -0
- package/test/tools/distance.test.js +140 -18
- package/test/tools/erase.test.js +12 -12
- package/test/tools/explode.test.js +45 -0
- package/test/tools/extend.test.js +326 -44
- package/test/tools/fillet.test.js +831 -0
- package/test/tools/identify.test.js +115 -16
- package/test/tools/matchProp.test.js +84 -0
- package/test/tools/mirror.test.js +475 -0
- package/test/tools/move.test.js +75 -19
- package/test/tools/offset.test.js +748 -0
- package/test/tools/pan.test.js +72 -0
- package/test/tools/pasteclip.test.js +100 -0
- package/test/tools/purge.test.js +89 -0
- package/test/tools/rotate.test.js +89 -23
- package/test/tools/scale.test.js +529 -0
- package/test/tools/trim.test.js +419 -84
- package/test/tools/zoom.test.js +504 -0
- package/core/entities/alignedDimension.js +0 -279
- package/core/entities/angularDimension.js +0 -194
- package/core/entities/baseDimension.js +0 -227
- package/core/entities/block.js +0 -247
- package/core/entities/diametricDimension.js +0 -133
- package/core/entities/dimension.js +0 -202
- package/core/entities/radialDimension.js +0 -126
- package/core/styles/dimStyle.js +0 -719
- package/core/styles/dimStyleManager.js +0 -47
- package/core/styles/layer.js +0 -133
- package/core/styles/layerManager.js +0 -40
- package/core/styles/ltype.js +0 -86
- package/core/styles/ltypeManager.js +0 -50
- package/core/styles/style.js +0 -158
- package/core/styles/styleManager.js +0 -43
- package/core/styles/styleManagerBase.js +0 -299
- package/test/entities/block.test.js +0 -22
- package/test/styles/dimstyle.test.js +0 -19
- package/test/styles/layerManager.test.js +0 -150
- package/test/styles/style.test.js +0 -33
- package/test/styles/stylemanagerbase.test.js +0 -219
package/core/entities/point.js
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
|
+
import { Utils } from '../lib/utils.js';
|
|
2
|
+
import { Constants } from '../lib/constants.js';
|
|
3
|
+
|
|
4
|
+
/** Point Entity Class */
|
|
1
5
|
export class Point {
|
|
2
6
|
/**
|
|
3
|
-
*
|
|
7
|
+
* Create a Point
|
|
8
|
+
* @param {number} x
|
|
4
9
|
* @param {number} y
|
|
10
|
+
* @param {number} bulge
|
|
11
|
+
* @param {number} sequence - dxf group code sequence reference
|
|
5
12
|
*/
|
|
6
|
-
constructor(x, y) {
|
|
13
|
+
constructor(x, y, bulge = 0, sequence) {
|
|
7
14
|
this.type = this.constructor.name;
|
|
8
15
|
this.x = 0;
|
|
9
16
|
this.y = 0;
|
|
10
17
|
// sequence holds a reference to the dxf group code sequence the point represents
|
|
11
18
|
// 10, 20, 30;
|
|
12
19
|
// 11, 21, 31;
|
|
13
|
-
this.sequence;
|
|
20
|
+
this.sequence = sequence;
|
|
14
21
|
|
|
15
22
|
// bulge value used for defining arcs in polylines
|
|
16
23
|
// arc is ccw if positive
|
|
17
|
-
this.bulge =
|
|
24
|
+
this.bulge = bulge;
|
|
18
25
|
|
|
19
26
|
if (x !== undefined) {
|
|
20
27
|
this.x = x;
|
|
@@ -25,39 +32,44 @@ export class Point {
|
|
|
25
32
|
/**
|
|
26
33
|
* Add this to that
|
|
27
34
|
* @param {Point} that
|
|
35
|
+
* @return {Point}
|
|
28
36
|
*/
|
|
29
37
|
add(that) {
|
|
30
|
-
return new Point(this.x + that.x, this.y + that.y);
|
|
38
|
+
return new Point(this.x + that.x, this.y + that.y, this.bulge, this.sequence);
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
/**
|
|
34
42
|
* subtract that from this
|
|
35
43
|
* @param {Point} that
|
|
44
|
+
* @return {Point}
|
|
36
45
|
*/
|
|
37
46
|
subtract(that) {
|
|
38
|
-
return new Point(this.x - that.x, this.y - that.y);
|
|
47
|
+
return new Point(this.x - that.x, this.y - that.y, this.bulge, this.sequence);
|
|
39
48
|
};
|
|
40
49
|
|
|
41
50
|
/**
|
|
42
51
|
* Angle between this and that in radians
|
|
43
52
|
* @param {Point} that
|
|
53
|
+
* @return {number}
|
|
44
54
|
*/
|
|
45
55
|
angle(that) {
|
|
46
56
|
const angle = Math.atan2((this.y - that.y), (this.x - that.x)) + Math.PI;
|
|
47
|
-
return angle % (Math.PI*2);
|
|
57
|
+
return angle % (Math.PI * 2);
|
|
48
58
|
}
|
|
49
59
|
|
|
50
60
|
|
|
51
61
|
/**
|
|
52
62
|
* Returns a deep clone of a point
|
|
63
|
+
* @return {Point}
|
|
53
64
|
*/
|
|
54
65
|
clone() {
|
|
55
|
-
return new Point(this.x, this.y);
|
|
66
|
+
return new Point(this.x, this.y, this.bulge, this.sequence);
|
|
56
67
|
};
|
|
57
68
|
|
|
58
69
|
/**
|
|
59
70
|
* Returns distance between this and that
|
|
60
71
|
* @param {Point} that
|
|
72
|
+
* @return {number}
|
|
61
73
|
*/
|
|
62
74
|
distance(that) {
|
|
63
75
|
return Math.sqrt((this.x - that.x) * (this.x - that.x) + (this.y - that.y) * (this.y - that.y));
|
|
@@ -66,26 +78,100 @@ export class Point {
|
|
|
66
78
|
|
|
67
79
|
/**
|
|
68
80
|
* Return dot product of this and that
|
|
81
|
+
* Measures how much two vectors point in the same direction.
|
|
82
|
+
* Equal to |this| * |that| * cos(angle between them).
|
|
83
|
+
* Positive: vectors point in the same direction (angle < 90°)
|
|
84
|
+
* Zero: vectors are perpendicular (angle = 90°)
|
|
85
|
+
* Negative: vectors point in opposite directions (angle > 90°)
|
|
69
86
|
* @param {Point} that
|
|
87
|
+
* @return {number}
|
|
70
88
|
*/
|
|
71
89
|
dot(that) {
|
|
72
90
|
return this.x * that.x + this.y * that.y;
|
|
73
91
|
};
|
|
74
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Return 2D cross product of this and that
|
|
95
|
+
* Measures the signed area of the parallelogram formed by the two vectors.
|
|
96
|
+
* Equal to |this| * |that| * sin(angle from this to that).
|
|
97
|
+
* Positive: that is counter-clockwise from this
|
|
98
|
+
* Zero: vectors are parallel (or one is zero length)
|
|
99
|
+
* Negative: that is clockwise from this
|
|
100
|
+
* @param {Point} that
|
|
101
|
+
* @return {number}
|
|
102
|
+
*/
|
|
103
|
+
cross(that) {
|
|
104
|
+
return this.x * that.y - this.y * that.x;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Return new point mirrored across the line defined by pt1 and pt2
|
|
109
|
+
* @param {Point} pt1 - first point on the mirror line
|
|
110
|
+
* @param {Point} pt2 - second point on the mirror line
|
|
111
|
+
* @return {Point}
|
|
112
|
+
*/
|
|
113
|
+
mirror(pt1, pt2) {
|
|
114
|
+
if (pt1.isSame(pt2)) return this.clone();
|
|
115
|
+
const perp = this.perpendicular(pt1, pt2);
|
|
116
|
+
return new Point(2 * perp.x - this.x, 2 * perp.y - this.y, -this.bulge, this.sequence);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Return new point scaled from base by a scalar factor
|
|
121
|
+
* @param {Point} base
|
|
122
|
+
* @param {number} factor
|
|
123
|
+
* @return {Point}
|
|
124
|
+
*/
|
|
125
|
+
scaleFrom(base, factor) {
|
|
126
|
+
const x = base.x + (this.x - base.x) * factor;
|
|
127
|
+
const y = base.y + (this.y - base.y) * factor;
|
|
128
|
+
return new Point(x, y, this.bulge, this.sequence);
|
|
129
|
+
}
|
|
130
|
+
|
|
75
131
|
/**
|
|
76
132
|
* Return new point rotated about centre by angle in radians
|
|
77
133
|
* @param {Point} centre
|
|
78
|
-
* @param {
|
|
134
|
+
* @param {number} angle - in radians
|
|
135
|
+
* @return {Point}
|
|
79
136
|
*/
|
|
80
137
|
rotate(centre, angle) {
|
|
81
138
|
const x = centre.x + (this.x - centre.x) * Math.cos(angle) - (this.y - centre.y) * Math.sin(angle);
|
|
82
139
|
const y = centre.y + (this.x - centre.x) * Math.sin(angle) + (this.y - centre.y) * Math.cos(angle);
|
|
83
|
-
return new Point(x, y);
|
|
140
|
+
return new Point(x, y, this.bulge, this.sequence);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Return the length (magnitude) of this vector.
|
|
145
|
+
* @return {number}
|
|
146
|
+
*/
|
|
147
|
+
length() {
|
|
148
|
+
return Math.sqrt(this.x ** 2 + this.y ** 2);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Return a new unit vector in the same direction as this.
|
|
153
|
+
* (Divides each component by the vector's magnitude.)
|
|
154
|
+
* @return {Point}
|
|
155
|
+
*/
|
|
156
|
+
normalise() {
|
|
157
|
+
const len = this.length();
|
|
158
|
+
if (len < Constants.Tolerance.EPSILON) return new Point(0, 0);
|
|
159
|
+
return new Point(this.x / len, this.y / len);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Return a new point scaled by a scalar factor.
|
|
164
|
+
* @param {number} scalar
|
|
165
|
+
* @return {Point}
|
|
166
|
+
*/
|
|
167
|
+
scale(scalar) {
|
|
168
|
+
return new Point(this.x * scalar, this.y * scalar);
|
|
84
169
|
}
|
|
85
170
|
|
|
86
171
|
/**
|
|
87
172
|
* Return new point with minimum values for x and y from this and that
|
|
88
173
|
* @param {Point} that
|
|
174
|
+
* @return {Point}
|
|
89
175
|
*/
|
|
90
176
|
min(that) {
|
|
91
177
|
return new Point(
|
|
@@ -97,6 +183,7 @@ export class Point {
|
|
|
97
183
|
/**
|
|
98
184
|
* Return new point with maximum values for x and y from this and that
|
|
99
185
|
* @param {Point} that
|
|
186
|
+
* @return {Point}
|
|
100
187
|
*/
|
|
101
188
|
max(that) {
|
|
102
189
|
return new Point(
|
|
@@ -108,6 +195,7 @@ export class Point {
|
|
|
108
195
|
/**
|
|
109
196
|
* Return midpoint between this and that
|
|
110
197
|
* @param {Point} that
|
|
198
|
+
* @return {Point}
|
|
111
199
|
*/
|
|
112
200
|
midPoint(that) {
|
|
113
201
|
// return point midway between this and that
|
|
@@ -123,7 +211,8 @@ export class Point {
|
|
|
123
211
|
* Returns linear interpolation between this and that
|
|
124
212
|
* e.g. t = 0.5 will return midpoint between this and that
|
|
125
213
|
* @param {Point} that
|
|
126
|
-
* @param {
|
|
214
|
+
* @param {number} t - ratio between 0 and 1
|
|
215
|
+
* @return {Point}
|
|
127
216
|
*/
|
|
128
217
|
lerp(that, t) {
|
|
129
218
|
return new Point(
|
|
@@ -134,8 +223,9 @@ export class Point {
|
|
|
134
223
|
|
|
135
224
|
/**
|
|
136
225
|
* Return new point projected from this along angle by distance
|
|
137
|
-
* @param {
|
|
138
|
-
* @param {
|
|
226
|
+
* @param {number} angle - in radians
|
|
227
|
+
* @param {number} distance
|
|
228
|
+
* @return {Point}
|
|
139
229
|
*/
|
|
140
230
|
project(angle, distance) {
|
|
141
231
|
if (angle === 0) {
|
|
@@ -153,7 +243,7 @@ export class Point {
|
|
|
153
243
|
* Find the closest point to this on the ray formed by Pt1 and Pt2
|
|
154
244
|
* @param {Point} Pt1
|
|
155
245
|
* @param {Point} Pt2
|
|
156
|
-
* @
|
|
246
|
+
* @return {Point} the closest point on the ray
|
|
157
247
|
*/
|
|
158
248
|
perpendicular(Pt1, Pt2) {
|
|
159
249
|
const APx = this.x - Pt1.x;
|
|
@@ -162,6 +252,7 @@ export class Point {
|
|
|
162
252
|
const ABy = Pt2.y - Pt1.y;
|
|
163
253
|
|
|
164
254
|
const magAB2 = ABx * ABx + ABy * ABy;
|
|
255
|
+
if (magAB2 === 0) return new Point(Pt1.x, Pt1.y);
|
|
165
256
|
const ABdotAP = ABx * APx + ABy * APy;
|
|
166
257
|
const t = ABdotAP / magAB2;
|
|
167
258
|
|
|
@@ -173,17 +264,18 @@ export class Point {
|
|
|
173
264
|
/**
|
|
174
265
|
* Check if this is the same as that
|
|
175
266
|
* @param {Point} that
|
|
267
|
+
* @return {boolean}
|
|
176
268
|
*/
|
|
177
269
|
isSame(that) {
|
|
178
|
-
if (this.x == that.x && this.y == that.y) return true;
|
|
270
|
+
if (Utils.round(this.x) == Utils.round(that.x) && Utils.round(this.y) == Utils.round(that.y)) return true;
|
|
179
271
|
return false;
|
|
180
272
|
}
|
|
181
273
|
|
|
182
274
|
/**
|
|
183
275
|
* Find the closest point on a line between start and end points
|
|
184
|
-
* @param {
|
|
185
|
-
* @param {
|
|
186
|
-
* @
|
|
276
|
+
* @param {Point} startPoint
|
|
277
|
+
* @param {Point} endPoint
|
|
278
|
+
* @return {Point} the closest point on the line
|
|
187
279
|
*/
|
|
188
280
|
closestPointOnLine(startPoint, endPoint) {
|
|
189
281
|
const pnt = this.perpendicular(startPoint, endPoint);
|
|
@@ -191,7 +283,13 @@ export class Point {
|
|
|
191
283
|
return pnt;
|
|
192
284
|
}
|
|
193
285
|
|
|
194
|
-
|
|
286
|
+
// point is not perpendicular to the line
|
|
287
|
+
// closest point must be at the start or end
|
|
288
|
+
if (this.distance(startPoint) < this.distance(endPoint)) {
|
|
289
|
+
return startPoint;
|
|
290
|
+
} else {
|
|
291
|
+
return endPoint;
|
|
292
|
+
}
|
|
195
293
|
}
|
|
196
294
|
|
|
197
295
|
/**
|
|
@@ -200,9 +298,9 @@ export class Point {
|
|
|
200
298
|
* @param {Point} endPoint
|
|
201
299
|
* @param {Point} centerPoint
|
|
202
300
|
* @param {number} direction - CCW if > 0
|
|
203
|
-
* @
|
|
301
|
+
* @return {Point} the closest point on the arc or null
|
|
204
302
|
*/
|
|
205
|
-
closestPointOnArc(startPoint, endPoint, centerPoint, direction=
|
|
303
|
+
closestPointOnArc(startPoint, endPoint, centerPoint, direction = 0) {
|
|
206
304
|
const length = this.distance(centerPoint);
|
|
207
305
|
const radius = centerPoint.distance(startPoint);
|
|
208
306
|
|
|
@@ -229,14 +327,16 @@ export class Point {
|
|
|
229
327
|
* @param {Point} endPoint
|
|
230
328
|
* @param {Point} centerPoint
|
|
231
329
|
* @param {number} direction - CCW if > 0
|
|
232
|
-
* @
|
|
330
|
+
* @return {Point} true or false
|
|
233
331
|
*/
|
|
234
|
-
isOnArc(startPoint, endPoint, centerPoint, direction=
|
|
332
|
+
isOnArc(startPoint, endPoint, centerPoint, direction = 0) {
|
|
333
|
+
// direction: ccw arc > 0, clockwise arc <= 0
|
|
235
334
|
const snapAngle = centerPoint.angle(this);
|
|
236
335
|
const startAngle = centerPoint.angle(startPoint);
|
|
237
336
|
const endAngle = centerPoint.angle(endPoint);
|
|
238
337
|
|
|
239
338
|
if (direction > 0) {
|
|
339
|
+
// Counter Clockwise Arc
|
|
240
340
|
if (startAngle < endAngle) {
|
|
241
341
|
if (snapAngle >= startAngle && snapAngle <= endAngle) {
|
|
242
342
|
return true;
|
|
@@ -248,7 +348,8 @@ export class Point {
|
|
|
248
348
|
return true;
|
|
249
349
|
}
|
|
250
350
|
}
|
|
251
|
-
} else if (direction
|
|
351
|
+
} else if (direction <= 0) {
|
|
352
|
+
// Clockwise Arc
|
|
252
353
|
if (startAngle < endAngle) {
|
|
253
354
|
if (snapAngle <= startAngle || snapAngle >= endAngle) {
|
|
254
355
|
return true;
|
|
@@ -270,19 +371,51 @@ export class Point {
|
|
|
270
371
|
* Determine if point is on line segment
|
|
271
372
|
* @param {Point} startPoint
|
|
272
373
|
* @param {Point} endPoint
|
|
273
|
-
* @
|
|
374
|
+
* @return {Point} true or false
|
|
274
375
|
*/
|
|
275
376
|
isOnLine(startPoint, endPoint) {
|
|
276
377
|
// check start -> point + point -> end equals start -> end
|
|
277
|
-
if (startPoint.distance(this) + this.distance(endPoint) === startPoint.distance(endPoint)) {
|
|
378
|
+
if (Utils.round(startPoint.distance(this) + this.distance(endPoint)) === Utils.round(startPoint.distance(endPoint))) {
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Check if point is inside rectangle defined by points A, B, C, D
|
|
386
|
+
* @param {Point} A - Bottom left rectangle corner
|
|
387
|
+
* @param {Point} B - Bottom right rectangle corner
|
|
388
|
+
* @param {Point} C - Top right rectangle corner
|
|
389
|
+
* @param {Point} D - Top left rectangle corner
|
|
390
|
+
* @return {boolean} - true if point is inside rectangle
|
|
391
|
+
*/
|
|
392
|
+
isInRectangle(A, B, C, D) {
|
|
393
|
+
/* Calculate area of rectangle ABCD */
|
|
394
|
+
const rectangleArea = Utils.areaOfTriangle(A, B, C) + Utils.areaOfTriangle(A, C, D);
|
|
395
|
+
|
|
396
|
+
/* Calculate area of triangle PAB */
|
|
397
|
+
const A1 = Utils.areaOfTriangle(this, A, B);
|
|
398
|
+
|
|
399
|
+
/* Calculate area of triangle PBC */
|
|
400
|
+
const A2 = Utils.areaOfTriangle(this, B, C);
|
|
401
|
+
|
|
402
|
+
/* Calculate area of triangle PCD */
|
|
403
|
+
const A3 = Utils.areaOfTriangle(this, C, D);
|
|
404
|
+
|
|
405
|
+
/* Calculate area of triangle PAD */
|
|
406
|
+
const A4 = Utils.areaOfTriangle(this, A, D);
|
|
407
|
+
|
|
408
|
+
/* Check if sum of A1, A2, A3 and A4 is same as A */
|
|
409
|
+
if (Utils.round(rectangleArea) === Utils.round(A1 + A2 + A3 + A4)) {
|
|
278
410
|
return true;
|
|
279
411
|
}
|
|
412
|
+
|
|
280
413
|
return false;
|
|
281
414
|
}
|
|
282
415
|
|
|
283
416
|
/**
|
|
284
417
|
* Get the arc angle in radians from the bulge value
|
|
285
|
-
* @
|
|
418
|
+
* @return {Point} arc angle in radians
|
|
286
419
|
*/
|
|
287
420
|
bulgeAngle() {
|
|
288
421
|
return Math.atan(this.bulge) * 4;
|
|
@@ -290,6 +423,8 @@ export class Point {
|
|
|
290
423
|
|
|
291
424
|
/**
|
|
292
425
|
* Return the radius of the arc from the next point in the polyline
|
|
426
|
+
* @param {Point} nextPoint
|
|
427
|
+
* @return {number}
|
|
293
428
|
*/
|
|
294
429
|
bulgeRadius(nextPoint) {
|
|
295
430
|
if (this.bulge == 0) {
|
|
@@ -303,7 +438,7 @@ export class Point {
|
|
|
303
438
|
/**
|
|
304
439
|
* Returns apothem; the distance from arc center to cord midpoint
|
|
305
440
|
* @param {Point} nextPoint
|
|
306
|
-
* @
|
|
441
|
+
* @return {number} apothem
|
|
307
442
|
*/
|
|
308
443
|
apothem(nextPoint) {
|
|
309
444
|
if (this.bulge == 0) {
|
|
@@ -317,7 +452,7 @@ export class Point {
|
|
|
317
452
|
/**
|
|
318
453
|
* Return the centre point of the arc
|
|
319
454
|
* @param {Point} nextPoint
|
|
320
|
-
* @
|
|
455
|
+
* @return {Point} Point
|
|
321
456
|
*/
|
|
322
457
|
bulgeCentrePoint(nextPoint) {
|
|
323
458
|
const midp = this.midPoint(nextPoint);
|
|
@@ -340,4 +475,34 @@ export class Point {
|
|
|
340
475
|
|
|
341
476
|
return centre;
|
|
342
477
|
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Calculate the bulge for a partial arc segment
|
|
481
|
+
* @param {Point} nextPoint - segment end point
|
|
482
|
+
* @param {Point} splitPoint - point where the arc is split
|
|
483
|
+
* @param {boolean} afterSplit - if true, return bulge for the portion after the split point
|
|
484
|
+
* @return {number} - the partial bulge value
|
|
485
|
+
*/
|
|
486
|
+
partialBulge(nextPoint, splitPoint, afterSplit = false) {
|
|
487
|
+
const center = this.bulgeCentrePoint(nextPoint);
|
|
488
|
+
const direction = this.bulge > 0 ? 1 : -1;
|
|
489
|
+
|
|
490
|
+
const startAngle = center.angle(this);
|
|
491
|
+
const endAngle = center.angle(nextPoint);
|
|
492
|
+
const splitAngle = center.angle(splitPoint);
|
|
493
|
+
|
|
494
|
+
let includedAngle;
|
|
495
|
+
if (afterSplit) {
|
|
496
|
+
// Angle from split point to end
|
|
497
|
+
includedAngle = (endAngle - splitAngle) * direction;
|
|
498
|
+
} else {
|
|
499
|
+
// Angle from start to split point
|
|
500
|
+
includedAngle = (splitAngle - startAngle) * direction;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Normalise to 0..2PI
|
|
504
|
+
includedAngle = ((includedAngle % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);
|
|
505
|
+
|
|
506
|
+
return Math.tan(includedAngle / 4) * direction;
|
|
507
|
+
}
|
|
343
508
|
}
|
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { DXFFile } from '../lib/dxf/dxfFile.js';
|
|
2
|
+
import { BasePolyline } from './basePolyline.js';
|
|
3
|
+
import { Point } from './point.js';
|
|
3
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Polyline Entity Class
|
|
7
|
+
* @extends BasePolyline
|
|
8
|
+
*/
|
|
4
9
|
export class Polyline extends BasePolyline {
|
|
10
|
+
/**
|
|
11
|
+
* Create a Polyline
|
|
12
|
+
* @param {Array} data
|
|
13
|
+
*/
|
|
5
14
|
constructor(data) {
|
|
6
15
|
super(data);
|
|
7
16
|
|
|
8
17
|
if (data) {
|
|
9
|
-
if (data.children) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (data.points) {
|
|
18
|
+
if (data.hasOwnProperty('children')) {
|
|
19
|
+
// remove any points
|
|
20
|
+
// point data comes from the vertices
|
|
21
|
+
if (data.hasOwnProperty('points')) {
|
|
13
22
|
this.points = [];
|
|
14
23
|
}
|
|
15
24
|
|
|
@@ -28,8 +37,46 @@ export class Polyline extends BasePolyline {
|
|
|
28
37
|
}
|
|
29
38
|
}
|
|
30
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Write the entity to file in the dxf format
|
|
42
|
+
* @param {DXFFile} file
|
|
43
|
+
*/
|
|
44
|
+
dxf(file) {
|
|
45
|
+
if (file.version < DXFFile.Version.R2000) {
|
|
46
|
+
// POLYLINE/VERTEX/SEQEND format for R12
|
|
47
|
+
file.writeGroupCode('0', 'POLYLINE');
|
|
48
|
+
file.writeGroupCode('8', this.layer);
|
|
49
|
+
file.writeGroupCode('6', this.lineType);
|
|
50
|
+
file.writeGroupCode('66', 1); // vertices-follow flag
|
|
51
|
+
file.writeGroupCode('70', this.flags.getFlagValue());
|
|
52
|
+
|
|
53
|
+
for (let i = 0; i < this.points.length; i++) {
|
|
54
|
+
file.writeGroupCode('0', 'VERTEX');
|
|
55
|
+
file.writeGroupCode('8', this.layer);
|
|
56
|
+
file.writeGroupCode('10', this.points[i].x);
|
|
57
|
+
file.writeGroupCode('20', this.points[i].y);
|
|
58
|
+
file.writeGroupCode('30', '0.0');
|
|
59
|
+
file.writeGroupCode('42', this.points[i].bulge);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
file.writeGroupCode('0', 'SEQEND');
|
|
63
|
+
file.writeGroupCode('8', this.layer);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Default to LWPOLYLINE output for R2000 and later
|
|
68
|
+
super.dxf(file);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Register the command
|
|
73
|
+
* @return {Object}
|
|
74
|
+
* command = name of the command
|
|
75
|
+
* shortcut = shortcut for the command
|
|
76
|
+
* type = type to group command in toolbars (omitted if not shown)
|
|
77
|
+
*/
|
|
31
78
|
static register() {
|
|
32
|
-
const command = {command: 'Polyline', shortcut: 'PL', type: 'Entity'};
|
|
79
|
+
const command = { command: 'Polyline', shortcut: 'PL', type: 'Entity' };
|
|
33
80
|
return command;
|
|
34
81
|
}
|
|
35
82
|
}
|
|
@@ -1,36 +1,57 @@
|
|
|
1
|
-
import {Point} from './point.js';
|
|
2
|
-
import {Strings} from '../lib/strings.js';
|
|
3
|
-
import {Entity} from './entity.js';
|
|
4
|
-
import {Input, PromptOptions} from '../lib/inputManager.js';
|
|
5
|
-
import {Logging} from '../lib/logging.js';
|
|
6
|
-
import {Polyline} from './polyline.js';
|
|
1
|
+
import { Point } from './point.js';
|
|
2
|
+
import { Strings } from '../lib/strings.js';
|
|
3
|
+
import { Entity } from './entity.js';
|
|
4
|
+
import { Input, PromptOptions } from '../lib/inputManager.js';
|
|
5
|
+
import { Logging } from '../lib/logging.js';
|
|
6
|
+
import { Polyline } from './polyline.js';
|
|
7
7
|
|
|
8
|
-
import {DesignCore} from '../designCore.js';
|
|
8
|
+
import { DesignCore } from '../designCore.js';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Rectangle Entity Class
|
|
12
|
+
* @extends Entity
|
|
13
|
+
*/
|
|
10
14
|
export class Rectangle extends Entity {
|
|
15
|
+
/**
|
|
16
|
+
* Create a Rectangle
|
|
17
|
+
* @param {Array} data
|
|
18
|
+
*/
|
|
11
19
|
constructor(data) {
|
|
12
20
|
super(data);
|
|
13
21
|
// There is no DXF representation of a Rectangle
|
|
14
22
|
// Convenience entity to create a polyline from two points
|
|
15
23
|
}
|
|
16
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Register the command
|
|
27
|
+
* @return {Object}
|
|
28
|
+
* command = name of the command
|
|
29
|
+
* shortcut = shortcut for the command
|
|
30
|
+
* type = type to group command in toolbars (omitted if not shown)
|
|
31
|
+
*/
|
|
17
32
|
static register() {
|
|
18
|
-
const command = {command: 'Rectangle', shortcut: 'REC', type: 'Entity'};
|
|
33
|
+
const command = { command: 'Rectangle', shortcut: 'REC', type: 'Entity' };
|
|
19
34
|
return command;
|
|
20
35
|
}
|
|
21
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Execute method
|
|
39
|
+
* executes the workflow, requesting input required to create an entity
|
|
40
|
+
*/
|
|
22
41
|
async execute() {
|
|
23
42
|
try {
|
|
24
43
|
const op = new PromptOptions(Strings.Input.START, [Input.Type.POINT]);
|
|
25
44
|
const pt1 = await DesignCore.Scene.inputManager.requestInput(op);
|
|
45
|
+
if (pt1 === undefined) return;
|
|
26
46
|
this.points.push(pt1);
|
|
27
47
|
|
|
28
48
|
const op2 = new PromptOptions(Strings.Input.END, [Input.Type.POINT]);
|
|
29
49
|
const pt2 = await DesignCore.Scene.inputManager.requestInput(op2);
|
|
50
|
+
if (pt2 === undefined) return;
|
|
30
51
|
this.points.push(pt2);
|
|
31
52
|
|
|
32
53
|
const points = this.rectPoints(this.points[0], this.points[1]);
|
|
33
|
-
const polyline = new Polyline({points: points});
|
|
54
|
+
const polyline = new Polyline({ points: points });
|
|
34
55
|
|
|
35
56
|
DesignCore.Scene.inputManager.executeCommand(polyline);
|
|
36
57
|
} catch (err) {
|
|
@@ -38,20 +59,29 @@ export class Rectangle extends Entity {
|
|
|
38
59
|
}
|
|
39
60
|
}
|
|
40
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Preview the entity during creation
|
|
64
|
+
*/
|
|
41
65
|
preview() {
|
|
42
66
|
if (this.points.length >= 1) {
|
|
43
67
|
const mousePoint = DesignCore.Mouse.pointOnScene();
|
|
44
68
|
const points = this.rectPoints(this.points.at(-1), mousePoint);
|
|
45
|
-
DesignCore.Scene.
|
|
69
|
+
DesignCore.Scene.tempEntities.create('Polyline', { points: points });
|
|
46
70
|
}
|
|
47
71
|
}
|
|
48
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Get the rectangle points
|
|
75
|
+
* @param {Point} pt1
|
|
76
|
+
* @param {Point} pt2
|
|
77
|
+
* @return {Array} array of points for each corner
|
|
78
|
+
*/
|
|
49
79
|
rectPoints(pt1, pt2) {
|
|
50
80
|
const points = [];
|
|
51
|
-
points.push(
|
|
81
|
+
points.push(new Point(pt1.x, pt1.y));
|
|
52
82
|
points.push(new Point(pt2.x, pt1.y));
|
|
53
|
-
points.push(
|
|
54
|
-
points.push(
|
|
83
|
+
points.push(new Point(pt2.x, pt2.y));
|
|
84
|
+
points.push(new Point(pt1.x, pt2.y));
|
|
55
85
|
points.push(new Point(pt1.x, pt1.y));
|
|
56
86
|
return points;
|
|
57
87
|
}
|
package/core/entities/solid.js
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
import {Entity} from './entity.js';
|
|
2
|
-
import {DXFFile} from '../lib/dxf/dxfFile.js';
|
|
3
|
-
import {BoundingBox} from '../lib/boundingBox.js';
|
|
1
|
+
import { Entity } from './entity.js';
|
|
2
|
+
import { DXFFile } from '../lib/dxf/dxfFile.js';
|
|
3
|
+
import { BoundingBox } from '../lib/boundingBox.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Solid Entity Class
|
|
7
|
+
* @extends Entity
|
|
8
|
+
*/
|
|
5
9
|
export class Solid extends Entity {
|
|
10
|
+
/**
|
|
11
|
+
* Create a Solid Entity
|
|
12
|
+
* @param {Array} data
|
|
13
|
+
*/
|
|
6
14
|
constructor(data) {
|
|
7
15
|
super(data);
|
|
8
16
|
}
|
|
9
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Draw the entity
|
|
20
|
+
* @param {Object} ctx - context
|
|
21
|
+
* @param {number} scale
|
|
22
|
+
*/
|
|
10
23
|
draw(ctx, scale) {
|
|
11
24
|
this.points.forEach((point, index) => {
|
|
12
25
|
if (index == 0) {
|
|
@@ -20,9 +33,13 @@ export class Solid extends Entity {
|
|
|
20
33
|
ctx.fill();
|
|
21
34
|
}
|
|
22
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Write the entity to file in the dxf format
|
|
38
|
+
* @param {DXFFile} file
|
|
39
|
+
*/
|
|
23
40
|
dxf(file) {
|
|
24
41
|
file.writeGroupCode('0', 'SOLID');
|
|
25
|
-
file.writeGroupCode('5',
|
|
42
|
+
file.writeGroupCode('5', this.handle, DXFFile.Version.R2000); // Handle
|
|
26
43
|
file.writeGroupCode('100', 'AcDbEntity', DXFFile.Version.R2000);
|
|
27
44
|
file.writeGroupCode('100', 'AcDbTrace', DXFFile.Version.R2000);
|
|
28
45
|
file.writeGroupCode('8', this.layer);
|
|
@@ -39,15 +56,35 @@ export class Solid extends Entity {
|
|
|
39
56
|
file.writeGroupCode('32', '0.0');
|
|
40
57
|
|
|
41
58
|
// If only three points are use to define the SOLID then the fourth points is the same as the third.
|
|
42
|
-
file.writeGroupCode('13', this.points[3].x
|
|
43
|
-
file.writeGroupCode('23', this.points[3].y
|
|
59
|
+
file.writeGroupCode('13', this.points.length > 3 ? this.points[3].x : this.points[2].x);
|
|
60
|
+
file.writeGroupCode('23', this.points.length > 3 ? this.points[3].y : this.points[2].x);
|
|
44
61
|
file.writeGroupCode('33', '0.0');
|
|
45
62
|
}
|
|
46
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Get closest point on entity
|
|
66
|
+
* @param {Point} P
|
|
67
|
+
* @return {Array} - [Point, distance]
|
|
68
|
+
*/
|
|
47
69
|
closestPoint(P) {
|
|
48
70
|
return [P, Infinity];
|
|
49
71
|
}
|
|
50
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Convert the entity to polyline points
|
|
75
|
+
* @return {Array} array of points representing the solid as a polyline
|
|
76
|
+
*/
|
|
77
|
+
toPolylinePoints() {
|
|
78
|
+
const points = this.points.map((point) => point.clone());
|
|
79
|
+
// Close the shape
|
|
80
|
+
points.push(this.points[0].clone());
|
|
81
|
+
return points;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Return boundingbox for entity
|
|
86
|
+
* @return {BoundingBox}
|
|
87
|
+
*/
|
|
51
88
|
boundingBox() {
|
|
52
89
|
return BoundingBox.fromPoints(this.points);
|
|
53
90
|
}
|