bspy 1.5.0__py3-none-any.whl → 2.1.0__py3-none-any.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.
- bspy/_spline_domain.py +88 -159
- bspy/_spline_evaluation.py +15 -0
- bspy/_spline_fitting.py +203 -163
- bspy/_spline_operations.py +40 -13
- bspy/spline.py +238 -96
- {bspy-1.5.0.dist-info → bspy-2.1.0.dist-info}/METADATA +4 -3
- bspy-2.1.0.dist-info/RECORD +15 -0
- {bspy-1.5.0.dist-info → bspy-2.1.0.dist-info}/WHEEL +1 -1
- bspy-1.5.0.dist-info/RECORD +0 -15
- {bspy-1.5.0.dist-info → bspy-2.1.0.dist-info}/LICENSE +0 -0
- {bspy-1.5.0.dist-info → bspy-2.1.0.dist-info}/top_level.txt +0 -0
bspy/spline.py
CHANGED
|
@@ -6,14 +6,6 @@ import bspy._spline_intersection
|
|
|
6
6
|
import bspy._spline_fitting
|
|
7
7
|
import bspy._spline_operations
|
|
8
8
|
|
|
9
|
-
def _isIterable(object):
|
|
10
|
-
result = True
|
|
11
|
-
try:
|
|
12
|
-
iterator = iter(object)
|
|
13
|
-
except TypeError:
|
|
14
|
-
result = False
|
|
15
|
-
return result
|
|
16
|
-
|
|
17
9
|
class Spline:
|
|
18
10
|
"""
|
|
19
11
|
A class to model, represent, and process piecewise polynomial tensor product
|
|
@@ -84,8 +76,8 @@ class Spline:
|
|
|
84
76
|
self.accuracy = accuracy
|
|
85
77
|
self.metadata = dict(metadata)
|
|
86
78
|
|
|
87
|
-
def __call__(self, uvw):
|
|
88
|
-
return self.evaluate(uvw)
|
|
79
|
+
def __call__(self, *uvw, **kwargs):
|
|
80
|
+
return self.evaluate(*uvw, **kwargs)
|
|
89
81
|
|
|
90
82
|
def __repr__(self):
|
|
91
83
|
return f"Spline({self.nInd}, {self.nDep}, {self.order}, " + \
|
|
@@ -94,81 +86,60 @@ class Spline:
|
|
|
94
86
|
|
|
95
87
|
def __add__(self, other):
|
|
96
88
|
if isinstance(other, Spline):
|
|
97
|
-
return self.add(other)
|
|
98
|
-
elif _isIterable(other):
|
|
99
|
-
return self.translate(other)
|
|
89
|
+
return self.add(other, [(ix, ix) for ix in range(min(self.nInd, other.nInd))])
|
|
100
90
|
else:
|
|
101
|
-
return
|
|
91
|
+
return self.translate(other)
|
|
102
92
|
|
|
103
93
|
def __radd__(self, other):
|
|
104
94
|
if isinstance(other, Spline):
|
|
105
|
-
return other.add(self)
|
|
106
|
-
elif _isIterable(other):
|
|
107
|
-
return self.translate(other)
|
|
95
|
+
return other.add(self, [(ix, ix) for ix in range(min(self.nInd, other.nInd))])
|
|
108
96
|
else:
|
|
109
|
-
return
|
|
97
|
+
return self.translate(other)
|
|
110
98
|
|
|
111
99
|
def __matmul__(self, other):
|
|
112
|
-
if
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
100
|
+
if isinstance(other, Spline):
|
|
101
|
+
return self.multiply(other, [(ix, ix) for ix in range(min(self.nInd, other.nInd))], 'D')
|
|
102
|
+
else:
|
|
103
|
+
other = np.atleast_1d(other)
|
|
104
|
+
if len(other.shape) > 1:
|
|
116
105
|
return self.transform(other.T)
|
|
117
106
|
else:
|
|
118
107
|
return self.dot(other)
|
|
119
|
-
else:
|
|
120
|
-
return NotImplemented
|
|
121
108
|
|
|
122
109
|
def __rmatmul__(self, other):
|
|
123
|
-
if
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
110
|
+
if isinstance(other, Spline):
|
|
111
|
+
return other.multiply(self, [(ix, ix) for ix in range(min(self.nInd, other.nInd))], 'D')
|
|
112
|
+
else:
|
|
113
|
+
other = np.atleast_1d(other)
|
|
114
|
+
if len(other.shape) > 1:
|
|
127
115
|
return self.transform(other)
|
|
128
116
|
else:
|
|
129
117
|
return self.dot(other)
|
|
130
|
-
else:
|
|
131
|
-
return NotImplemented
|
|
132
118
|
|
|
133
119
|
def __mul__(self, other):
|
|
134
120
|
if isinstance(other, Spline):
|
|
135
|
-
|
|
136
|
-
return self.multiply(other, None, 'S')
|
|
137
|
-
else:
|
|
138
|
-
return self.multiply(other, None, 'D')
|
|
139
|
-
elif np.isscalar(other) or _isIterable(other):
|
|
140
|
-
return self.scale(other)
|
|
121
|
+
return self.multiply(other, [(ix, ix) for ix in range(min(self.nInd, other.nInd))], 'S')
|
|
141
122
|
else:
|
|
142
|
-
return
|
|
123
|
+
return self.scale(other)
|
|
143
124
|
|
|
144
125
|
def __rmul__(self, other):
|
|
145
126
|
if isinstance(other, Spline):
|
|
146
|
-
|
|
147
|
-
return other.multiply(self, None, 'S')
|
|
148
|
-
else:
|
|
149
|
-
return other.multiply(self, None, 'D')
|
|
150
|
-
return other.multiply(self)
|
|
151
|
-
elif np.isscalar(other) or _isIterable(other):
|
|
152
|
-
return self.scale(other)
|
|
127
|
+
return other.multiply(self, [(ix, ix) for ix in range(min(self.nInd, other.nInd))], 'S')
|
|
153
128
|
else:
|
|
154
|
-
return
|
|
129
|
+
return self.scale(other)
|
|
155
130
|
|
|
156
131
|
def __sub__(self, other):
|
|
157
132
|
if isinstance(other, Spline):
|
|
158
|
-
return self.subtract(other)
|
|
159
|
-
elif _isIterable(other):
|
|
160
|
-
return self.translate(-np.array(other))
|
|
133
|
+
return self.subtract(other, [(ix, ix) for ix in range(min(self.nInd, other.nInd))])
|
|
161
134
|
else:
|
|
162
|
-
return
|
|
135
|
+
return self.translate(-np.atleast_1d(other))
|
|
163
136
|
|
|
164
137
|
def __rsub__(self, other):
|
|
165
138
|
if isinstance(other, Spline):
|
|
166
|
-
return other.subtract(self)
|
|
167
|
-
|
|
139
|
+
return other.subtract(self, [(ix, ix) for ix in range(min(self.nInd, other.nInd))])
|
|
140
|
+
else:
|
|
168
141
|
spline = self.scale(-1.0)
|
|
169
142
|
return spline.translate(other)
|
|
170
|
-
else:
|
|
171
|
-
return NotImplemented
|
|
172
143
|
|
|
173
144
|
def add(self, other, indMap = None):
|
|
174
145
|
"""
|
|
@@ -201,10 +172,12 @@ class Spline:
|
|
|
201
172
|
|
|
202
173
|
Notes
|
|
203
174
|
-----
|
|
175
|
+
Equivalent to spline1 + spline2 with indMap = range(min(spline1.nInd, spline2.nInd)).
|
|
176
|
+
|
|
204
177
|
Uses `common_basis` to ensure mapped variables share the same order and knots.
|
|
205
178
|
"""
|
|
206
179
|
if indMap is not None:
|
|
207
|
-
indMap = [mapping if
|
|
180
|
+
indMap = [(mapping, mapping) if np.isscalar(mapping) else mapping for mapping in indMap]
|
|
208
181
|
return bspy._spline_operations.add(self, other, indMap)
|
|
209
182
|
|
|
210
183
|
def blossom(self, uvw):
|
|
@@ -274,6 +247,33 @@ class Spline:
|
|
|
274
247
|
"""
|
|
275
248
|
return bspy._spline_evaluation.bspline_values(knot, knots, splineOrder, u, derivativeOrder, taylorCoefs)
|
|
276
249
|
|
|
250
|
+
@staticmethod
|
|
251
|
+
def circular_arc(radius, angle, tolerance = None):
|
|
252
|
+
"""
|
|
253
|
+
Create a 2D circular arc for a given radius and angle accurate to within a given tolerance.
|
|
254
|
+
|
|
255
|
+
Parameters
|
|
256
|
+
----------
|
|
257
|
+
radius : `float`
|
|
258
|
+
The radius of the circular arc.
|
|
259
|
+
|
|
260
|
+
angle : `float`
|
|
261
|
+
The angle of the circular arc measured in degrees starting at the x-axis rotating counterclockwise.
|
|
262
|
+
|
|
263
|
+
tolerance : `float`, optional
|
|
264
|
+
The maximum allowed error in the circular arc (default is machine epsilon).
|
|
265
|
+
|
|
266
|
+
Returns
|
|
267
|
+
-------
|
|
268
|
+
spline : `Spline`
|
|
269
|
+
A spline curve for the circular arc (domain from 0 to 1).
|
|
270
|
+
|
|
271
|
+
See Also
|
|
272
|
+
--------
|
|
273
|
+
`section` : Fit a planar section to the list of 4-tuples of data.
|
|
274
|
+
`revolve` : Rotate the spline to create a surface of revolution.
|
|
275
|
+
"""
|
|
276
|
+
return bspy._spline_fitting.circular_arc(radius, angle, tolerance)
|
|
277
277
|
|
|
278
278
|
def clamp(self, left, right):
|
|
279
279
|
"""
|
|
@@ -477,7 +477,7 @@ class Spline:
|
|
|
477
477
|
The type of product to perform on the dependent variables (default is 'S').
|
|
478
478
|
'C' is for a cross product, self x other (nDep must be 2 or 3).
|
|
479
479
|
'D' is for a dot product (nDep must match).
|
|
480
|
-
'S' is for a scalar product (nDep must be 1 for one of the splines).
|
|
480
|
+
'S' is for a scalar product (nDep must match or be 1 for one of the splines).
|
|
481
481
|
|
|
482
482
|
Returns
|
|
483
483
|
-------
|
|
@@ -495,7 +495,7 @@ class Spline:
|
|
|
495
495
|
Computer Aided Geometric Design 11, no. 6 (1994): 597-620.
|
|
496
496
|
"""
|
|
497
497
|
if indMap is not None:
|
|
498
|
-
indMap = [(
|
|
498
|
+
indMap = [(mapping, mapping, True) if np.isscalar(mapping) else (*mapping, True) for mapping in indMap]
|
|
499
499
|
return bspy._spline_operations.multiplyAndConvolve(self, other, indMap, productType)
|
|
500
500
|
|
|
501
501
|
def copy(self, metadata={}):
|
|
@@ -534,7 +534,28 @@ class Spline:
|
|
|
534
534
|
"""
|
|
535
535
|
return bspy._spline_operations.cross(self, vector)
|
|
536
536
|
|
|
537
|
-
def
|
|
537
|
+
def curvature(self, uvw):
|
|
538
|
+
"""
|
|
539
|
+
Compute the curvature of a univariate spline.
|
|
540
|
+
|
|
541
|
+
Parameters
|
|
542
|
+
----------
|
|
543
|
+
uvw : `iterable`
|
|
544
|
+
An iterable of length `nInd` that specifies the values of each independent variable (the parameter values).
|
|
545
|
+
|
|
546
|
+
Returns
|
|
547
|
+
-------
|
|
548
|
+
value : scalar
|
|
549
|
+
The value of the curvature at the given point on the curve.
|
|
550
|
+
|
|
551
|
+
Notes
|
|
552
|
+
-----
|
|
553
|
+
Computes the curvature of the graph of the function if nDep == 1. If nDep == 1 or 2,
|
|
554
|
+
then the curvature is computed as a signed quantity.
|
|
555
|
+
"""
|
|
556
|
+
return bspy._spline_evaluation.curvature(self, uvw)
|
|
557
|
+
|
|
558
|
+
def derivative(self, with_respect_to, *uvw, **kwargs):
|
|
538
559
|
"""
|
|
539
560
|
Compute the derivative of the spline at given parameter values.
|
|
540
561
|
|
|
@@ -544,13 +565,18 @@ class Spline:
|
|
|
544
565
|
An iterable of length `nInd` that specifies the integer order of derivative for each independent variable.
|
|
545
566
|
A zero-order derivative just evaluates the spline normally.
|
|
546
567
|
|
|
547
|
-
uvw : `iterable`
|
|
548
|
-
An iterable of length `nInd` that specifies the values of each independent variable (the parameter values)
|
|
568
|
+
*uvw : `iterable` or iterable of iterables
|
|
569
|
+
An iterable of length `nInd` that specifies the values of each independent variable (the parameter values), or
|
|
570
|
+
an iterable of iterables of length `nInd` that specifies values for each independent variable (numpy ufunc style).
|
|
571
|
+
|
|
572
|
+
**kwargs:
|
|
573
|
+
For other keyword-only arguments, see the `ufunc docs <https://numpy.org/doc/stable/reference/ufuncs.html#ufuncs-kwargs>`_.
|
|
549
574
|
|
|
550
575
|
Returns
|
|
551
576
|
-------
|
|
552
577
|
value : `numpy.array`
|
|
553
|
-
The value of the derivative of the spline at the given parameter values.
|
|
578
|
+
The value of the derivative of the spline at the given parameter values (array of size nDep). If multiple points are
|
|
579
|
+
passed (numpy ufunc style), then multiple arrays are returned, one for each dependent variable.
|
|
554
580
|
|
|
555
581
|
See Also
|
|
556
582
|
--------
|
|
@@ -566,7 +592,13 @@ class Spline:
|
|
|
566
592
|
evaluated, then the dot product of those B-splines with the vector of
|
|
567
593
|
B-spline coefficients is computed.
|
|
568
594
|
"""
|
|
569
|
-
|
|
595
|
+
if len(uvw) > 1 or (not np.isscalar(uvw[0]) and len(uvw[0]) > self.nInd):
|
|
596
|
+
def vectorized(*uvwInstance):
|
|
597
|
+
return tuple(bspy._spline_evaluation.derivative(self, with_respect_to, uvwInstance))
|
|
598
|
+
uFunc = np.frompyfunc(vectorized, self.nInd, self.nDep)
|
|
599
|
+
return uFunc(*uvw, **kwargs)
|
|
600
|
+
else:
|
|
601
|
+
return bspy._spline_evaluation.derivative(self, with_respect_to, *uvw)
|
|
570
602
|
|
|
571
603
|
def differentiate(self, with_respect_to = 0):
|
|
572
604
|
"""
|
|
@@ -623,6 +655,10 @@ class Spline:
|
|
|
623
655
|
See Also
|
|
624
656
|
--------
|
|
625
657
|
`multiply` : Multiply two splines (cross, dot, or scalar product).
|
|
658
|
+
|
|
659
|
+
Notes
|
|
660
|
+
-----
|
|
661
|
+
Equivalent to spline @ vector.
|
|
626
662
|
"""
|
|
627
663
|
return bspy._spline_operations.dot(self, vector)
|
|
628
664
|
|
|
@@ -685,19 +721,24 @@ class Spline:
|
|
|
685
721
|
"""
|
|
686
722
|
return bspy._spline_domain.elevate_and_insert_knots(self, m, newKnots)
|
|
687
723
|
|
|
688
|
-
def evaluate(self, uvw):
|
|
724
|
+
def evaluate(self, *uvw, **kwargs):
|
|
689
725
|
"""
|
|
690
726
|
Compute the value of the spline at given parameter values.
|
|
691
727
|
|
|
692
728
|
Parameters
|
|
693
729
|
----------
|
|
694
|
-
uvw : `iterable`
|
|
695
|
-
An iterable of length `nInd` that specifies the values of each independent variable (the parameter values)
|
|
730
|
+
*uvw : `iterable` or iterable of iterables
|
|
731
|
+
An iterable of length `nInd` that specifies the values of each independent variable (the parameter values), or
|
|
732
|
+
an iterable of iterables of length `nInd` that specifies values for each independent variable (numpy ufunc style).
|
|
733
|
+
|
|
734
|
+
**kwargs:
|
|
735
|
+
For other keyword-only arguments, see the `ufunc docs <https://numpy.org/doc/stable/reference/ufuncs.html#ufuncs-kwargs>`_.
|
|
696
736
|
|
|
697
737
|
Returns
|
|
698
738
|
-------
|
|
699
739
|
value : `numpy.array`
|
|
700
|
-
The value of the spline at the given parameter values.
|
|
740
|
+
The value of the spline at the given parameter values (array of size nDep). If multiple points are
|
|
741
|
+
passed (numpy ufunc style), then multiple arrays are returned, one for each dependent variable.
|
|
701
742
|
|
|
702
743
|
See Also
|
|
703
744
|
--------
|
|
@@ -705,12 +746,20 @@ class Spline:
|
|
|
705
746
|
|
|
706
747
|
Notes
|
|
707
748
|
-----
|
|
749
|
+
Equivalent to spline(*uvw, **kwargs).
|
|
750
|
+
|
|
708
751
|
The evaluate method uses the de Boor recurrence relations for a B-spline
|
|
709
752
|
series to evaluate a spline. The non-zero B-splines are
|
|
710
753
|
evaluated, then the dot product of those B-splines with the vector of
|
|
711
754
|
B-spline coefficients is computed.
|
|
712
755
|
"""
|
|
713
|
-
|
|
756
|
+
if len(uvw) > 1 or (not np.isscalar(uvw[0]) and len(uvw[0]) > self.nInd):
|
|
757
|
+
def vectorized(*uvwInstance):
|
|
758
|
+
return tuple(bspy._spline_evaluation.evaluate(self, uvwInstance))
|
|
759
|
+
uFunc = np.frompyfunc(vectorized, self.nInd, self.nDep)
|
|
760
|
+
return uFunc(*uvw, **kwargs)
|
|
761
|
+
else:
|
|
762
|
+
return bspy._spline_evaluation.evaluate(self, *uvw)
|
|
714
763
|
|
|
715
764
|
def extrapolate(self, newDomain, continuityOrder):
|
|
716
765
|
"""
|
|
@@ -773,6 +822,31 @@ class Spline:
|
|
|
773
822
|
"""
|
|
774
823
|
return bspy._spline_domain.fold(self, foldedInd)
|
|
775
824
|
|
|
825
|
+
def graph(self):
|
|
826
|
+
"""
|
|
827
|
+
Generate the spline which is the graph of the given spline.
|
|
828
|
+
|
|
829
|
+
Parameters
|
|
830
|
+
----------
|
|
831
|
+
|
|
832
|
+
Returns
|
|
833
|
+
-------
|
|
834
|
+
Given a spline with n independent variables and m dependent variables, generate a new
|
|
835
|
+
spline with n independent variables which has n + m dependent variables, the first n of
|
|
836
|
+
which are just the independent variables themselves. For example, given a scalar
|
|
837
|
+
valued function f of two variables u and v, return the spline of two variables whose
|
|
838
|
+
three dependent variables are (u, v, f(u,v)).
|
|
839
|
+
|
|
840
|
+
See Also
|
|
841
|
+
--------
|
|
842
|
+
`add` : Add two splines together
|
|
843
|
+
|
|
844
|
+
Notes
|
|
845
|
+
-----
|
|
846
|
+
Makes use of matrix spline multiply and tensor product addition for splines.
|
|
847
|
+
"""
|
|
848
|
+
return bspy._spline_operations.graph(self)
|
|
849
|
+
|
|
776
850
|
def insert_knots(self, newKnots):
|
|
777
851
|
"""
|
|
778
852
|
Insert new knots into a spline.
|
|
@@ -893,9 +967,9 @@ class Spline:
|
|
|
893
967
|
if not(self.nDep == other.nDep): raise ValueError("The number of dependent variables for both splines much match.")
|
|
894
968
|
freeParameters = self.nInd + other.nInd - self.nDep
|
|
895
969
|
if freeParameters == 0:
|
|
896
|
-
return (
|
|
970
|
+
return self.subtract(other).zeros()
|
|
897
971
|
elif freeParameters == 1:
|
|
898
|
-
return (
|
|
972
|
+
return self.subtract(other).contours()
|
|
899
973
|
else:
|
|
900
974
|
return NotImplemented
|
|
901
975
|
|
|
@@ -1061,7 +1135,7 @@ class Spline:
|
|
|
1061
1135
|
The type of product to perform on the dependent variables (default is 'S').
|
|
1062
1136
|
'C' is for a cross product, self x other (nDep must be 2 or 3).
|
|
1063
1137
|
'D' is for a dot product (nDep must match).
|
|
1064
|
-
'S' is for a scalar product (nDep must be 1 for one of the splines).
|
|
1138
|
+
'S' is for a scalar product (nDep must match or be 1 for one of the splines).
|
|
1065
1139
|
|
|
1066
1140
|
Returns
|
|
1067
1141
|
-------
|
|
@@ -1076,11 +1150,13 @@ class Spline:
|
|
|
1076
1150
|
|
|
1077
1151
|
Notes
|
|
1078
1152
|
-----
|
|
1153
|
+
Equivalent to spline1 * spline2 with indMap = range(min(spline1.nInd, spline2.nInd)) and productType = 'S'.
|
|
1154
|
+
|
|
1079
1155
|
Taken in part from Lee, E. T. Y. "Computing a chain of blossoms, with application to products of splines."
|
|
1080
1156
|
Computer Aided Geometric Design 11, no. 6 (1994): 597-620.
|
|
1081
1157
|
"""
|
|
1082
1158
|
if indMap is not None:
|
|
1083
|
-
indMap = [(
|
|
1159
|
+
indMap = [(mapping, mapping, False) if np.isscalar(mapping) else (*mapping, False) for mapping in indMap]
|
|
1084
1160
|
return bspy._spline_operations.multiplyAndConvolve(self, other, indMap, productType)
|
|
1085
1161
|
|
|
1086
1162
|
def normal(self, uvw, normalize=True, indices=None):
|
|
@@ -1156,49 +1232,60 @@ class Spline:
|
|
|
1156
1232
|
"""
|
|
1157
1233
|
return bspy._spline_evaluation.range_bounds(self)
|
|
1158
1234
|
|
|
1159
|
-
def
|
|
1235
|
+
def remove_knot(self, iKnot):
|
|
1160
1236
|
"""
|
|
1161
|
-
Remove
|
|
1162
|
-
|
|
1237
|
+
Remove a single knot from a univariate spline.
|
|
1238
|
+
|
|
1163
1239
|
Parameters
|
|
1164
1240
|
----------
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1241
|
+
iKnot : integer
|
|
1242
|
+
index of the knot to remove from the spline
|
|
1243
|
+
|
|
1244
|
+
Returns
|
|
1245
|
+
-------
|
|
1246
|
+
spline : `Spline`
|
|
1247
|
+
New spline with the specified knot removed
|
|
1248
|
+
residual : array-like
|
|
1249
|
+
A vector containing the least squares residuals for each dependent variable
|
|
1169
1250
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
which is the default.)
|
|
1251
|
+
See Also
|
|
1252
|
+
--------
|
|
1253
|
+
`remove_knots`
|
|
1174
1254
|
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1255
|
+
Notes
|
|
1256
|
+
-----
|
|
1257
|
+
Solves a simple least squares problem
|
|
1258
|
+
"""
|
|
1259
|
+
return bspy._spline_domain.remove_knot(self, iKnot)
|
|
1260
|
+
|
|
1261
|
+
def remove_knots(self, tolerance = 1.0e-14):
|
|
1262
|
+
"""
|
|
1263
|
+
Remove interior knots from a spline.
|
|
1264
|
+
|
|
1265
|
+
Parameters
|
|
1266
|
+
----------
|
|
1267
|
+
tolerance : `float`, optional
|
|
1268
|
+
The maximum pointwise relative error permitted after removing all the knots. Knots will be
|
|
1269
|
+
removed until removal of the next knot would put the pointwise error above the threshold.
|
|
1270
|
+
The default is 1.0e-14 which is relative to the size of each of the dependent variables.
|
|
1179
1271
|
|
|
1180
1272
|
Returns
|
|
1181
1273
|
-------
|
|
1182
1274
|
spline : `Spline`
|
|
1183
1275
|
A spline with the knots removed.
|
|
1184
|
-
|
|
1185
|
-
totalRemoved : `int`
|
|
1186
|
-
The total number of knots removed.
|
|
1187
|
-
|
|
1188
|
-
residualError : `float`
|
|
1189
|
-
The residual error relative to the old spline. (The returned spline's accuracy is also adjusted accordingly.)
|
|
1190
1276
|
|
|
1191
1277
|
See Also
|
|
1192
1278
|
--------
|
|
1193
1279
|
`insert_knots` : Insert new knots into a spline.
|
|
1280
|
+
`remove_knot` : Remove an indicated knot from a spline.
|
|
1194
1281
|
`trim` : Trim the domain of a spline.
|
|
1195
1282
|
|
|
1196
1283
|
Notes
|
|
1197
1284
|
-----
|
|
1198
|
-
|
|
1285
|
+
Calls `remove_knot` repeatedly until no longer possible.
|
|
1199
1286
|
"""
|
|
1200
|
-
return bspy._spline_domain.remove_knots(self,
|
|
1201
|
-
|
|
1287
|
+
return bspy._spline_domain.remove_knots(self, tolerance)
|
|
1288
|
+
|
|
1202
1289
|
def reparametrize(self, newDomain):
|
|
1203
1290
|
"""
|
|
1204
1291
|
Reparametrize a spline to match new domain bounds. The spline's number of knots and its coefficients remain unchanged.
|
|
@@ -1241,9 +1328,46 @@ class Spline:
|
|
|
1241
1328
|
"""
|
|
1242
1329
|
return bspy._spline_domain.reverse(self, variable)
|
|
1243
1330
|
|
|
1331
|
+
def revolve(self, angle):
|
|
1332
|
+
"""
|
|
1333
|
+
Rotate the spline to create a surface of revolution (nDep must equal 2,
|
|
1334
|
+
first dimension provides the radius for x and y, second dimension provides the z).
|
|
1335
|
+
|
|
1336
|
+
Parameters
|
|
1337
|
+
----------
|
|
1338
|
+
angle : `float`
|
|
1339
|
+
The angle of the circular arc measured in degrees starting at the x-axis rotating counterclockwise.
|
|
1340
|
+
|
|
1341
|
+
Returns
|
|
1342
|
+
-------
|
|
1343
|
+
spline : `Spline`
|
|
1344
|
+
Surface of revolution (first independent variable sweeps the arc from 0 to 1).
|
|
1345
|
+
|
|
1346
|
+
See Also
|
|
1347
|
+
--------
|
|
1348
|
+
`circular_arc` : Create a 2D circular arc for a given radius and angle accurate to within a given tolerance.
|
|
1349
|
+
"""
|
|
1350
|
+
return bspy._spline_fitting.revolve(self, angle)
|
|
1351
|
+
|
|
1244
1352
|
@staticmethod
|
|
1245
1353
|
def ruled_surface(spline1, spline2):
|
|
1246
|
-
|
|
1354
|
+
"""
|
|
1355
|
+
Create a ruled surface between two splines.
|
|
1356
|
+
|
|
1357
|
+
Parameters
|
|
1358
|
+
----------
|
|
1359
|
+
spline1 : `Spline`
|
|
1360
|
+
The first spline (must have the same nInd and nDep as the second spline).
|
|
1361
|
+
|
|
1362
|
+
spline2 : `Spline`
|
|
1363
|
+
The second spline (must have the same nInd and nDep as the first spline).
|
|
1364
|
+
|
|
1365
|
+
Returns
|
|
1366
|
+
-------
|
|
1367
|
+
spline : `Spline`
|
|
1368
|
+
Ruled surface between spline1 and spline2.
|
|
1369
|
+
"""
|
|
1370
|
+
return bspy._spline_fitting.ruled_surface(spline1, spline2)
|
|
1247
1371
|
|
|
1248
1372
|
def save(self, fileName):
|
|
1249
1373
|
"""
|
|
@@ -1288,6 +1412,10 @@ class Spline:
|
|
|
1288
1412
|
`multiply` : Multiply two splines (cross, dot, or scalar product).
|
|
1289
1413
|
`transform` : Transform a spline by the given matrix.
|
|
1290
1414
|
`translate` : Translate a spline by the given translation vector.
|
|
1415
|
+
|
|
1416
|
+
Notes
|
|
1417
|
+
-----
|
|
1418
|
+
Equivalent to spline * multiplier.
|
|
1291
1419
|
"""
|
|
1292
1420
|
return bspy._spline_operations.scale(self, multiplier)
|
|
1293
1421
|
|
|
@@ -1316,6 +1444,10 @@ class Spline:
|
|
|
1316
1444
|
consecutive data points without passing through an intermediate inflection point (i.e. a point which
|
|
1317
1445
|
has zero curvature and at which the sign of the curvature changes), then this method will fail
|
|
1318
1446
|
with an error.
|
|
1447
|
+
|
|
1448
|
+
See Also
|
|
1449
|
+
--------
|
|
1450
|
+
`circular_arc` : Create a 2D circular arc for a given radius and angle accurate to within a given tolerance.
|
|
1319
1451
|
"""
|
|
1320
1452
|
return bspy._spline_fitting.section(xytk)
|
|
1321
1453
|
|
|
@@ -1350,10 +1482,12 @@ class Spline:
|
|
|
1350
1482
|
|
|
1351
1483
|
Notes
|
|
1352
1484
|
-----
|
|
1485
|
+
Equivalent to spline1 - spline2 with indMap = range(min(spline1.nInd, spline2.nInd)).
|
|
1486
|
+
|
|
1353
1487
|
Uses `common_basis` to ensure mapped variables share the same order and knots.
|
|
1354
1488
|
"""
|
|
1355
1489
|
if indMap is not None:
|
|
1356
|
-
indMap = [mapping if
|
|
1490
|
+
indMap = [(mapping, mapping) if np.isscalar(mapping) else mapping for mapping in indMap]
|
|
1357
1491
|
return self.add(other.scale(-1.0), indMap)
|
|
1358
1492
|
|
|
1359
1493
|
def transform(self, matrix, maxSingularValue=None):
|
|
@@ -1378,6 +1512,10 @@ class Spline:
|
|
|
1378
1512
|
--------
|
|
1379
1513
|
`scale` : Scale a spline by the given scalar or scale vector.
|
|
1380
1514
|
`translate` : Translate a spline by the given translation vector.
|
|
1515
|
+
|
|
1516
|
+
Notes
|
|
1517
|
+
-----
|
|
1518
|
+
Equivalent to spline @ matrix.
|
|
1381
1519
|
"""
|
|
1382
1520
|
return bspy._spline_operations.transform(self, matrix, maxSingularValue)
|
|
1383
1521
|
|
|
@@ -1399,6 +1537,10 @@ class Spline:
|
|
|
1399
1537
|
--------
|
|
1400
1538
|
`scale` : Scale a spline by the given scalar or scale vector.
|
|
1401
1539
|
`transform` : Transform a spline by the given matrix.
|
|
1540
|
+
|
|
1541
|
+
Notes
|
|
1542
|
+
-----
|
|
1543
|
+
Equivalent to spline + translationVector.
|
|
1402
1544
|
"""
|
|
1403
1545
|
return bspy._spline_operations.translate(self, translationVector)
|
|
1404
1546
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bspy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Library for manipulating and rendering non-uniform b-splines
|
|
5
5
|
Home-page: http://github.com/ericbrec/bspy
|
|
6
6
|
Author: Eric Brechner
|
|
@@ -33,8 +33,9 @@ Requires-Dist: pyopengltk
|
|
|
33
33
|
Library for manipulating and rendering b-spline curves, surfaces, and multidimensional manifolds with non-uniform knots in each dimension.
|
|
34
34
|
|
|
35
35
|
The [Spline](https://ericbrec.github.io/bspy/bspy/spline.html) class has a method to fit multidimensional data for
|
|
36
|
-
scalar and vector functions of single and multiple variables.
|
|
37
|
-
|
|
36
|
+
scalar and vector functions of single and multiple variables. It also has methods to create circular arcs, ruled surfaces, and surfaces of revolution.
|
|
37
|
+
Other methods add, subtract, multiply, and linearly transform splines, as well as confine spline curves to a given range.
|
|
38
|
+
There are methods to evaluate spline values, derivatives, integrals, normals, curvature, and the Jacobian, as well as methods that return spline representations of derivatives, normals, integrals, graphs, and convolutions. In addition, there are methods to manipulate the domain of splines, including trim, join, reparametrize, reverse, add and remove knots, elevate and extrapolate, and fold and unfold. Finally, there are methods to compute the zeros and contours of a spline and to intersect two splines.
|
|
38
39
|
|
|
39
40
|
The [SplineOpenGLFrame](https://ericbrec.github.io/bspy/bspy/splineOpenGLFrame.html) class is an
|
|
40
41
|
[OpenGLFrame](https://pypi.org/project/pyopengltk/) with custom shaders to render spline curves and surfaces.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
bspy/__init__.py,sha256=XRBelbYtbhB6AWKh8DTsWVMDIteVxUm7Cf_S1fkqeEs,851
|
|
2
|
+
bspy/_spline_domain.py,sha256=XDctoM5Gd9KF5OhMb2eaZ6oAk4MSecCTdDqc9qX6BRE,28333
|
|
3
|
+
bspy/_spline_evaluation.py,sha256=1aCf4Op5zQNv-_wW2IOR13MieuYPVJrN1cJCBiI8AaY,7534
|
|
4
|
+
bspy/_spline_fitting.py,sha256=oPaP0kcaBUQK3T6eHPFys9rpfhkWccr8TQDPQi7Egb8,25993
|
|
5
|
+
bspy/_spline_intersection.py,sha256=gWs22hfIKqD6YZaeFWJO_3t0ohCNzVvxdiWJqVNlJMI,40934
|
|
6
|
+
bspy/_spline_operations.py,sha256=yWzOH0new78rE_movBVX2k-ais7It8t7wml6naCgcH4,42420
|
|
7
|
+
bspy/bspyApp.py,sha256=UxmNp_IGaG7gMVexUmA7YfuwX5iuMBr7ibW3DRan8R8,14524
|
|
8
|
+
bspy/drawableSpline.py,sha256=Ha7wh__aRTpGTr3cEDG49SeAyRrKtfMUQYkEZ3w9OJw,17004
|
|
9
|
+
bspy/spline.py,sha256=sfiYGRCP1h8rgnlHHaIYckVZ56-mRGnGpq4KdUC9qYs,69575
|
|
10
|
+
bspy/splineOpenGLFrame.py,sha256=77rikAbAood76cf5w1Idj7wciTwPV-Bn-yGSuRFvlJM,60616
|
|
11
|
+
bspy-2.1.0.dist-info/LICENSE,sha256=nLfJULN68Jw6GfCJp4xeMksGuRdyWNdgEsZGjw2twig,1091
|
|
12
|
+
bspy-2.1.0.dist-info/METADATA,sha256=V1uTS820oScmbcDcIsJgYpGz_i6iVQShCGDWZAfceWM,3963
|
|
13
|
+
bspy-2.1.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
14
|
+
bspy-2.1.0.dist-info/top_level.txt,sha256=fotZnJn6aCwgUbBEV3hslIko7Nw-eqtHLq2eyJLlFsY,5
|
|
15
|
+
bspy-2.1.0.dist-info/RECORD,,
|
bspy-1.5.0.dist-info/RECORD
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
bspy/__init__.py,sha256=XRBelbYtbhB6AWKh8DTsWVMDIteVxUm7Cf_S1fkqeEs,851
|
|
2
|
-
bspy/_spline_domain.py,sha256=Fr7j6jTMAO22kL5ddVhfUdtbWHGDnpJ0q6s7HUGQ8GY,31078
|
|
3
|
-
bspy/_spline_evaluation.py,sha256=6QqV59jHM-uJwtKaRxbBCRsJNqSNsHSibnloNCcnqfc,7059
|
|
4
|
-
bspy/_spline_fitting.py,sha256=Q8IORwt-O8wCobmwupUMer5XcL66bn-b_kmxaXkJcAY,25303
|
|
5
|
-
bspy/_spline_intersection.py,sha256=gWs22hfIKqD6YZaeFWJO_3t0ohCNzVvxdiWJqVNlJMI,40934
|
|
6
|
-
bspy/_spline_operations.py,sha256=tmI8c6pN9MHzJBATGCVaXitmM4VjbGy1E0cD3-DgUzc,40879
|
|
7
|
-
bspy/bspyApp.py,sha256=UxmNp_IGaG7gMVexUmA7YfuwX5iuMBr7ibW3DRan8R8,14524
|
|
8
|
-
bspy/drawableSpline.py,sha256=Ha7wh__aRTpGTr3cEDG49SeAyRrKtfMUQYkEZ3w9OJw,17004
|
|
9
|
-
bspy/spline.py,sha256=qGu_ST93T1tSVxmYGLOegIQrOAz901X0VaggWwXQ-WA,64031
|
|
10
|
-
bspy/splineOpenGLFrame.py,sha256=77rikAbAood76cf5w1Idj7wciTwPV-Bn-yGSuRFvlJM,60616
|
|
11
|
-
bspy-1.5.0.dist-info/LICENSE,sha256=nLfJULN68Jw6GfCJp4xeMksGuRdyWNdgEsZGjw2twig,1091
|
|
12
|
-
bspy-1.5.0.dist-info/METADATA,sha256=SSeypwrd437pW4rS68JaCTs29hksspplZ5by-Y8ziZU,3853
|
|
13
|
-
bspy-1.5.0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
14
|
-
bspy-1.5.0.dist-info/top_level.txt,sha256=fotZnJn6aCwgUbBEV3hslIko7Nw-eqtHLq2eyJLlFsY,5
|
|
15
|
-
bspy-1.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|