Skip to content

Commit

Permalink
Move _py_geometric_intersection into hazmat. (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhermes committed May 15, 2020
1 parent 5e1c5f3 commit 058502c
Show file tree
Hide file tree
Showing 18 changed files with 167 additions and 169 deletions.
23 changes: 0 additions & 23 deletions docs/algorithms/geometric-helpers.rst

This file was deleted.

1 change: 0 additions & 1 deletion docs/algorithms/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,3 @@ This is to help with the exposition of the computation and
:titlesonly:

curve-curve-intersection
geometric-helpers
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bezier.hazmat.geometric\_intersection module
============================================

.. automodule:: bezier.hazmat.geometric_intersection
:members:
:inherited-members:
:undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions docs/python/reference/bezier.hazmat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Submodules

bezier.hazmat.algebraic_intersection
bezier.hazmat.curve_helpers
bezier.hazmat.geometric_intersection
bezier.hazmat.helpers
bezier.hazmat.intersection_helpers
bezier.hazmat.triangle_helpers
Expand Down
6 changes: 6 additions & 0 deletions docs/releases/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Breaking Changes
- Moved non-public ``bezier._py_intersection_helpers`` module to
``bezier.hazmat.intersection_helpers``
(`#222 <https://github.com/dhermes/bezier/pull/222>`__).
- Moved non-public ``bezier._py_geometric_intersection`` module to
``bezier.hazmat.geometric_intersection``
(`#223 <https://github.com/dhermes/bezier/pull/223>`__).

Documentation
--------------
Expand All @@ -34,6 +37,9 @@ Documentation
- Updated from ``https://docs.scipy.org/doc/numpy`` to ``https://numpy.org``
for references to the NumPy documentation
(`#221 <https://github.com/dhermes/bezier/pull/221>`__).
- Removed ``algorithms/geometric-helpers`` document since the functions and
classes there are now fully documented in ``bezier.hazmat``
(`#223 <https://github.com/dhermes/bezier/pull/223>`__).

.. |pypi| image:: https://img.shields.io/pypi/v/bezier/2020.2.4.dev1.svg
:target: https://pypi.org/project/bezier/2020.2.4.dev1/
Expand Down
4 changes: 2 additions & 2 deletions src/python/bezier/_clipping.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import numpy as np

from bezier import _helpers
from bezier import _py_geometric_intersection
from bezier.hazmat import geometric_intersection


NO_PARALLEL = "Parallel lines not supported during clipping."
Expand Down Expand Up @@ -164,7 +164,7 @@ def _update_parameters(s_min, s_max, start0, end0, start1, end1):
NotImplementedError: If the two line segments are parallel. (This
case will be supported at some point, just not now.)
"""
s, t, success = _py_geometric_intersection.segment_intersection(
s, t, success = geometric_intersection.segment_intersection(
start0, end0, start1, end1
)

Expand Down
6 changes: 3 additions & 3 deletions src/python/bezier/_geometric_intersection.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import atexit

from bezier import _py_geometric_intersection
from bezier.hazmat import geometric_intersection

try:
from bezier import _speedup
Expand All @@ -29,8 +29,8 @@

# pylint: disable=invalid-name
if _speedup is None: # pragma: NO COVER
bbox_intersect = _py_geometric_intersection.bbox_intersect
all_intersections = _py_geometric_intersection.all_intersections
bbox_intersect = geometric_intersection.bbox_intersect
all_intersections = geometric_intersection.all_intersections
else:
bbox_intersect = _speedup.bbox_intersect
all_intersections = _speedup.curve_intersections
Expand Down
2 changes: 1 addition & 1 deletion src/python/bezier/_speedup.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ SEGMENTS_TOO_SMALL = (
"Did not have enough space for segments. Needed space "
"for {:d} `CurvedPolygonSegment`-s but only had space for {:d}.")
# NOTE: The ``SUBDIVISION_NO_CONVERGE`` error message is copied from
# ``_py_geometric_intersection.py::_NO_CONVERGE_TEMPLATE``. This
# ``hazmat/geometric_intersection.py::_NO_CONVERGE_TEMPLATE``. This
# assumes, but does not verify, that the Fortran subroutine
# ``curve_intersection.f90::all_intersections_abi()`` uses
# ``MAX_INTERSECT_SUBDIVISIONS = 20``.
Expand Down
6 changes: 3 additions & 3 deletions src/python/bezier/hazmat/algebraic_intersection.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
from bezier import _geometric_intersection
from bezier import _helpers
from bezier import _intersection_helpers
from bezier import _py_geometric_intersection
from bezier.hazmat import geometric_intersection
from bezier.hazmat import helpers as _py_helpers


Expand Down Expand Up @@ -112,8 +112,8 @@
"Currently only supporting degree pairs "
"1-1, 1-2, 1-3, 1-4, 2-2, 2-3, 2-4 and 3-3."
)
_LINEARIZATION = _py_geometric_intersection.Linearization
_DISJOINT = _py_geometric_intersection.BoxIntersectionType.DISJOINT
_LINEARIZATION = geometric_intersection.Linearization
_DISJOINT = geometric_intersection.BoxIntersectionType.DISJOINT


def _evaluate3(nodes, x_val, y_val):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def bbox_intersect(nodes1, nodes2):
B |eacute| zier shape.
Returns:
int: Enum from ``BoxIntersectionType`` indicating the type of
int: Enum from :class:`.BoxIntersectionType` indicating the type of
bounding box intersection.
"""
left1, right1, bottom1, top1 = _py_helpers.bbox(nodes1)
Expand Down Expand Up @@ -152,14 +152,14 @@ def linearization_error(nodes):
\left.\frac{s(1 - s)}{2!} \cdot 10\right|_{s = \frac{1}{2}}
= \frac{5}{4}.
.. image:: ../images/linearization_error.png
.. image:: ../../images/linearization_error.png
:align: center
.. testsetup:: linearization-error, linearization-error-fail
import numpy as np
import bezier
from bezier._py_geometric_intersection import linearization_error
from bezier.hazmat.geometric_intersection import linearization_error
.. doctest:: linearization-error
Expand Down Expand Up @@ -296,13 +296,13 @@ def segment_intersection(start0, end0, start1, end1):
L_1\left(\frac{3}{4}\right) =
\frac{1}{2} \left[\begin{array}{c} 1 \\ 1 \end{array}\right]`.
.. image:: ../images/segment_intersection1.png
.. image:: ../../images/segment_intersection1.png
:align: center
.. testsetup:: segment-intersection1, segment-intersection2
import numpy as np
from bezier._py_geometric_intersection import segment_intersection
from bezier.hazmat.geometric_intersection import segment_intersection
.. doctest:: segment-intersection1
:options: +NORMALIZE_WHITESPACE
Expand Down Expand Up @@ -336,7 +336,7 @@ def segment_intersection(start0, end0, start1, end1):
we should be able to determine that the lines don't intersect, but
this function is not meant for that check:
.. image:: ../images/segment_intersection2.png
.. image:: ../../images/segment_intersection2.png
:align: center
.. doctest:: segment-intersection2
Expand All @@ -360,7 +360,9 @@ def segment_intersection(start0, end0, start1, end1):
.. testsetup:: segment-intersection2-continued
import numpy as np
from bezier._py_geometric_intersection import parallel_lines_parameters
from bezier.hazmat.geometric_intersection import (
parallel_lines_parameters
)
start0 = np.asfortranarray([1.0, 0.0])
end0 = np.asfortranarray([0.0, 1.0])
Expand Down Expand Up @@ -443,13 +445,15 @@ def parallel_lines_parameters(start0, end0, start1, end1):
If it is not on the first line, then we are done, the
segments don't meet:
.. image:: ../images/parallel_lines_parameters1.png
.. image:: ../../images/parallel_lines_parameters1.png
:align: center
.. testsetup:: parallel-different1, parallel-different2
import numpy as np
from bezier._py_geometric_intersection import parallel_lines_parameters
from bezier.hazmat.geometric_intersection import (
parallel_lines_parameters
)
.. doctest:: parallel-different1
Expand Down Expand Up @@ -485,7 +489,7 @@ def parallel_lines_parameters(start0, end0, start1, end1):
:math:`E_1 = S_0 + 2 \Delta_0`) correspond to segments that
don't meet:
.. image:: ../images/parallel_lines_parameters2.png
.. image:: ../../images/parallel_lines_parameters2.png
:align: center
.. doctest:: parallel-different2
Expand All @@ -508,13 +512,15 @@ def parallel_lines_parameters(start0, end0, start1, end1):
but if the intervals overlap, like :math:`\left[0, 1\right]` and
:math:`\left[-1, \frac{1}{2}\right]`, the segments meet:
.. image:: ../images/parallel_lines_parameters3.png
.. image:: ../../images/parallel_lines_parameters3.png
:align: center
.. testsetup:: parallel-different3, parallel-different4
import numpy as np
from bezier._py_geometric_intersection import parallel_lines_parameters
from bezier.hazmat.geometric_intersection import (
parallel_lines_parameters
)
start0 = np.asfortranarray([1.0, 0.0])
delta0 = np.asfortranarray([2.0, -1.0])
Expand All @@ -541,7 +547,7 @@ def parallel_lines_parameters(start0, end0, start1, end1):
Similarly, if the second interval completely contains the first,
the segments meet:
.. image:: ../images/parallel_lines_parameters4.png
.. image:: ../../images/parallel_lines_parameters4.png
:align: center
.. doctest:: parallel-different4
Expand Down Expand Up @@ -808,17 +814,18 @@ def add_intersection(s, t, intersections):
If ``s`` is below :math:`2^{-10}`, it will be replaced with ``1 - s``
and compared against ``1 - s'`` for all ``s'`` already in
``intersections``. (Similar if ``t`` is below the :attr:`.ZERO_THRESHOLD`.)
``intersections``. (Similar if ``t`` is below the
:attr:`~bezier.hazmat.intersection_helpers.ZERO_THRESHOLD`.)
This is perfectly "appropriate" since evaluating a B |eacute| zier curve
requires using both ``s`` and ``1 - s``, so both values are equally
relevant.
Compares :math:`\|p - q\|` to :math:`\|p\|` where :math:`p = (s, t)` is
current candidate intersection (or the "normalized" version, such as
:math:`p = (1 - s, t)`) and :math:`q` is one of the already added
intersections. If the difference is below :math:`2^{-42}` (i.e.
:attr`.NEWTON_ERROR_RATIO`) then the intersection is considered to be
duplicate.
intersections. If the difference is below :math:`2^{-36}` (i.e.
:attr:`~bezier.hazmat.intersection_helpers.NEWTON_ERROR_RATIO`)
then the intersection is considered to be duplicate.
Args:
s (float): The first parameter in an intersection.
Expand Down Expand Up @@ -870,13 +877,13 @@ def endpoint_check(
Args:
first (SubdividedCurve): First curve being intersected (assumed in
:math:\mathbf{R}^2`).
:math:`\mathbf{R}^2`).
node_first (numpy.ndarray): 1D ``2``-array, one of the endpoints
of ``first``.
s (float): The parameter corresponding to ``node_first``, so
expected to be one of ``0.0`` or ``1.0``.
second (SubdividedCurve): Second curve being intersected (assumed in
:math:\mathbf{R}^2`).
:math:`\mathbf{R}^2`).
node_second (numpy.ndarray): 1D ``2``-array, one of the endpoints
of ``second``.
t (float): The parameter corresponding to ``node_second``, so
Expand Down Expand Up @@ -933,9 +940,9 @@ def tangent_bbox_intersection(first, second, intersections):
Args:
first (SubdividedCurve): First curve being intersected (assumed in
:math:\mathbf{R}^2`).
:math:`\mathbf{R}^2`).
second (SubdividedCurve): Second curve being intersected (assumed in
:math:\mathbf{R}^2`).
:math:`\mathbf{R}^2`).
intersections (list): A list of already encountered
intersections. If these curves intersect at their tangency,
then those intersections will be added to this list.
Expand Down Expand Up @@ -981,7 +988,7 @@ def bbox_line_intersect(nodes, line_start, line_end):
line_end (numpy.ndarray): End of a line segment (1D ``2``-array).
Returns:
int: Enum from ``BoxIntersectionType`` indicating the type of
int: Enum from :class:`.BoxIntersectionType` indicating the type of
bounding box intersection.
"""
left, right, bottom, top = _py_helpers.bbox(nodes)
Expand Down Expand Up @@ -1142,11 +1149,12 @@ def prune_candidates(candidates):
if those convex hulls collide.
Args:
candidates (List): An iterable of pairs of curves (or
linearized curves).
candidates (List[Union[SubdividedCurve, Linearization]]): An iterable
of pairs of curves (or linearized curves).
Returns:
List: A pruned list of curve pairs.
List[Union[SubdividedCurve, Linearization]]: A pruned list of curve
pairs.
"""
pruned = []
# NOTE: In the below we replace ``isinstance(a, B)`` with
Expand Down Expand Up @@ -1194,9 +1202,9 @@ def coincident_parameters(nodes1, nodes2):
.. math::
B_1(s_0) = B_2(0)
B_1(s_m) = B_2(1)
B_1(0) = B_2(t_0)
B_1(s_0) = B_2(0) \\
B_1(s_m) = B_2(1) \\
B_1(0) = B_2(t_0) \\
B_1(1) = B_2(t_n)
and then finding the "shared interval" where both curves are defined.
Expand Down Expand Up @@ -1473,8 +1481,8 @@ class BoxIntersectionType: # pylint: disable=too-few-public-methods
.. note::
This class would be more "correct" as an ``enum.Enum``, but it we keep
the values integers to make interfacing with Fortran easier.
This class would be more "correct" as an :class:`enum.Enum`, but it we
keep the values integers to make interfacing with Fortran easier.
"""

INTERSECTION = 0
Expand All @@ -1497,7 +1505,7 @@ class SubdividedCurve: # pylint: disable=too-few-public-methods
original_nodes (numpy.ndarray): The control points of the original
curve used to define the current one (before subdivision began).
start (Optional[float]): The start parameter after subdivision.
end (Optional[float]): The start parameter after subdivision.
end (Optional[float]): The end parameter after subdivision.
"""

__slots__ = ("nodes", "original_nodes", "start", "end")
Expand Down Expand Up @@ -1592,7 +1600,7 @@ def subdivide(self):
"""Do-nothing method to match the :class:`.Curve` interface.
Returns:
Tuple[~bezier._py_geometric_intersection.Linearization]: List of
Tuple[~bezier.hazmat.geometric_intersection.Linearization]: List of
all subdivided parts, which is just the current object.
"""
return (self,)
Expand All @@ -1603,12 +1611,12 @@ def from_shape(cls, shape):
Args:
shape (Union[SubdividedCurve, \
~bezier._py_geometric_intersection.Linearization]): A curve or an
already linearized curve.
~bezier.hazmat.geometric_intersection.Linearization]): A curve or
an already linearized curve.
Returns:
Union[SubdividedCurve, \
~bezier._py_geometric_intersection.Linearization]: The
~bezier.hazmat.geometric_intersection.Linearization]: The
(potentially linearized) curve.
"""
# NOTE: In the below we replace ``isinstance(a, B)`` with
Expand Down
3 changes: 2 additions & 1 deletion src/python/bezier/hazmat/intersection_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
NEWTON_ERROR_RATIO = 0.5 ** 36
"""float: Cap on error ratio during Newton's method
See :func:`.newton_iterate` for more details."""
Equal to :math:`2^{-36}`. See :func:`.newton_iterate` for more details.
"""
NEWTON_NO_CONVERGE = """\
Unsupported multiplicity.
Expand Down
Loading

0 comments on commit 058502c

Please sign in to comment.