bspy 1.2.3__py3-none-any.whl → 1.2.4__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.
@@ -218,8 +218,9 @@ def _refine_projected_polyhedron(interval):
218
218
  # No roots in this interval.
219
219
  return root, intervals
220
220
  scale = max(scale, abs(coefsMin), abs(coefsMax))
221
-
222
- if scale < epsilon:
221
+ newScale = scale * interval.scale
222
+
223
+ if newScale < evaluationEpsilon:
223
224
  # Return the bounds of the interval within which the spline is zero.
224
225
  root = (interval.intercept, interval.slope + interval.intercept)
225
226
  else:
@@ -265,7 +266,6 @@ def _refine_projected_polyhedron(interval):
265
266
  domain.append(xInterval)
266
267
 
267
268
  if domain is not None:
268
- newScale = scale * interval.scale
269
269
  domain = np.array(domain).T
270
270
  width = domain[1] - domain[0]
271
271
  newSlope = np.multiply(width, interval.slope)
@@ -273,10 +273,9 @@ def _refine_projected_polyhedron(interval):
273
273
  # one iteration past being less than sqrt(machineEpsilon) or simply less than epsilon.
274
274
  if interval.atMachineEpsilon or newSlope.max() < epsilon:
275
275
  newIntercept = np.multiply(domain[0], interval.slope) + interval.intercept
276
- root = newIntercept + 0.5 * newSlope
277
276
  # Double-check that we're at an actual zero (avoids boundary case).
278
- if newScale * np.linalg.norm(spline(0.5 * (domain[0] + domain[1]))) >= evaluationEpsilon:
279
- root = None
277
+ if newScale * np.linalg.norm(spline(0.5 * (domain[0] + domain[1]))) < evaluationEpsilon:
278
+ root = (newIntercept, newIntercept + newSlope)
280
279
  else:
281
280
  # Split domain in dimensions that aren't decreasing in width sufficiently.
282
281
  domains = [domain]
@@ -299,7 +298,10 @@ def _refine_projected_polyhedron(interval):
299
298
  newIntercept = np.multiply(domain[0], interval.slope) + interval.intercept
300
299
  for i, w in zip(range(spline.nInd), width):
301
300
  if w < machineEpsilon:
302
- domain[1, i] = domain[0, i] + machineEpsilon
301
+ if domain[0, i] > machineEpsilon:
302
+ domain[0, i] = domain[1, i] - machineEpsilon
303
+ else:
304
+ domain[1, i] = domain[0, i] + machineEpsilon
303
305
  newDomain = [None if s < epsilon else (0.0, 1.0) for s in newSlope]
304
306
  intervals.append(Interval(spline.trim(domain.T).reparametrize(newDomain), newScale, newSlope, newIntercept, epsilon, np.dot(newSlope, newSlope) < machineEpsilon))
305
307
 
@@ -333,25 +335,48 @@ def zeros_using_projected_polyhedron(self, epsilon=None):
333
335
  nextIntervals += newIntervals
334
336
  intervals = nextIntervals
335
337
 
336
- # Check for duplicate roots. We test for a distance between roots of 2*epsilon to account for a left vs. right sided limit.
337
- i = 0
338
- rootCount = len(roots)
339
- while i < rootCount:
340
- root = roots[i]
341
- j = i + 1
342
- while j < rootCount:
343
- if np.linalg.norm(root - roots[j]) < 2.0 * epsilon:
344
- # For a duplicate root, return the average value.
345
- roots[i] = 0.5 * (root + roots[j])
346
- roots.pop(j)
347
- rootCount -= 1
348
- else:
349
- j += 1
350
- i += 1
338
+ # Connect intervals of zeros that overlap.
339
+ gotOverlap = True
340
+ while gotOverlap:
341
+ gotOverlap = False
342
+ i = 0
343
+ rootCount = len(roots)
344
+ while i < rootCount:
345
+ iRoot = roots[i]
346
+ root = (iRoot[0].copy(), iRoot[1].copy()) # Temporary storage for expanded interval
347
+ j = i + 1
348
+ # Check for overlap with other intervals.
349
+ while j < rootCount:
350
+ jRoot = roots[j]
351
+ overlapped = True
352
+ for d in range(self.nInd):
353
+ if iRoot[0][d] < jRoot[1][d] + epsilon and jRoot[0][d] < iRoot[1][d] + epsilon:
354
+ root[0][d] = min(iRoot[0][d], jRoot[0][d])
355
+ root[1][d] = max(iRoot[1][d], jRoot[1][d])
356
+ else:
357
+ overlapped = False
358
+ break
359
+ if overlapped:
360
+ # For an overlapped interval, expand original interval and toss overlapping interval.
361
+ iRoot[0][:] = root[0]
362
+ iRoot[1][:] = root[1]
363
+ roots.pop(j)
364
+ rootCount -= 1
365
+ gotOverlap = True
366
+ else:
367
+ j += 1
368
+ i += 1
369
+
370
+ # Collapse intervals to points as appropriate.
371
+ for i in range(len(roots)):
372
+ iRoot = roots[i]
373
+ # If interval is small, just return a single value (not an interval).
374
+ if True: # Skip small interval test, since it's typically a shallow point, not a flat section. np.linalg.norm(iRoot[1] - iRoot[0]) < 2.0 * epsilon:
375
+ roots[i] = 0.5 * (iRoot[0] + iRoot[1])
351
376
 
