bezier.hazmat.helpers module¶
Pure Python generic geometry and floating point helpers.
-
bezier.hazmat.helpers.vector_close(vec1, vec2, eps=9.094947017729282e-13)¶ Checks that two vectors are equal to some threshold.
Does so by computing \(s_1 = \|v_1\|_2\) and \(s_2 = \|v_2\|_2\) and then checking if
\[\|v_1 - v_2\|_2 \leq \varepsilon \min(s_1, s_2)\]where \(\varepsilon = 2^{-40} \approx 10^{-12}\) is a fixed threshold. In the rare case that one of
vec1orvec2is the zero vector (i.e. when \(\min(s_1, s_2) = 0\)) instead checks that the other vector is close enough to zero:\[\|v_1\|_2 = 0 \Longrightarrow \|v_2\|_2 \leq \varepsilon\]Note
This function assumes that both vectors have finite values, i.e. that no NaN or infinite numbers occur. NumPy provides
numpy.allclose()for coverage of all cases.Note
There is also a Fortran implementation of this function, which will be used if it can be built.
Parameters: - vec1 (numpy.ndarray) – First vector (1D) for comparison.
- vec2 (numpy.ndarray) – Second vector (1D) for comparison.
- eps (float) – Error threshold. Defaults to \(2^{-40}\).
Returns: Flag indicating if they are close to precision.
Return type:
-
bezier.hazmat.helpers.in_interval(value, start, end)¶ Checks if a
valueis an interval (inclusive).Note
The current implementation does the most basic check, however, in the future, a more generic check may be desired that allows wiggle room around the endpoints to account for round-off.
Note
There is also a Fortran implementation of this function, which will be used if it can be built.
Parameters: Returns: Indicating if the value is in the interval.
Return type:
-
bezier.hazmat.helpers.bbox(nodes)¶ Get the bounding box for set of points.
Note
There is also a Fortran implementation of this function, which will be used if it can be built.
Parameters: nodes (numpy.ndarray) – A set of points. Returns: The left, right, bottom and top bounds for the box. Return type: Tuple[float,float,float,float]
-
bezier.hazmat.helpers.contains_nd(nodes, point)¶ Predicate indicating if a point is within a bounding box.
Note
There is also a Fortran implementation of this function, which will be used if it can be built.
Parameters: - nodes (numpy.ndarray) – A set of points.
- point (numpy.ndarray) – A 1D NumPy array representing a point
in the same dimension as
nodes.
Returns: Indicating containment.
Return type:
-
bezier.hazmat.helpers.cross_product(vec0, vec1)¶ Compute the cross product of vectors in \(\mathbf{R}^2\).
Utilizes the fact that
\[\begin{split}\left[\begin{array}{c} A \\ B \\ 0 \end{array}\right] \times \left[\begin{array}{c} C \\ D \\ 0 \end{array}\right] = \left[\begin{array}{c} 0 \\ 0 \\ AD - BC \end{array}\right]\end{split}\]and just returns the \(z\) component.
Note
There is also a Fortran implementation of this function, which will be used if it can be built.
Parameters: - vec0 (numpy.ndarray) – A vector as a 1D NumPy array with two values.
- vec1 (numpy.ndarray) – A vector as a 1D NumPy array with two values.
Returns: The cross product (or rather, its \(z\) component).
Return type:
-
bezier.hazmat.helpers.matrix_product(mat1, mat2)¶ Compute the product of two Fortran contiguous matrices.
This is to avoid the overhead of NumPy converting to C-contiguous before computing a matrix product.
Does so via
A B = (B^T A^T)^TsinceB^TandA^Twill be C-contiguous without a copy, then the productP = B^T A^Twill be C-contiguous and we can return the viewP^Twithout a copy.Parameters: - mat1 (numpy.ndarray) – The left-hand side matrix.
- mat2 (numpy.ndarray) – The right-hand side matrix.
Returns: The product of the two matrices.
Return type:
-
bezier.hazmat.helpers.wiggle_interval(value, wiggle=5.684341886080802e-14)¶ Check if
valueis in \(\left[0, 1\right]\).Allows a little bit of wiggle room outside the interval. A value within
wiggleof0.0will be converted to0.0and similar for1.0.Note
There is also a Fortran implementation of this function, which will be used if it can be built.
Parameters: Returns: Pair of
- The
valueif it’s in the interval, or0.0or1.0if the value lies slightly outside. If thevalueis too far outside the unit interval, will be NaN. - Boolean indicating if the
valueis inside the unit interval.
Return type: - The
-
bezier.hazmat.helpers.cross_product_compare(start, candidate1, candidate2)¶ Compare two relative changes by their cross-product.
This is meant to be a way to determine which vector is more “inside” relative to
start.Note
This is a helper for
simple_convex_hull().Parameters: - start (numpy.ndarray) – The start vector (as 1D NumPy array with 2 elements).
- candidate1 (numpy.ndarray) – The first candidate vector (as 1D NumPy array with 2 elements).
- candidate2 (numpy.ndarray) – The second candidate vector (as 1D NumPy array with 2 elements).
Returns: The cross product of the two differences.
Return type:
-
bezier.hazmat.helpers.in_sorted(values, value)¶ Checks if a value is in a sorted list.
Uses the
bisectbuiltin to find the insertion point forvalue.Parameters: Returns: Indicating if the value is contained.
Return type:
-
bezier.hazmat.helpers.simple_convex_hull(points)¶ Compute the convex hull for a set of points.
This uses Andrew’s monotone chain convex hull algorithm and this code used a wikibooks implementation as motivation. The code there is licensed CC BY-SA 3.0.
Note
There is also a Fortran implementation of this function, which will be used if it can be built. Note that
scipy.spatial.ConvexHullcan do this as well (via Qhull), but that would require a hard dependency onscipyand that helper computes much more than we need.Note
This computes the convex hull in a “naive” way. It’s expected that internal callers of this function will have a small number of points so
n log nvs.n^2vs.naren’t that relevant.Parameters: points (numpy.ndarray) – A 2 x Narray (float64) of points.Returns: The 2 x Narray (float64) of ordered points in the polygonal convex hull.Return type: numpy.ndarray
-
bezier.hazmat.helpers.is_separating(direction, polygon1, polygon2)¶ Checks if a given
directionis a separating line for two polygons.Note
This is a helper for
polygon_collide().Parameters: - direction (numpy.ndarray) – A 1D
2-array (float64) of a potential separating line for the two polygons. - polygon1 (numpy.ndarray) – A
2 x Narray (float64) of ordered points in a polygon. - polygon2 (numpy.ndarray) – A
2 x Narray (float64) of ordered points in a polygon.
Returns: Flag indicating if
directionis a separating line.Return type: - direction (numpy.ndarray) – A 1D
-
bezier.hazmat.helpers.polygon_collide(polygon1, polygon2)¶ Determines if two convex polygons collide.
This code uses the Separating axis theorem (SAT) to quickly determine if the polygons intersect. See also.
Note
There is also a Fortran implementation of this function, which will be used if it can be built.
Parameters: - polygon1 (numpy.ndarray) – A
2 x Narray (float64) of ordered points in a polygon. - polygon2 (numpy.ndarray) – A
2 x Narray (float64) of ordered points in a polygon.
Returns: Flag indicating if the two polygons collide.
Return type: - polygon1 (numpy.ndarray) – A
-
bezier.hazmat.helpers.solve2x2(lhs, rhs)¶ Solve a square 2 x 2 system via LU factorization.
This is meant to be a stand-in for LAPACK’s
dgesv, which just wraps two calls todgetrfanddgetrs. We wrap for two reasons:- We seek to avoid exceptions as part of the control flow (which is
what
numpy.linalg.solve()does). - We seek to avoid excessive type- and size-checking, since this special case is already known.
Parameters: - lhs (numpy.ndarray) – A
2 x 2array of real numbers. - rhs (numpy.ndarray) – A 1D array of 2 real numbers.
Returns: A triple of
- A flag indicating if
lhsis a singular matrix. - The first component of the solution.
- The second component of the solution.
Return type: - We seek to avoid exceptions as part of the control flow (which is
what
-
exception
bezier.hazmat.helpers.UnsupportedDegree(degree, supported=())¶ Bases:
NotImplementedErrorCustom exception to indicate the given degree is unsupported.
This is intentionally a subclass of a
NotImplementedErrorsince it’s intended to indicate a lack of an implementation. For example,Curve.reduce_()uses hard-coded matrices for a small subset of possible degrees, so the implementation is degree-specific:>>> degree = 5 >>> nodes = np.empty((2, degree + 1), order="F") >>> curve = bezier.Curve(nodes, degree=degree) >>> curve.reduce_() Traceback (most recent call last): ... bezier.hazmat.helpers.UnsupportedDegree: The only degrees supported at this time are 1, 2, 3 and 4 (degree=5)
Parameters: -
args¶
-
with_traceback()¶ Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
-