@bitbybit-dev/base 0.20.2 → 0.20.4
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 +1 -1
- package/lib/api/inputs/base-inputs.d.ts +8 -0
- package/lib/api/inputs/index.d.ts +3 -0
- package/lib/api/inputs/index.js +3 -0
- package/lib/api/inputs/inputs.d.ts +3 -0
- package/lib/api/inputs/inputs.js +3 -0
- package/lib/api/inputs/line-inputs.d.ts +240 -0
- package/lib/api/inputs/line-inputs.js +247 -0
- package/lib/api/inputs/mesh-inputs.d.ts +82 -0
- package/lib/api/inputs/mesh-inputs.js +83 -0
- package/lib/api/inputs/point-inputs.d.ts +153 -0
- package/lib/api/inputs/point-inputs.js +188 -0
- package/lib/api/inputs/polyline-inputs.d.ts +206 -0
- package/lib/api/inputs/polyline-inputs.js +229 -0
- package/lib/api/inputs/text-inputs.d.ts +1 -1
- package/lib/api/inputs/transforms-inputs.d.ts +18 -0
- package/lib/api/inputs/transforms-inputs.js +29 -0
- package/lib/api/inputs/vector-inputs.d.ts +8 -0
- package/lib/api/inputs/vector-inputs.js +8 -0
- package/lib/api/models/index.d.ts +1 -0
- package/lib/api/models/index.js +1 -0
- package/lib/api/models/point/bucket.d.ts +1 -0
- package/lib/api/models/point/bucket.js +1 -0
- package/lib/api/models/point/hex-grid-data.d.ts +8 -0
- package/lib/api/models/point/hex-grid-data.js +2 -0
- package/lib/api/models/point/index.d.ts +1 -0
- package/lib/api/models/point/index.js +1 -0
- package/lib/api/services/dates.js +45 -15
- package/lib/api/services/index.d.ts +3 -0
- package/lib/api/services/index.js +3 -0
- package/lib/api/services/line.d.ts +158 -0
- package/lib/api/services/line.js +334 -0
- package/lib/api/services/lists.d.ts +1 -1
- package/lib/api/services/lists.js +1 -2
- package/lib/api/services/mesh.d.ts +66 -0
- package/lib/api/services/mesh.js +235 -0
- package/lib/api/services/point.d.ts +96 -1
- package/lib/api/services/point.js +540 -1
- package/lib/api/services/polyline.d.ts +149 -0
- package/lib/api/services/polyline.js +446 -0
- package/lib/api/services/transforms.d.ts +26 -1
- package/lib/api/services/transforms.js +66 -3
- package/lib/api/services/vector.d.ts +18 -0
- package/lib/api/services/vector.js +27 -0
- package/lib/api/unit-test-helper.d.ts +20 -0
- package/lib/api/unit-test-helper.js +130 -0
- package/package.json +2 -2
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { GeometryHelper } from "./geometry-helper";
|
|
2
|
+
import * as Inputs from "../inputs";
|
|
3
|
+
import { Point } from "./point";
|
|
4
|
+
import { Vector } from "./vector";
|
|
5
|
+
/**
|
|
6
|
+
* Contains various methods for lines and segments. Line in bitbybit is a simple object that has start and end point properties.
|
|
7
|
+
* { start: [ x, y, z ], end: [ x, y, z ] }
|
|
8
|
+
*/
|
|
9
|
+
export declare class Line {
|
|
10
|
+
private readonly vector;
|
|
11
|
+
private readonly point;
|
|
12
|
+
private readonly geometryHelper;
|
|
13
|
+
constructor(vector: Vector, point: Point, geometryHelper: GeometryHelper);
|
|
14
|
+
/**
|
|
15
|
+
* Gets the start point of the line
|
|
16
|
+
* @param inputs a line
|
|
17
|
+
* @returns start point
|
|
18
|
+
* @group get
|
|
19
|
+
* @shortname line start point
|
|
20
|
+
* @drawable true
|
|
21
|
+
*/
|
|
22
|
+
getStartPoint(inputs: Inputs.Line.LineDto): Inputs.Base.Point3;
|
|
23
|
+
/**
|
|
24
|
+
* Gets the end point of the line
|
|
25
|
+
* @param inputs a line
|
|
26
|
+
* @returns end point
|
|
27
|
+
* @group get
|
|
28
|
+
* @shortname line end point
|
|
29
|
+
* @drawable true
|
|
30
|
+
*/
|
|
31
|
+
getEndPoint(inputs: Inputs.Line.LineDto): Inputs.Base.Point3;
|
|
32
|
+
/**
|
|
33
|
+
* Gets the length of the line
|
|
34
|
+
* @param inputs a line
|
|
35
|
+
* @returns line length
|
|
36
|
+
* @group get
|
|
37
|
+
* @shortname line length
|
|
38
|
+
* @drawable false
|
|
39
|
+
*/
|
|
40
|
+
length(inputs: Inputs.Line.LineDto): number;
|
|
41
|
+
/**
|
|
42
|
+
* Reverse the endpoints of the line
|
|
43
|
+
* @param inputs a line
|
|
44
|
+
* @returns reversed line
|
|
45
|
+
* @group operations
|
|
46
|
+
* @shortname reversed line
|
|
47
|
+
* @drawable true
|
|
48
|
+
*/
|
|
49
|
+
reverse(inputs: Inputs.Line.LineDto): Inputs.Base.Line3;
|
|
50
|
+
/**
|
|
51
|
+
* Transform the line
|
|
52
|
+
* @param inputs a line
|
|
53
|
+
* @returns transformed line
|
|
54
|
+
* @group transforms
|
|
55
|
+
* @shortname transform line
|
|
56
|
+
* @drawable true
|
|
57
|
+
*/
|
|
58
|
+
transformLine(inputs: Inputs.Line.TransformLineDto): Inputs.Base.Line3;
|
|
59
|
+
/**
|
|
60
|
+
* Transforms the lines with multiple transform for each line
|
|
61
|
+
* @param inputs lines
|
|
62
|
+
* @returns transformed lines
|
|
63
|
+
* @group transforms
|
|
64
|
+
* @shortname transform lines
|
|
65
|
+
* @drawable true
|
|
66
|
+
*/
|
|
67
|
+
transformsForLines(inputs: Inputs.Line.TransformsLinesDto): Inputs.Base.Line3[];
|
|
68
|
+
/**
|
|
69
|
+
* Create the line
|
|
70
|
+
* @param inputs start and end points of the line
|
|
71
|
+
* @returns line
|
|
72
|
+
* @group create
|
|
73
|
+
* @shortname line
|
|
74
|
+
* @drawable true
|
|
75
|
+
*/
|
|
76
|
+
create(inputs: Inputs.Line.LinePointsDto): Inputs.Base.Line3;
|
|
77
|
+
/**
|
|
78
|
+
* Create the segment
|
|
79
|
+
* @param inputs start and end points of the segment
|
|
80
|
+
* @returns segment
|
|
81
|
+
* @group create
|
|
82
|
+
* @shortname segment
|
|
83
|
+
* @drawable true
|
|
84
|
+
*/
|
|
85
|
+
createSegment(inputs: Inputs.Line.LinePointsDto): Inputs.Base.Segment3;
|
|
86
|
+
/**
|
|
87
|
+
* Gets the point on the line segment at a given param
|
|
88
|
+
* @param inputs line
|
|
89
|
+
* @returns point on line
|
|
90
|
+
* @group get
|
|
91
|
+
* @shortname point on line
|
|
92
|
+
* @drawable true
|
|
93
|
+
*/
|
|
94
|
+
getPointOnLine(inputs: Inputs.Line.PointOnLineDto): Inputs.Base.Point3;
|
|
95
|
+
/**
|
|
96
|
+
* Create the lines segments between all of the points in a list
|
|
97
|
+
* @param inputs points
|
|
98
|
+
* @returns lines
|
|
99
|
+
* @group create
|
|
100
|
+
* @shortname lines between points
|
|
101
|
+
* @drawable true
|
|
102
|
+
*/
|
|
103
|
+
linesBetweenPoints(inputs: Inputs.Line.PointsLinesDto): Inputs.Base.Line3[];
|
|
104
|
+
/**
|
|
105
|
+
* Create the lines between start and end points
|
|
106
|
+
* @param inputs start points and end points
|
|
107
|
+
* @returns lines
|
|
108
|
+
* @group create
|
|
109
|
+
* @shortname start and end points to lines
|
|
110
|
+
* @drawable true
|
|
111
|
+
*/
|
|
112
|
+
linesBetweenStartAndEndPoints(inputs: Inputs.Line.LineStartEndPointsDto): Inputs.Base.Line3[];
|
|
113
|
+
/**
|
|
114
|
+
* Convert the line to segment
|
|
115
|
+
* @param inputs line
|
|
116
|
+
* @returns segment
|
|
117
|
+
* @group convert
|
|
118
|
+
* @shortname line to segment
|
|
119
|
+
* @drawable false
|
|
120
|
+
*/
|
|
121
|
+
lineToSegment(inputs: Inputs.Line.LineDto): Inputs.Base.Segment3;
|
|
122
|
+
/**
|
|
123
|
+
* Converts the lines to segments
|
|
124
|
+
* @param inputs lines
|
|
125
|
+
* @returns segments
|
|
126
|
+
* @group convert
|
|
127
|
+
* @shortname lines to segments
|
|
128
|
+
* @drawable false
|
|
129
|
+
*/
|
|
130
|
+
linesToSegments(inputs: Inputs.Line.LinesDto): Inputs.Base.Segment3[];
|
|
131
|
+
/**
|
|
132
|
+
* Converts the segment to line
|
|
133
|
+
* @param inputs segment
|
|
134
|
+
* @returns line
|
|
135
|
+
* @group convert
|
|
136
|
+
* @shortname segment to line
|
|
137
|
+
* @drawable true
|
|
138
|
+
*/
|
|
139
|
+
segmentToLine(inputs: Inputs.Line.SegmentDto): Inputs.Base.Line3;
|
|
140
|
+
/**
|
|
141
|
+
* Converts the segments to lines
|
|
142
|
+
* @param inputs segments
|
|
143
|
+
* @returns lines
|
|
144
|
+
* @group convert
|
|
145
|
+
* @shortname segments to lines
|
|
146
|
+
* @drawable true
|
|
147
|
+
*/
|
|
148
|
+
segmentsToLines(inputs: Inputs.Line.SegmentsDto): Inputs.Base.Line3[];
|
|
149
|
+
/**
|
|
150
|
+
* If two lines intersect return the intersection point
|
|
151
|
+
* @param inputs line1 and line2
|
|
152
|
+
* @returns intersection point or undefined if no intersection
|
|
153
|
+
* @group intersection
|
|
154
|
+
* @shortname line-line int
|
|
155
|
+
* @drawable true
|
|
156
|
+
*/
|
|
157
|
+
lineLineIntersection(inputs: Inputs.Line.LineLineIntersectionDto): Inputs.Base.Point3 | undefined;
|
|
158
|
+
}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contains various methods for lines and segments. Line in bitbybit is a simple object that has start and end point properties.
|
|
3
|
+
* { start: [ x, y, z ], end: [ x, y, z ] }
|
|
4
|
+
*/
|
|
5
|
+
export class Line {
|
|
6
|
+
constructor(vector, point, geometryHelper) {
|
|
7
|
+
this.vector = vector;
|
|
8
|
+
this.point = point;
|
|
9
|
+
this.geometryHelper = geometryHelper;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Gets the start point of the line
|
|
13
|
+
* @param inputs a line
|
|
14
|
+
* @returns start point
|
|
15
|
+
* @group get
|
|
16
|
+
* @shortname line start point
|
|
17
|
+
* @drawable true
|
|
18
|
+
*/
|
|
19
|
+
getStartPoint(inputs) {
|
|
20
|
+
return inputs.line.start;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Gets the end point of the line
|
|
24
|
+
* @param inputs a line
|
|
25
|
+
* @returns end point
|
|
26
|
+
* @group get
|
|
27
|
+
* @shortname line end point
|
|
28
|
+
* @drawable true
|
|
29
|
+
*/
|
|
30
|
+
getEndPoint(inputs) {
|
|
31
|
+
return inputs.line.end;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Gets the length of the line
|
|
35
|
+
* @param inputs a line
|
|
36
|
+
* @returns line length
|
|
37
|
+
* @group get
|
|
38
|
+
* @shortname line length
|
|
39
|
+
* @drawable false
|
|
40
|
+
*/
|
|
41
|
+
length(inputs) {
|
|
42
|
+
return this.point.distance({ startPoint: inputs.line.start, endPoint: inputs.line.end });
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Reverse the endpoints of the line
|
|
46
|
+
* @param inputs a line
|
|
47
|
+
* @returns reversed line
|
|
48
|
+
* @group operations
|
|
49
|
+
* @shortname reversed line
|
|
50
|
+
* @drawable true
|
|
51
|
+
*/
|
|
52
|
+
reverse(inputs) {
|
|
53
|
+
return { start: inputs.line.end, end: inputs.line.start };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Transform the line
|
|
57
|
+
* @param inputs a line
|
|
58
|
+
* @returns transformed line
|
|
59
|
+
* @group transforms
|
|
60
|
+
* @shortname transform line
|
|
61
|
+
* @drawable true
|
|
62
|
+
*/
|
|
63
|
+
transformLine(inputs) {
|
|
64
|
+
const transformation = inputs.transformation;
|
|
65
|
+
let transformedControlPoints = [inputs.line.start, inputs.line.end];
|
|
66
|
+
transformedControlPoints = this.geometryHelper.transformControlPoints(transformation, transformedControlPoints);
|
|
67
|
+
return {
|
|
68
|
+
start: transformedControlPoints[0],
|
|
69
|
+
end: transformedControlPoints[1]
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Transforms the lines with multiple transform for each line
|
|
74
|
+
* @param inputs lines
|
|
75
|
+
* @returns transformed lines
|
|
76
|
+
* @group transforms
|
|
77
|
+
* @shortname transform lines
|
|
78
|
+
* @drawable true
|
|
79
|
+
*/
|
|
80
|
+
transformsForLines(inputs) {
|
|
81
|
+
return inputs.lines.map((line, index) => {
|
|
82
|
+
const transformation = inputs.transformation[index];
|
|
83
|
+
let transformedControlPoints = [line.start, line.end];
|
|
84
|
+
transformedControlPoints = this.geometryHelper.transformControlPoints(transformation, transformedControlPoints);
|
|
85
|
+
return {
|
|
86
|
+
start: transformedControlPoints[0],
|
|
87
|
+
end: transformedControlPoints[1]
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create the line
|
|
93
|
+
* @param inputs start and end points of the line
|
|
94
|
+
* @returns line
|
|
95
|
+
* @group create
|
|
96
|
+
* @shortname line
|
|
97
|
+
* @drawable true
|
|
98
|
+
*/
|
|
99
|
+
create(inputs) {
|
|
100
|
+
return {
|
|
101
|
+
start: inputs.start,
|
|
102
|
+
end: inputs.end,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create the segment
|
|
107
|
+
* @param inputs start and end points of the segment
|
|
108
|
+
* @returns segment
|
|
109
|
+
* @group create
|
|
110
|
+
* @shortname segment
|
|
111
|
+
* @drawable true
|
|
112
|
+
*/
|
|
113
|
+
createSegment(inputs) {
|
|
114
|
+
return [
|
|
115
|
+
inputs.start,
|
|
116
|
+
inputs.end,
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Gets the point on the line segment at a given param
|
|
121
|
+
* @param inputs line
|
|
122
|
+
* @returns point on line
|
|
123
|
+
* @group get
|
|
124
|
+
* @shortname point on line
|
|
125
|
+
* @drawable true
|
|
126
|
+
*/
|
|
127
|
+
getPointOnLine(inputs) {
|
|
128
|
+
// Calculate direction vector of line segment
|
|
129
|
+
const point1 = inputs.line.start;
|
|
130
|
+
const point2 = inputs.line.end;
|
|
131
|
+
const parameter = inputs.param;
|
|
132
|
+
const direction = [point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]];
|
|
133
|
+
// Calculate point on line segment corresponding to parameter value
|
|
134
|
+
const point = [point1[0] + parameter * direction[0], point1[1] + parameter * direction[1], point1[2] + parameter * direction[2]];
|
|
135
|
+
return point;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Create the lines segments between all of the points in a list
|
|
139
|
+
* @param inputs points
|
|
140
|
+
* @returns lines
|
|
141
|
+
* @group create
|
|
142
|
+
* @shortname lines between points
|
|
143
|
+
* @drawable true
|
|
144
|
+
*/
|
|
145
|
+
linesBetweenPoints(inputs) {
|
|
146
|
+
const lines = [];
|
|
147
|
+
for (let i = 1; i < inputs.points.length; i++) {
|
|
148
|
+
const previousPoint = inputs.points[i - 1];
|
|
149
|
+
const currentPoint = inputs.points[i];
|
|
150
|
+
lines.push({ start: previousPoint, end: currentPoint });
|
|
151
|
+
}
|
|
152
|
+
return lines;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Create the lines between start and end points
|
|
156
|
+
* @param inputs start points and end points
|
|
157
|
+
* @returns lines
|
|
158
|
+
* @group create
|
|
159
|
+
* @shortname start and end points to lines
|
|
160
|
+
* @drawable true
|
|
161
|
+
*/
|
|
162
|
+
linesBetweenStartAndEndPoints(inputs) {
|
|
163
|
+
return inputs.startPoints
|
|
164
|
+
.map((s, index) => ({ start: s, end: inputs.endPoints[index] }))
|
|
165
|
+
.filter(line => this.point.distance({ startPoint: line.start, endPoint: line.end }) !== 0);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Convert the line to segment
|
|
169
|
+
* @param inputs line
|
|
170
|
+
* @returns segment
|
|
171
|
+
* @group convert
|
|
172
|
+
* @shortname line to segment
|
|
173
|
+
* @drawable false
|
|
174
|
+
*/
|
|
175
|
+
lineToSegment(inputs) {
|
|
176
|
+
return [inputs.line.start, inputs.line.end];
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Converts the lines to segments
|
|
180
|
+
* @param inputs lines
|
|
181
|
+
* @returns segments
|
|
182
|
+
* @group convert
|
|
183
|
+
* @shortname lines to segments
|
|
184
|
+
* @drawable false
|
|
185
|
+
*/
|
|
186
|
+
linesToSegments(inputs) {
|
|
187
|
+
return inputs.lines.map(line => [line.start, line.end]);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Converts the segment to line
|
|
191
|
+
* @param inputs segment
|
|
192
|
+
* @returns line
|
|
193
|
+
* @group convert
|
|
194
|
+
* @shortname segment to line
|
|
195
|
+
* @drawable true
|
|
196
|
+
*/
|
|
197
|
+
segmentToLine(inputs) {
|
|
198
|
+
return { start: inputs.segment[0], end: inputs.segment[1] };
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Converts the segments to lines
|
|
202
|
+
* @param inputs segments
|
|
203
|
+
* @returns lines
|
|
204
|
+
* @group convert
|
|
205
|
+
* @shortname segments to lines
|
|
206
|
+
* @drawable true
|
|
207
|
+
*/
|
|
208
|
+
segmentsToLines(inputs) {
|
|
209
|
+
return inputs.segments.map(segment => ({ start: segment[0], end: segment[1] }));
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* If two lines intersect return the intersection point
|
|
213
|
+
* @param inputs line1 and line2
|
|
214
|
+
* @returns intersection point or undefined if no intersection
|
|
215
|
+
* @group intersection
|
|
216
|
+
* @shortname line-line int
|
|
217
|
+
* @drawable true
|
|
218
|
+
*/
|
|
219
|
+
lineLineIntersection(inputs) {
|
|
220
|
+
const epsilon = inputs.tolerance || 1e-6; // Default tolerance
|
|
221
|
+
const checkSegments = inputs.checkSegmentsOnly;
|
|
222
|
+
const line1 = inputs.line1;
|
|
223
|
+
const line2 = inputs.line2;
|
|
224
|
+
// Input validation
|
|
225
|
+
if (!(line1 === null || line1 === void 0 ? void 0 : line1.start) || !line1.end || !(line2 === null || line2 === void 0 ? void 0 : line2.start) || !line2.end ||
|
|
226
|
+
line1.start.length !== 3 || line1.end.length !== 3 ||
|
|
227
|
+
line2.start.length !== 3 || line2.end.length !== 3) {
|
|
228
|
+
console.error("Invalid line input to lineLineIntersection");
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
const p1 = line1.start;
|
|
232
|
+
const d1 = this.vector.sub({ first: line1.end, second: line1.start }); // Direction vector line 1
|
|
233
|
+
const p2 = line2.start;
|
|
234
|
+
const d2 = this.vector.sub({ first: line2.end, second: line2.start }); // Direction vector line 2
|
|
235
|
+
const p21 = this.vector.sub({ first: p2, second: p1 }); // Vector between start points
|
|
236
|
+
// --- Check for Zero-Length Segments ---
|
|
237
|
+
const lenSq1 = this.vector.lengthSq({ vector: d1 });
|
|
238
|
+
const lenSq2 = this.vector.lengthSq({ vector: d2 });
|
|
239
|
+
// Compare squared length against squared epsilon
|
|
240
|
+
if (lenSq1 < epsilon * epsilon || lenSq2 < epsilon * epsilon) {
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
// --- Check for Parallelism ---
|
|
244
|
+
const d1_cross_d2 = this.vector.cross({ first: d1, second: d2 });
|
|
245
|
+
const crossMagSq = this.vector.lengthSq({ vector: d1_cross_d2 });
|
|
246
|
+
// Check if squared magnitude of cross product is near zero (relative to segment lengths)
|
|
247
|
+
// Use epsilon squared as a base tolerance, potentially scale by magnitudes
|
|
248
|
+
const parallel_tolerance_sq = epsilon * epsilon; // May need adjustment: * lenSq1 * lenSq2;
|
|
249
|
+
if (crossMagSq < parallel_tolerance_sq) {
|
|
250
|
+
// Potentially Parallel or Collinear
|
|
251
|
+
// Check if collinear: p21 must be parallel to d1
|
|
252
|
+
const p21_cross_d1 = this.vector.cross({ first: p21, second: d1 });
|
|
253
|
+
// Use similar tolerance logic for collinear check
|
|
254
|
+
const collinear_tolerance_sq = epsilon * epsilon * lenSq1; // Scale by line1 length
|
|
255
|
+
if (this.vector.lengthSq({ vector: p21_cross_d1 }) < collinear_tolerance_sq) {
|
|
256
|
+
// Collinear
|
|
257
|
+
if (!checkSegments) {
|
|
258
|
+
return p1; // Infinite lines intersect everywhere, return p1 arbitrarily
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
// --- Check for Segment Overlap (Collinear case) ---
|
|
262
|
+
const d1d1 = lenSq1; // Reuse calculated squared length
|
|
263
|
+
// Avoid division by zero if lenSq1 is extremely small (should be caught earlier)
|
|
264
|
+
const safe_d1d1 = (d1d1 < epsilon * epsilon) ? 1.0 : d1d1;
|
|
265
|
+
const d1p21 = this.vector.dot({ first: d1, second: p21 }); // Dot product d1·(p2-p1)
|
|
266
|
+
const t_p2 = d1p21 / safe_d1d1; // Parameter for p2 projected onto line1's frame
|
|
267
|
+
const vec_e2_p1 = this.vector.sub({ first: line2.end, second: p1 });
|
|
268
|
+
const t_e2 = this.vector.dot({ first: d1, second: vec_e2_p1 }) / safe_d1d1; // Param for e2
|
|
269
|
+
const interval2_t = [Math.min(t_p2, t_e2), Math.max(t_p2, t_e2)];
|
|
270
|
+
const interval1_t = [0, 1]; // Line1 segment parameter range
|
|
271
|
+
const overlap_start = Math.max(interval1_t[0], interval2_t[0]);
|
|
272
|
+
const overlap_end = Math.min(interval1_t[1], interval2_t[1]);
|
|
273
|
+
// Check for overlap including tolerance
|
|
274
|
+
if (overlap_start <= overlap_end + epsilon) {
|
|
275
|
+
// Overlap exists, but intersection is a segment, not a single point
|
|
276
|
+
return undefined;
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
// Collinear but segments do not overlap
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
// Parallel but not collinear
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// --- Lines are NOT Parallel - Check for Skewness using Scalar Triple Product ---
|
|
290
|
+
const scalarTripleProduct = this.vector.dot({ first: p21, second: d1_cross_d2 });
|
|
291
|
+
// If the scalar triple product is significantly non-zero, the lines are skew.
|
|
292
|
+
// Tolerance needs consideration - relates to the "volume" formed by the vectors.
|
|
293
|
+
// A simple absolute check against epsilon^3 or similar might work for typical scales.
|
|
294
|
+
// Consider scaling tolerance if coordinates can be very large/small.
|
|
295
|
+
const skew_tolerance = epsilon * epsilon * epsilon;
|
|
296
|
+
if (Math.abs(scalarTripleProduct) > skew_tolerance) {
|
|
297
|
+
// Lines are Skew
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
// --- Lines are Intersecting (Coplanar and Non-Parallel) ---
|
|
301
|
+
// Calculate intersection parameters t (for line1) and u (for line2)
|
|
302
|
+
// We can use the formulas derived earlier, which are valid for intersecting lines.
|
|
303
|
+
const d1d1 = lenSq1;
|
|
304
|
+
const d2d2 = lenSq2;
|
|
305
|
+
const d1d2 = this.vector.dot({ first: d1, second: d2 });
|
|
306
|
+
const d1p21 = this.vector.dot({ first: d1, second: p21 });
|
|
307
|
+
const d2p21 = this.vector.dot({ first: d2, second: p21 });
|
|
308
|
+
// Denominator for parameter calculation (same as crossMagSq, essentially)
|
|
309
|
+
const denominator = d1d1 * d2d2 - d1d2 * d1d2;
|
|
310
|
+
// Denominator *should* be non-zero based on the parallelism check above,
|
|
311
|
+
// but add a defensive check.
|
|
312
|
+
if (Math.abs(denominator) < epsilon * epsilon) {
|
|
313
|
+
console.error("Internal error: Denominator near zero after non-parallel check.");
|
|
314
|
+
return undefined; // Should not happen
|
|
315
|
+
}
|
|
316
|
+
const t = (d2d2 * d1p21 - d1d2 * d2p21) / denominator;
|
|
317
|
+
const u = (d1d2 * d1p21 - d1d1 * d2p21) / denominator;
|
|
318
|
+
// --- Optional check: Is intersection within segment bounds? ---
|
|
319
|
+
if (checkSegments) {
|
|
320
|
+
// Check if t and u are within the range [0, 1] (using tolerance)
|
|
321
|
+
if (t < -epsilon || t > 1.0 + epsilon || u < -epsilon || u > 1.0 + epsilon) {
|
|
322
|
+
return undefined; // Intersection point is outside one or both segments
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// --- Calculate Intersection Point ---
|
|
326
|
+
const intersectionPoint = this.getPointOnLine({ param: t, line: line1 });
|
|
327
|
+
// Clip near-zero results based on the input epsilon
|
|
328
|
+
return [
|
|
329
|
+
Math.abs(intersectionPoint[0]) < epsilon ? 0 : intersectionPoint[0],
|
|
330
|
+
Math.abs(intersectionPoint[1]) < epsilon ? 0 : intersectionPoint[1],
|
|
331
|
+
Math.abs(intersectionPoint[2]) < epsilon ? 0 : intersectionPoint[2],
|
|
332
|
+
];
|
|
333
|
+
}
|
|
334
|
+
}
|
|
@@ -95,7 +95,7 @@ export declare class Lists {
|
|
|
95
95
|
* @shortname group elements
|
|
96
96
|
* @drawable false
|
|
97
97
|
*/
|
|
98
|
-
groupNth<T>(inputs: Inputs.Lists.GroupListDto<T>): T[];
|
|
98
|
+
groupNth<T>(inputs: Inputs.Lists.GroupListDto<T>): T[][];
|
|
99
99
|
/**
|
|
100
100
|
* Get the depth of the list
|
|
101
101
|
* @param inputs a list
|
|
@@ -267,13 +267,12 @@ export class Lists {
|
|
|
267
267
|
result.push(currentGroup);
|
|
268
268
|
currentGroup = [];
|
|
269
269
|
}
|
|
270
|
-
if (keepRemainder && index === list.length - 1) {
|
|
270
|
+
if (currentGroup.length > 0 && keepRemainder && index === list.length - 1) {
|
|
271
271
|
result.push(currentGroup);
|
|
272
272
|
}
|
|
273
273
|
});
|
|
274
274
|
return result;
|
|
275
275
|
};
|
|
276
|
-
// TODO make this work on any level
|
|
277
276
|
return groupElements(inputs);
|
|
278
277
|
}
|
|
279
278
|
/**
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as Inputs from "../inputs";
|
|
2
|
+
import { Polyline } from "./polyline";
|
|
3
|
+
import { Vector } from "./vector";
|
|
4
|
+
/**
|
|
5
|
+
* Contains various mesh helper methods that are not necessarily present in higher level CAD kernels that bitbybit is using.
|
|
6
|
+
*/
|
|
7
|
+
export declare class MeshBitByBit {
|
|
8
|
+
private readonly vector;
|
|
9
|
+
private readonly polyline;
|
|
10
|
+
constructor(vector: Vector, polyline: Polyline);
|
|
11
|
+
/**
|
|
12
|
+
* Computes the signed distance from a point to a plane.
|
|
13
|
+
* @param inputs a point and a plane
|
|
14
|
+
* @returns signed distance
|
|
15
|
+
* @group base
|
|
16
|
+
* @shortname signed dist to plane
|
|
17
|
+
* @drawable false
|
|
18
|
+
*/
|
|
19
|
+
signedDistanceToPlane(inputs: Inputs.Mesh.SignedDistanceFromPlaneToPointDto): number;
|
|
20
|
+
/**
|
|
21
|
+
* Calculates the triangle plane from triangle.
|
|
22
|
+
* @param inputs triangle and tolerance
|
|
23
|
+
* @returns triangle plane
|
|
24
|
+
* @group traingle
|
|
25
|
+
* @shortname triangle plane
|
|
26
|
+
* @drawable false
|
|
27
|
+
*/
|
|
28
|
+
calculateTrianglePlane(inputs: Inputs.Mesh.TriangleToleranceDto): Inputs.Base.TrianglePlane3 | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Calculates the intersection of two triangles.
|
|
31
|
+
* @param inputs first triangle, second triangle, and tolerance
|
|
32
|
+
* @returns intersection segment or undefined if no intersection
|
|
33
|
+
* @group traingle
|
|
34
|
+
* @shortname triangle-triangle int
|
|
35
|
+
* @drawable false
|
|
36
|
+
*/
|
|
37
|
+
triangleTriangleIntersection(inputs: Inputs.Mesh.TriangleTriangleToleranceDto): Inputs.Base.Segment3 | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Computes the intersection segments of two meshes.
|
|
40
|
+
* @param inputs first mesh, second mesh, and tolerance
|
|
41
|
+
* @returns array of intersection segments
|
|
42
|
+
* @group mesh
|
|
43
|
+
* @shortname mesh-mesh int segments
|
|
44
|
+
* @drawable false
|
|
45
|
+
*/
|
|
46
|
+
meshMeshIntersectionSegments(inputs: Inputs.Mesh.MeshMeshToleranceDto): Inputs.Base.Segment3[];
|
|
47
|
+
/**
|
|
48
|
+
* Computes the intersection polylines of two meshes.
|
|
49
|
+
* @param inputs first mesh, second mesh, and tolerance
|
|
50
|
+
* @returns array of intersection polylines
|
|
51
|
+
* @group mesh
|
|
52
|
+
* @shortname mesh-mesh int polylines
|
|
53
|
+
* @drawable true
|
|
54
|
+
*/
|
|
55
|
+
meshMeshIntersectionPolylines(inputs: Inputs.Mesh.MeshMeshToleranceDto): Inputs.Base.Polyline3[];
|
|
56
|
+
/**
|
|
57
|
+
* Computes the intersection points of two meshes.
|
|
58
|
+
* @param inputs first mesh, second mesh, and tolerance
|
|
59
|
+
* @returns array of intersection points
|
|
60
|
+
* @group mesh
|
|
61
|
+
* @shortname mesh-mesh int points
|
|
62
|
+
* @drawable false
|
|
63
|
+
*/
|
|
64
|
+
meshMeshIntersectionPoints(inputs: Inputs.Mesh.MeshMeshToleranceDto): Inputs.Base.Point3[][];
|
|
65
|
+
private computeIntersectionPoint;
|
|
66
|
+
}
|