engeom 0.2.5__cp38-abi3-macosx_11_0_arm64.whl → 0.2.6__cp38-abi3-macosx_11_0_arm64.whl
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.
- engeom/_plot/__init__.py +1 -0
- engeom/_plot/common.py +17 -0
- engeom/{matplotlib.py → _plot/matplotlib.py} +88 -45
- engeom/_plot/pyvista.py +256 -0
- engeom/airfoil/__init__.py +4 -0
- engeom/airfoil.pyi +202 -51
- engeom/engeom.abi3.so +0 -0
- engeom/engeom.pyi +35 -2
- engeom/geom2/__init__.py +5 -0
- engeom/geom2.pyi +323 -85
- engeom/geom3/__init__.py +5 -0
- engeom/geom3.pyi +406 -117
- engeom/metrology/__init__.py +4 -0
- engeom/metrology.pyi +85 -12
- engeom/plot.py +26 -0
- {engeom-0.2.5.dist-info → engeom-0.2.6.dist-info}/METADATA +1 -1
- engeom-0.2.6.dist-info/RECORD +21 -0
- engeom/pyvista.py +0 -178
- engeom-0.2.5.dist-info/RECORD +0 -18
- {engeom-0.2.5.dist-info → engeom-0.2.6.dist-info}/WHEEL +0 -0
engeom/geom2.pyi
CHANGED
@@ -2,149 +2,261 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from typing import Iterable, Tuple, TypeVar, Iterator, Any
|
4
4
|
|
5
|
-
import
|
6
|
-
from engeom.engeom import
|
5
|
+
from numpy.typing import NDArray
|
6
|
+
from engeom.engeom import ResampleEnum
|
7
|
+
|
8
|
+
from engeom import geom3
|
7
9
|
|
8
10
|
Transformable2 = TypeVar("Transformable2", Vector2, Point2, Iso2, SurfacePoint2)
|
9
11
|
PointOrVec2 = TypeVar("PointOrVec2", Point2, Vector2)
|
10
12
|
|
11
13
|
|
12
14
|
class Vector2(Iterable[float]):
|
15
|
+
"""
|
16
|
+
A class representing a vector in 2D space. The vector contains an x and y component. It is iterable and will
|
17
|
+
yield the x and y components in order, allowing the Python unpacking operator `*` to be used to compensate for the
|
18
|
+
lack of function overloading through some other parts of the library.
|
19
|
+
|
20
|
+
A vector has different semantics than a point when it comes to transformations and some mathematical operations.
|
21
|
+
"""
|
22
|
+
|
13
23
|
def __iter__(self) -> Iterator[float]:
|
14
24
|
pass
|
15
25
|
|
16
26
|
def __init__(self, x: float, y: float):
|
17
27
|
"""
|
18
|
-
|
19
|
-
:param x:
|
20
|
-
:param y:
|
28
|
+
Create a 2D vector from the given x and y components.
|
29
|
+
:param x: the x component of the vector.
|
30
|
+
:param y: the y component of the vector.
|
21
31
|
"""
|
22
32
|
...
|
23
33
|
|
24
34
|
@property
|
25
35
|
def x(self) -> float:
|
36
|
+
"""
|
37
|
+
Access the x component of the vector as a floating point value.
|
38
|
+
"""
|
26
39
|
...
|
27
40
|
|
28
41
|
@property
|
29
42
|
def y(self) -> float:
|
43
|
+
"""
|
44
|
+
Access the y component of the vector as a floating point value.
|
45
|
+
"""
|
30
46
|
...
|
31
47
|
|
32
48
|
def __rmul__(self, other: float) -> Vector2:
|
49
|
+
"""
|
50
|
+
Multiply the vector by a scalar value. This allows the scalar to be on the left side of the multiplication
|
51
|
+
operator.
|
52
|
+
:param other: a scalar value to multiply the vector by.
|
53
|
+
:return: a new vector that is the result of the multiplication.
|
54
|
+
"""
|
55
|
+
...
|
56
|
+
|
57
|
+
def __mul__(self, other: float) -> Vector2:
|
58
|
+
"""
|
59
|
+
Multiply the vector by a scalar value.
|
60
|
+
:param other: a scalar value to multiply the vector by.
|
61
|
+
:return: a new vector that is the result of the multiplication.
|
62
|
+
"""
|
33
63
|
...
|
34
64
|
|
35
65
|
def __add__(self, other: PointOrVec2) -> PointOrVec2:
|
66
|
+
"""
|
67
|
+
Add a vector to a point or another vector. Adding a vector to a point will return a new point, while
|
68
|
+
adding a vector to a vector will return a new vector.
|
69
|
+
:param other: a point or vector to add to the vector.
|
70
|
+
:return: a new point or vector that is the result of the addition.
|
71
|
+
"""
|
36
72
|
...
|
37
73
|
|
38
74
|
def __sub__(self, other: Vector2) -> Vector2:
|
75
|
+
"""
|
76
|
+
Subtract a vector from this vector.
|
77
|
+
:param other: the vector to subtract from this vector.
|
78
|
+
:return: a new vector that is the result of the subtraction.
|
79
|
+
"""
|
39
80
|
...
|
40
81
|
|
41
82
|
def __neg__(self) -> Vector2:
|
83
|
+
"""
|
84
|
+
Invert the vector by negating the x and y components.
|
85
|
+
:return: a new vector in which the x and y components are negated.
|
86
|
+
"""
|
42
87
|
...
|
43
88
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
89
|
+
def __truediv__(self, other: float) -> Vector2:
|
90
|
+
"""
|
91
|
+
Divide the vector by a scalar value.
|
92
|
+
:param other: a scalar value to divide the vector by.
|
93
|
+
:return: a new vector that is the result of the division.
|
94
|
+
"""
|
48
95
|
...
|
49
96
|
|
50
|
-
def as_numpy(self) ->
|
97
|
+
def as_numpy(self) -> NDArray[float]:
|
51
98
|
"""
|
52
|
-
Create a numpy array of shape (2,) from the vector.
|
99
|
+
Create a numpy array of shape (2, ) from the vector.
|
53
100
|
"""
|
54
101
|
...
|
55
102
|
|
56
103
|
def dot(self, other: Vector2) -> float:
|
57
104
|
"""
|
58
|
-
Compute the dot product of two vectors.
|
105
|
+
Compute the dot product of two vectors. The result is a scalar value.
|
106
|
+
:param other: the vector to compute the dot product with.
|
107
|
+
:return: the scalar dot product of the two vectors.
|
59
108
|
"""
|
60
109
|
...
|
61
110
|
|
62
111
|
def cross(self, other: Vector2) -> float:
|
63
112
|
"""
|
64
113
|
Compute the cross product of two vectors.
|
114
|
+
:param other: the vector to compute the cross product with.
|
115
|
+
:return: the scalar cross product of the two vectors.
|
65
116
|
"""
|
66
117
|
...
|
67
118
|
|
68
119
|
def norm(self) -> float:
|
69
120
|
"""
|
70
|
-
Compute the norm of the vector.
|
121
|
+
Compute the Euclidian norm (aka magnitude, length) of the vector.
|
71
122
|
"""
|
72
123
|
...
|
73
124
|
|
74
125
|
def normalized(self) -> Vector2:
|
75
126
|
"""
|
76
|
-
Return a normalized version of the vector.
|
127
|
+
Return a normalized version of the vector. The normalized vector will have the same direction as the original
|
128
|
+
vector, but with a magnitude of 1.
|
77
129
|
"""
|
78
130
|
...
|
79
131
|
|
80
132
|
def angle_to(self, other: Vector2) -> float:
|
81
133
|
"""
|
82
134
|
Compute the smallest angle between two vectors and return it in radians.
|
135
|
+
|
136
|
+
:param other: the vector to compute the angle to.
|
137
|
+
:return: the angle between the two vectors in radians.
|
83
138
|
"""
|
84
139
|
...
|
85
140
|
|
86
141
|
|
87
142
|
class Point2(Iterable[float]):
|
143
|
+
"""
|
144
|
+
A class representing a point in 2D space. The point contains an x and y component. It is iterable and will yield
|
145
|
+
the x and y components in order, allowing the Python unpacking operator `*` to be used to compensate for the lack
|
146
|
+
of function overloading through some other parts of the library.
|
147
|
+
|
148
|
+
A point has different semantics than a vector when it comes to transformations and some mathematical operations.
|
149
|
+
"""
|
150
|
+
|
88
151
|
def __iter__(self) -> Iterator[float]:
|
89
152
|
pass
|
90
153
|
|
91
154
|
def __init__(self, x: float, y: float):
|
92
155
|
"""
|
93
|
-
|
94
|
-
:param x:
|
95
|
-
:param y:
|
156
|
+
Create a 2D point from the given x and y components.
|
157
|
+
:param x: the x component of the point.
|
158
|
+
:param y: the y component of the point.
|
96
159
|
"""
|
97
160
|
...
|
98
161
|
|
99
162
|
@property
|
100
163
|
def x(self) -> float:
|
164
|
+
"""
|
165
|
+
Access the x component of the point as a floating point value.
|
166
|
+
"""
|
101
167
|
...
|
102
168
|
|
103
169
|
@property
|
104
170
|
def y(self) -> float:
|
171
|
+
"""
|
172
|
+
Access the y component of the point as a floating point value.
|
173
|
+
"""
|
105
174
|
...
|
106
175
|
|
107
176
|
@property
|
108
177
|
def coords(self) -> Vector2:
|
109
178
|
"""
|
110
|
-
Get the coordinates of the point as a Vector2 object.
|
111
|
-
:return: a Vector2 object
|
179
|
+
Get the coordinates of the point as a `Vector2` object.
|
180
|
+
:return: a `Vector2` object with the same x and y components as the point.
|
112
181
|
"""
|
113
182
|
...
|
114
183
|
|
115
184
|
def __sub__(self, other: PointOrVec2) -> PointOrVec2:
|
185
|
+
"""
|
186
|
+
Subtract a point or vector from this point. Subtracting a point from a point will return a new vector, while
|
187
|
+
subtracting a vector from a point will return a new point.
|
188
|
+
:param other: a point or vector to subtract from the point.
|
189
|
+
:return: a new point or vector that is the result of the subtraction.
|
190
|
+
"""
|
116
191
|
...
|
117
192
|
|
118
193
|
def __add__(self, other: Vector2) -> Vector2:
|
194
|
+
"""
|
195
|
+
Add a vector to this point.
|
196
|
+
:param other: the vector to add to the point.
|
197
|
+
:return: a new point that is the result of the addition.
|
198
|
+
"""
|
119
199
|
...
|
120
200
|
|
121
|
-
def __mul__(self, other) -> Point2:
|
201
|
+
def __mul__(self, other: float) -> Point2:
|
202
|
+
"""
|
203
|
+
Multiply the point's x and y components by a scalar value, returning a new point.
|
204
|
+
:param other: the scalar value to multiply the point by.
|
205
|
+
:return: a new point that is the result of the multiplication.
|
206
|
+
"""
|
122
207
|
...
|
123
208
|
|
124
209
|
def __truediv__(self, other) -> Point2:
|
210
|
+
"""
|
211
|
+
Divide the point's x and y components by a scalar value, returning a new point.
|
212
|
+
:param other: the scalar value to divide the point by.
|
213
|
+
:return: a new point that is the result of the division.
|
214
|
+
"""
|
125
215
|
...
|
126
216
|
|
127
217
|
def __rmul__(self, other) -> Point2:
|
218
|
+
"""
|
219
|
+
Multiply the point's x and y components by a scalar value, returning a new point. This allows the scalar to be
|
220
|
+
on the left side of the multiplication.
|
221
|
+
:param other: the scalar value to multiply the point by.
|
222
|
+
:return: a new point that is the result of the multiplication.
|
223
|
+
"""
|
128
224
|
...
|
129
225
|
|
130
226
|
def __neg__(self) -> Point2:
|
227
|
+
"""
|
228
|
+
Invert the point by negating the x and y components.
|
229
|
+
:return: a new point in which the x and y components are negated.
|
230
|
+
"""
|
131
231
|
...
|
132
232
|
|
133
|
-
def as_numpy(self) ->
|
233
|
+
def as_numpy(self) -> NDArray[float]:
|
134
234
|
"""
|
135
|
-
Create a numpy array of shape (2,) from the point.
|
235
|
+
Create a numpy array of shape (2, ) from the point.
|
136
236
|
"""
|
137
237
|
...
|
138
238
|
|
139
239
|
|
140
240
|
class SurfacePoint2:
|
241
|
+
"""
|
242
|
+
This class is used to represent a surface point in 2D space.
|
243
|
+
|
244
|
+
Surface points are a composite structure that consist of a point in space and a normal direction. Conceptually, they
|
245
|
+
come from metrology as a means of representing a point on the surface of an object along with the normal direction
|
246
|
+
of the surface at that point. However, they are also isomorphic with the concept of a ray or a parameterized line
|
247
|
+
with a direction of unit length, and can be used in that way as well.
|
248
|
+
"""
|
249
|
+
|
141
250
|
def __init__(self, x: float, y: float, nx: float, ny: float):
|
142
251
|
"""
|
252
|
+
Create a surface point from the given x and y components and the normal vector components. The normal vector
|
253
|
+
components will be normalized automatically upon creation. If the normal vector is the zero vector, an
|
254
|
+
exception will be thrown.
|
143
255
|
|
144
|
-
:param x:
|
145
|
-
:param y:
|
146
|
-
:param nx:
|
147
|
-
:param ny:
|
256
|
+
:param x: the x component of the point.
|
257
|
+
:param y: the y component of the point.
|
258
|
+
:param nx: the x component of the normal vector.
|
259
|
+
:param ny: the y component of the normal vector.
|
148
260
|
"""
|
149
261
|
...
|
150
262
|
|
@@ -229,15 +341,15 @@ class SurfacePoint2:
|
|
229
341
|
for clockwise rotation.
|
230
342
|
|
231
343
|
:param angle: the angle to rotate the normal vector by.
|
232
|
-
:return:
|
344
|
+
:return: a new surface point with the rotated normal vector.
|
233
345
|
"""
|
234
346
|
|
235
347
|
def __mul__(self, other: float) -> SurfacePoint2:
|
236
348
|
"""
|
237
349
|
Multiply the position of the surface point by a scalar value. The normal vector is not affected unless the
|
238
350
|
scalar is negative, in which case the normal vector is inverted.
|
239
|
-
:param other:
|
240
|
-
:return:
|
351
|
+
:param other: the scalar value to multiply the position by.
|
352
|
+
:return: a new surface point with the position multiplied by the scalar.
|
241
353
|
"""
|
242
354
|
...
|
243
355
|
|
@@ -245,8 +357,8 @@ class SurfacePoint2:
|
|
245
357
|
"""
|
246
358
|
Multiply the position of the surface point by a scalar value. The normal vector is not affected unless the
|
247
359
|
scalar is negative, in which case the normal vector is inverted.
|
248
|
-
:param other:
|
249
|
-
:return:
|
360
|
+
:param other: the scalar value to multiply the position by.
|
361
|
+
:return: a new surface point with the position multiplied by the scalar.
|
250
362
|
"""
|
251
363
|
...
|
252
364
|
|
@@ -254,8 +366,8 @@ class SurfacePoint2:
|
|
254
366
|
"""
|
255
367
|
Divide the position of the surface point by a scalar value. The normal vector is not affected unless the
|
256
368
|
scalar is negative, in which case the normal vector is inverted.
|
257
|
-
:param other:
|
258
|
-
:return:
|
369
|
+
:param other: the scalar value to divide the position by.
|
370
|
+
:return: a new surface point with the position divided by the scalar.
|
259
371
|
"""
|
260
372
|
...
|
261
373
|
|
@@ -267,12 +379,27 @@ class SurfacePoint2:
|
|
267
379
|
|
268
380
|
|
269
381
|
class Iso2:
|
382
|
+
"""
|
383
|
+
A class representing an isometry in 2D space. An isometry is a transformation that preserves distances and angles,
|
384
|
+
also sometimes known as a rigid body transformation. It is composed of a translation and a rotation.
|
385
|
+
|
386
|
+
`Iso2` objects can be used to transform points, vectors, surface points, other isometries, and a number of other
|
387
|
+
2D geometric constructs.
|
388
|
+
"""
|
389
|
+
|
270
390
|
def __init__(self, tx: float, ty: float, r: float):
|
271
391
|
"""
|
392
|
+
Create an isometry from a translation and a rotation. The translation is represented by the x and y components
|
393
|
+
of the translation vector. The rotation is represented by the angle in radians, and will be a rotation around
|
394
|
+
the origin of the coordinate system.
|
395
|
+
|
396
|
+
In convention with typical transformation matrices, transforming by an isometry constructed this way is the
|
397
|
+
equivalent of first rotating by the angle `r` and then translating by the vector `(tx, ty)`.
|
272
398
|
|
273
|
-
:param tx:
|
274
|
-
:param ty:
|
275
|
-
:param r:
|
399
|
+
:param tx: the x component of the translation vector.
|
400
|
+
:param ty: the y component of the translation vector.
|
401
|
+
:param r: the angle of rotation in radians around the origin, where a positive value is a counter-clockwise
|
402
|
+
rotation.
|
276
403
|
"""
|
277
404
|
...
|
278
405
|
|
@@ -284,43 +411,81 @@ class Iso2:
|
|
284
411
|
...
|
285
412
|
|
286
413
|
def __matmul__(self, other: Transformable2) -> Transformable2:
|
414
|
+
"""
|
415
|
+
Transform a point, vector, or other transformable object by the isometry using the matrix multiplication
|
416
|
+
operator. The transform must be on the right side of the operator, and the object being transformed must be on
|
417
|
+
the left side. This is the equivalent of multiplying the object by the isometry matrix.
|
418
|
+
|
419
|
+
When composing multiple isometries together, remember that the order of operations is reversed. For example, if
|
420
|
+
you have isometries A, B, and C, and you want to compose them together such that they are the equivalent of
|
421
|
+
first applying A, then B, then C, you would write `D = C @ B @ A`.
|
422
|
+
|
423
|
+
:param other: the object to transform.
|
424
|
+
:return: an object of the same type as the input, transformed by the isometry.
|
425
|
+
"""
|
287
426
|
...
|
288
427
|
|
289
428
|
def inverse(self) -> Iso2:
|
290
429
|
"""
|
291
|
-
Get the inverse of the isometry
|
430
|
+
Get the inverse of the isometry, which is the isometry that undoes the transformation of the original isometry,
|
431
|
+
or the isometry that when composed with the original isometry produces the identity isometry.
|
292
432
|
"""
|
293
433
|
...
|
294
434
|
|
295
|
-
def as_numpy(self) ->
|
435
|
+
def as_numpy(self) -> NDArray[float]:
|
296
436
|
"""
|
297
437
|
Create a numpy array of shape (3, 3) from the isometry.
|
298
438
|
"""
|
299
439
|
...
|
300
440
|
|
301
|
-
def transform_points(self, points:
|
441
|
+
def transform_points(self, points: NDArray[float]) -> NDArray[float]:
|
302
442
|
"""
|
303
|
-
Transform an array of points using the isometry.
|
443
|
+
Transform an array of points using the isometry. The semantics of transforming points are such that the full
|
444
|
+
matrix is applied, first rotating the point around the origin and then translating it by the translation vector.
|
445
|
+
|
446
|
+
To transform vectors, use the `transform_vectors` method instead.
|
447
|
+
|
448
|
+
This is an efficient way to transform a large number of points at once, rather than using the `@` operator
|
449
|
+
individually on a large number of `Point2` objects.
|
450
|
+
|
304
451
|
:param points: a numpy array of shape (N, 2)
|
305
|
-
:return: a numpy array of shape (N, 2)
|
452
|
+
:return: a numpy array of shape (N, 2) containing the transformed points in the same order as the input.
|
306
453
|
"""
|
307
454
|
...
|
308
455
|
|
309
|
-
def transform_vectors(self, vectors:
|
456
|
+
def transform_vectors(self, vectors: NDArray[float]) -> NDArray[float]:
|
310
457
|
"""
|
311
|
-
Transform an array of vectors using the isometry. The
|
312
|
-
|
313
|
-
|
458
|
+
Transform an array of vectors using the isometry. The semantics of transforming vectors are such that only the
|
459
|
+
rotation matrix is applied, and the translation vector is not used. The vectors retain their original
|
460
|
+
magnitude, but their direction is rotated by the isometry.
|
461
|
+
|
462
|
+
To transform points, use the `transform_points` method instead.
|
463
|
+
|
464
|
+
This is an efficient way to transform a large number of vectors at once, rather than using the `@` operator
|
465
|
+
individually on a large number of `Vector2` objects.
|
466
|
+
|
467
|
+
:param vectors: a numpy array of shape (N, 2)
|
468
|
+
:return: a numpy array of shape (N, 2) containing the transformed vectors in the same order as the input.
|
314
469
|
"""
|
315
470
|
...
|
316
471
|
|
317
472
|
|
318
473
|
class SvdBasis2:
|
474
|
+
"""
|
475
|
+
A class which creates a set of orthonormal basis vectors from a set of points in 2D space. The basis is created
|
476
|
+
using a singular value decomposition of the points, and is very similar to the statistical concept of principal
|
477
|
+
component analysis.
|
478
|
+
|
479
|
+
The basis can be used to determine the rank of the point set, the variance of the points along the basis vectors,
|
480
|
+
and to extract an isometry that will transform points from the world space to the basis space. It is useful for
|
481
|
+
orienting unknown point sets in a consistent way, for finding best-fit lines or planes, and for other similar
|
482
|
+
tasks.
|
483
|
+
"""
|
319
484
|
|
320
485
|
def __init__(
|
321
486
|
self,
|
322
|
-
points:
|
323
|
-
weights:
|
487
|
+
points: NDArray[float],
|
488
|
+
weights: NDArray[float] | None = None
|
324
489
|
):
|
325
490
|
"""
|
326
491
|
Create a basis from a set of points. The basis will be calculated using a singular value decomposition of the
|
@@ -367,14 +532,14 @@ class SvdBasis2:
|
|
367
532
|
"""
|
368
533
|
...
|
369
534
|
|
370
|
-
def basis_variances(self) ->
|
535
|
+
def basis_variances(self) -> NDArray[float]:
|
371
536
|
"""
|
372
537
|
Get the variance of the points along the singular vectors.
|
373
538
|
:return: a numpy array of the variance of the points along the singular vectors.
|
374
539
|
"""
|
375
540
|
...
|
376
541
|
|
377
|
-
def basis_stdevs(self) ->
|
542
|
+
def basis_stdevs(self) -> NDArray[float]:
|
378
543
|
"""
|
379
544
|
Get the standard deviation of the points along the singular vectors.
|
380
545
|
:return: a numpy array of the standard deviation of the points along the singular vectors.
|
@@ -394,61 +559,92 @@ class SvdBasis2:
|
|
394
559
|
|
395
560
|
class CurveStation2:
|
396
561
|
"""
|
397
|
-
A class representing a station along a curve in
|
562
|
+
A class representing a station along a curve in 2D space. The station is represented by a point on the curve, a
|
398
563
|
tangent (direction) vector, and a length along the curve.
|
564
|
+
|
565
|
+
These are created as the result of position finding operations on `Curve2` objects.
|
399
566
|
"""
|
400
567
|
|
401
568
|
@property
|
402
569
|
def point(self) -> Point2:
|
403
|
-
"""
|
570
|
+
"""
|
571
|
+
Get the point in 2D world space where the station is located.
|
572
|
+
:return: the point in 2D world space.
|
573
|
+
"""
|
404
574
|
...
|
405
575
|
|
406
576
|
@property
|
407
577
|
def direction(self) -> Vector2:
|
408
|
-
"""
|
578
|
+
"""
|
579
|
+
Get the direction vector of the curve at the location of the station. This is the tangent vector of the curve,
|
580
|
+
and is typically the direction from the previous vertex to the next vertex.
|
581
|
+
:return: the direction vector of the curve at the station.
|
582
|
+
"""
|
409
583
|
...
|
410
584
|
|
411
585
|
@property
|
412
586
|
def normal(self) -> Vector2:
|
413
|
-
"""
|
587
|
+
"""
|
588
|
+
Get the normal vector of the curve at the location of the station. This is the vector that is orthogonal to the
|
589
|
+
direction vector, and is the direction vector at the station rotated by -90 degrees. When the curve represents
|
590
|
+
a manifold surface, this vector represents the direction of the surface normal.
|
591
|
+
:return: the surface normal vector of the curve at the station.
|
592
|
+
"""
|
414
593
|
...
|
415
594
|
|
416
595
|
@property
|
417
596
|
def direction_point(self) -> SurfacePoint2:
|
418
597
|
"""
|
419
|
-
|
598
|
+
Get the combined point and direction vector of the curve at the location of the station, returned as a
|
599
|
+
`SurfacePoint2` object.
|
600
|
+
:return: the combined point and direction vector of the curve at the station.
|
420
601
|
"""
|
421
602
|
...
|
422
603
|
|
423
604
|
@property
|
424
605
|
def surface_point(self) -> SurfacePoint2:
|
425
606
|
"""
|
426
|
-
|
607
|
+
Get the combined point and normal vector of the curve at the location of the station, returned as a
|
608
|
+
`SurfacePoint2` object.
|
609
|
+
:return: the combined point and normal vector of the curve at the station.
|
427
610
|
"""
|
428
611
|
...
|
429
612
|
|
430
613
|
@property
|
431
614
|
def index(self) -> int:
|
432
|
-
"""
|
615
|
+
"""
|
616
|
+
Get the index of the previous vertex on the curve, at or before the station.
|
617
|
+
:return: the index of the previous vertex on the curve.
|
618
|
+
"""
|
433
619
|
...
|
434
620
|
|
435
621
|
@property
|
436
622
|
def length_along(self) -> float:
|
437
|
-
"""
|
623
|
+
"""
|
624
|
+
Get the length along the curve to the station, starting at the first vertex of the curve.
|
625
|
+
:return: the length along the curve to the station.
|
626
|
+
"""
|
438
627
|
...
|
439
628
|
|
440
629
|
|
441
630
|
class Curve2:
|
442
631
|
"""
|
443
632
|
A class representing a curve in 2D space. The curve is defined by a set of vertices and the line segments between
|
444
|
-
them
|
633
|
+
them (also known as a polyline).
|
634
|
+
|
635
|
+
Because the curve is in 2D space, it also has a concept of a surface normal direction, which is orthogonal to the
|
636
|
+
tangent direction of the curve at any point. This normal direction allows a `Curve2` to represent a 2D manifold
|
637
|
+
surface boundary, defining the concepts of inside and outside. It is commonly used to represent the surface of a
|
638
|
+
solid body in a 2D cross-section.
|
445
639
|
|
640
|
+
Additionally, the `Curve2` object can be used to represent closed regions by connecting the first and last vertices
|
641
|
+
and allowing the curve to be treated as a closed loop. This lets the `Curve2` also represent closed polygons.
|
446
642
|
"""
|
447
643
|
|
448
644
|
def __init__(
|
449
645
|
self,
|
450
|
-
vertices:
|
451
|
-
normals:
|
646
|
+
vertices: NDArray[float],
|
647
|
+
normals: NDArray[float] | None = None,
|
452
648
|
tol: float = 1e-6,
|
453
649
|
force_closed: bool = False,
|
454
650
|
hull_ccw: bool = False,
|
@@ -461,11 +657,14 @@ class Curve2:
|
|
461
657
|
to model a manifold surface.
|
462
658
|
|
463
659
|
There are three ways to specify the winding order of the vertices:
|
660
|
+
|
464
661
|
1. Control it manually by passing the vertices array with the rows already organized so that an exterior surface
|
465
662
|
is counter-clockwise.
|
663
|
+
|
466
664
|
2. If the vertices represent an exterior shape, pass `hull_ccw=True` to have the constructor automatically
|
467
665
|
check the winding order and reverse it if point ordering in the convex hull does not match ordering in the
|
468
666
|
original array.
|
667
|
+
|
469
668
|
3. Pass a `normals` array the same size as the `vertices` array, where the normals are non-zero vectors pointed
|
470
669
|
in the "outside" direction at each point. The constructor will reverse the winding if the majority of normals
|
471
670
|
do not point in the same direction as the winding.
|
@@ -485,7 +684,7 @@ class Curve2:
|
|
485
684
|
|
486
685
|
def length(self) -> float:
|
487
686
|
"""
|
488
|
-
Get the length of the curve.
|
687
|
+
Get the total length of the curve as a scalar value.
|
489
688
|
:return: the length of the curve.
|
490
689
|
"""
|
491
690
|
...
|
@@ -589,7 +788,7 @@ class Curve2:
|
|
589
788
|
"""
|
590
789
|
...
|
591
790
|
|
592
|
-
def make_hull(self) ->
|
791
|
+
def make_hull(self) -> NDArray[int]:
|
593
792
|
"""
|
594
793
|
Get the vertices of a convex hull of the curve, in counter-clockwise order.
|
595
794
|
:return: a numpy array of shape (N, 2) representing the convex hull of the curve.
|
@@ -613,7 +812,7 @@ class Curve2:
|
|
613
812
|
...
|
614
813
|
|
615
814
|
@property
|
616
|
-
def points(self) ->
|
815
|
+
def points(self) -> NDArray[float]:
|
617
816
|
"""
|
618
817
|
Get the points of the curve.
|
619
818
|
:return: a numpy array of shape (N, 2) representing the points of the curve.
|
@@ -628,7 +827,7 @@ class Curve2:
|
|
628
827
|
"""
|
629
828
|
...
|
630
829
|
|
631
|
-
def resample(self, resample:
|
830
|
+
def resample(self, resample: ResampleEnum) -> Curve2:
|
632
831
|
"""
|
633
832
|
Resample the curve using the given resampling method. The resampling method can be one of the following:
|
634
833
|
|
@@ -649,21 +848,32 @@ class Curve2:
|
|
649
848
|
"""
|
650
849
|
...
|
651
850
|
|
851
|
+
def to_3d(self) -> geom3.Curve3:
|
852
|
+
"""
|
853
|
+
Convert the curve to a 3D curve by adding a z-coordinate of 0 to all points.
|
854
|
+
:return: a new `Curve3` object representing the curve in 3D space.
|
855
|
+
"""
|
856
|
+
...
|
857
|
+
|
652
858
|
|
653
859
|
class Circle2:
|
860
|
+
"""
|
861
|
+
A class representing a circle in 2D space. The circle is defined by a center point and a radius.
|
862
|
+
"""
|
863
|
+
|
654
864
|
def __init__(self, x: float, y: float, r: float):
|
655
865
|
"""
|
656
|
-
|
657
|
-
:param x:
|
658
|
-
:param y:
|
659
|
-
:param r:
|
866
|
+
Create a circle from the given center point and radius.
|
867
|
+
:param x: the x-coordinate of the center of the circle.
|
868
|
+
:param y: the y-coordinate of the center of the circle.
|
869
|
+
:param r: the radius of the circle.
|
660
870
|
"""
|
661
871
|
...
|
662
872
|
|
663
873
|
@property
|
664
874
|
def center(self) -> Point2:
|
665
875
|
"""
|
666
|
-
Get the center of the circle.
|
876
|
+
Get the `Point2` at the center of the circle.
|
667
877
|
:return: the center of the circle.
|
668
878
|
"""
|
669
879
|
...
|
@@ -702,20 +912,36 @@ class Circle2:
|
|
702
912
|
|
703
913
|
|
704
914
|
class Arc2:
|
915
|
+
"""
|
916
|
+
An arc in 2D space. The arc is defined by a center point, a radius, a start angle, and a sweep angle.
|
917
|
+
|
918
|
+
* The center point and the radius define the circle of which the arc is part.
|
919
|
+
|
920
|
+
* The start angle is the angle in radians from the positive x-axis to the point where the arc begins. A positive
|
921
|
+
value is a counter-clockwise rotation, so a start angle of $\\pi / 2$ would start the arc at the top $y=r$ of the
|
922
|
+
circle.
|
923
|
+
|
924
|
+
* The sweep angle is the angle in radians that the arc covers, beginning at the starting point. A positive value is
|
925
|
+
a counter-clockwise rotation, a negative value is clockwise.
|
926
|
+
"""
|
927
|
+
|
705
928
|
def __init__(self, x: float, y: float, r: float, start_radians: float, sweep_radians: float):
|
706
929
|
"""
|
930
|
+
Create an arc from the given center point, radius, start angle, and sweep angle.
|
707
931
|
|
708
|
-
:param x:
|
709
|
-
:param y:
|
710
|
-
:param r:
|
711
|
-
:param start_radians:
|
712
|
-
|
932
|
+
:param x: the x-coordinate of the center of the arc.
|
933
|
+
:param y: the y-coordinate of the center of the arc.
|
934
|
+
:param r: the radius of the arc.
|
935
|
+
:param start_radians: the start angle of the arc in radians, which is the angle from the positive x-axis to the
|
936
|
+
starting point of the arc. A positive value is a counter-clockwise rotation.
|
937
|
+
:param sweep_radians: the sweep angle of the arc in radians, which is the angle that the arc covers, beginning
|
938
|
+
at the starting point. A positive value is a counter-clockwise rotation, a negative value is clockwise.
|
713
939
|
"""
|
714
940
|
|
715
941
|
@property
|
716
942
|
def center(self) -> Point2:
|
717
943
|
"""
|
718
|
-
Get the center of the arc.
|
944
|
+
Get the center point of the arc.
|
719
945
|
:return: the center of the arc.
|
720
946
|
"""
|
721
947
|
...
|
@@ -723,31 +949,31 @@ class Arc2:
|
|
723
949
|
@property
|
724
950
|
def x(self) -> float:
|
725
951
|
"""
|
726
|
-
Get the x-coordinate of the arc.
|
727
|
-
:return: the x-coordinate of the arc.
|
952
|
+
Get the x-coordinate of the center of the arc.
|
953
|
+
:return: the x-coordinate of the arc center.
|
728
954
|
"""
|
729
955
|
...
|
730
956
|
|
731
957
|
@property
|
732
958
|
def y(self) -> float:
|
733
959
|
"""
|
734
|
-
Get the y-coordinate of the arc.
|
735
|
-
:return: the y-coordinate of the arc
|
960
|
+
Get the y-coordinate of the center of the arc.
|
961
|
+
:return: the y-coordinate of the arc center
|
736
962
|
"""
|
737
963
|
...
|
738
964
|
|
739
965
|
@property
|
740
966
|
def r(self) -> float:
|
741
967
|
"""
|
742
|
-
Get the radius of the arc
|
743
|
-
:return: the radius of the arc
|
968
|
+
Get the radius of the arc
|
969
|
+
:return: the radius of the arc
|
744
970
|
"""
|
745
971
|
...
|
746
972
|
|
747
973
|
@property
|
748
974
|
def start(self) -> float:
|
749
975
|
"""
|
750
|
-
Get the start angle of the arc in radians.
|
976
|
+
Get the start angle of the arc, in radians.
|
751
977
|
:return: the start angle of the arc in radians.
|
752
978
|
"""
|
753
979
|
...
|
@@ -755,7 +981,7 @@ class Arc2:
|
|
755
981
|
@property
|
756
982
|
def sweep(self) -> float:
|
757
983
|
"""
|
758
|
-
Get the sweep angle of the arc in radians.
|
984
|
+
Get the sweep angle of the arc, in radians.
|
759
985
|
:return: the sweep angle of the arc in radians.
|
760
986
|
"""
|
761
987
|
...
|
@@ -786,9 +1012,21 @@ class Arc2:
|
|
786
1012
|
|
787
1013
|
|
788
1014
|
class Aabb2:
|
1015
|
+
"""
|
1016
|
+
A class representing an axis-aligned bounding box in 2D space. The bounding box is defined by a minimum point and a
|
1017
|
+
maximum point, which are the lower-left and upper-right corners of the box, respectively.
|
1018
|
+
|
1019
|
+
Bounding boxes are typically used for accelerating intersection and distance queries and are used internally inside
|
1020
|
+
the Rust language `engeom` library for this purpose. However, they have other useful applications and so are
|
1021
|
+
exposed here in the Python API.
|
1022
|
+
|
1023
|
+
Typically, `Aabb2` objects will be retrieved from other `engeom` objects which use them internally, such as curves,
|
1024
|
+
circles, arcs, etc. However, they can also be created and manipulated directly.
|
1025
|
+
"""
|
1026
|
+
|
789
1027
|
def __init__(self, x_min: float, y_min: float, x_max: float, y_max: float):
|
790
1028
|
"""
|
791
|
-
Create an axis-aligned bounding box from the
|
1029
|
+
Create an axis-aligned bounding box from the minimum and maximum coordinates.
|
792
1030
|
|
793
1031
|
:param x_min: the minimum x-coordinate of the AABB
|
794
1032
|
:param y_min: the minimum y-coordinate of the AABB
|
@@ -810,7 +1048,7 @@ class Aabb2:
|
|
810
1048
|
...
|
811
1049
|
|
812
1050
|
@staticmethod
|
813
|
-
def from_points(points:
|
1051
|
+
def from_points(points: NDArray[float]) -> Aabb2:
|
814
1052
|
"""
|
815
1053
|
Create an AABB that bounds a set of points. If the point array is empty or the wrong shape, an error will be
|
816
1054
|
thrown.
|