352
377
  # Sort roots if there's only one dimension.
353
378
  if self.nInd == 1:
354
- roots.sort(key=lambda root: root[0] if type(root) is tuple else root)
379
+ roots.sort(key=lambda root: root[0] if isinstance(root, tuple) else root)
355
380
 
356
381
  return roots
357
382
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bspy
3
- Version: 1.2.3
3
+ Version: 1.2.4
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
@@ -2,14 +2,14 @@ bspy/__init__.py,sha256=XRBelbYtbhB6AWKh8DTsWVMDIteVxUm7Cf_S1fkqeEs,851
2
2
  bspy/_spline_domain.py,sha256=29_Mp0bn9_8z4ltu__DG9_NZuCiSuol0tRgAeIuzXZI,27826
3
3
  bspy/_spline_evaluation.py,sha256=i0qPy6UNe1MeoCOxF5LjTtloP6HUnxtxPHseAUAlmJU,6376
4
4
  bspy/_spline_fitting.py,sha256=NKNUfHfHYkQLlK_4i5oF7MIS59wrCqVKkPXHDcDGwIc,20552
5
- bspy/_spline_intersection.py,sha256=olDQpLohlF6DhNshMY0kriitlypXHNVXPcMcY3NUnGs,33110
5
+ bspy/_spline_intersection.py,sha256=Pe_TiVHB8gVjZ74gFgHeg0tfn7DhYLEMpPx-bfGcP6A,34402
6
6
  bspy/_spline_operations.py,sha256=8VIVLGgYln7lLplgVBpnMVHMWbjigvir-LHE8tusZ-A,35715
7
7
  bspy/bspyApp.py,sha256=UxmNp_IGaG7gMVexUmA7YfuwX5iuMBr7ibW3DRan8R8,14524
8
8
  bspy/drawableSpline.py,sha256=Ha7wh__aRTpGTr3cEDG49SeAyRrKtfMUQYkEZ3w9OJw,17004
9
9
  bspy/spline.py,sha256=WIPhSQu09laxQdtjpp4XDO8RscYRin4hF8ERVHLeE1o,59087
10
10
  bspy/splineOpenGLFrame.py,sha256=77rikAbAood76cf5w1Idj7wciTwPV-Bn-yGSuRFvlJM,60616
11
- bspy-1.2.3.dist-info/LICENSE,sha256=nLfJULN68Jw6GfCJp4xeMksGuRdyWNdgEsZGjw2twig,1091
12
- bspy-1.2.3.dist-info/METADATA,sha256=uEuJAnmqnP85Zs8qInKp4JzRYPo_GTp7OJ08bisn9No,3777
13
- bspy-1.2.3.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92
14
- bspy-1.2.3.dist-info/top_level.txt,sha256=fotZnJn6aCwgUbBEV3hslIko7Nw-eqtHLq2eyJLlFsY,5
15
- bspy-1.2.3.dist-info/RECORD,,
11
+ bspy-1.2.4.dist-info/LICENSE,sha256=nLfJULN68Jw6GfCJp4xeMksGuRdyWNdgEsZGjw2twig,1091
12
+ bspy-1.2.4.dist-info/METADATA,sha256=Lms9vTCdZnxc4xPJJ4Aya4c5brPr-tpK3Vs3QWlj8m0,3777
13
+ bspy-1.2.4.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
14
+ bspy-1.2.4.dist-info/top_level.txt,sha256=fotZnJn6aCwgUbBEV3hslIko7Nw-eqtHLq2eyJLlFsY,5
15
+ bspy-1.2.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.1)
2
+ Generator: bdist_wheel (0.41.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
File without changes