"""Intersections and joins of geometric objects.
The join of two objects X and Y is defined as the union of all lines connecting a point
in X with a point in Y.
The functions in this module automatically choose elementary intersection/join functions
based on the types of objects and reduce intersections/joins of more than two objects if
possible. The following types are currently supported:
.. list-table:: Supported types for intersections
:header-rows: 1
:align: left
* - Types
- Function
* - Subspace and Subspace
- :py:func:`ddg.geometry._subspaces.intersect_subspaces`
* - Quadric and Subspace
- :py:func:`ddg.geometry._quadrics.intersect_quadric_subspace`
.. list-table:: Supported types for joins
:header-rows: 1
:align: left
* - Types
- Function
* - Subspace and Subspace
- :py:func:`ddg.geometry._subspaces.join_subspaces`
* - Quadric and Subspace
- :py:func:`ddg.geometry._quadrics.join_quadric_subspace`
Please refer to the elementary functions for further restrictions and details.
"""
from ddg.geometry._quadrics import (
Quadric,
intersect_quadric_subspace,
intersect_quadrics,
join_quadric_subspace,
)
from ddg.geometry._subspaces import Subspace, intersect_subspaces, join_subspaces
[docs]def intersect(*objects, resolve=True):
"""Intersect any number of supported geometric objects.
Parameters
----------
*objects : Iterable of ddg.geometry.Subspace or ddg.geometry.Quadric
Any number of subspaces can be intersected with at most one quadric. Further,
two quadrics can be intersected.
Returns
-------
ddg.geometry.Subspace, ddg.geometry.Quadric or ddg.geometry.QuadricIntersection
Intersection of the objects.
Raises
------
ValueError
If no objects are handed to the function for intersection
NotImplementedError
If the objects are of any type other than
* any number of ddg.geometry.Subspace with at most one
ddg.geometry.Quadric
* two ddg.geometry.Quadric
See Also
--------
ddg.geometry.join
"""
if len(objects) >= 1 and (
isinstance(objects[0], Subspace) or isinstance(objects[0], Quadric)
):
if (
len(objects) == 2
and isinstance(objects[0], Quadric)
and isinstance(objects[1], Quadric)
):
intersection = intersect_quadrics(objects[0], objects[1])
else:
intersection = objects[0]
# Consecutively go through the list and intersect with every element.
for obj in objects[1:]:
if isinstance(intersection, Subspace) and isinstance(obj, Subspace):
intersection = intersect_subspaces(intersection, obj)
elif isinstance(intersection, Quadric) and isinstance(obj, Subspace):
intersection = intersect_quadric_subspace(intersection, obj)
elif isinstance(intersection, Subspace) and isinstance(obj, Quadric):
intersection = intersect_quadric_subspace(obj, intersection)
else:
raise NotImplementedError("Combination of types not supported.")
else:
raise ValueError("Not enough objects handed for intersection.")
return intersection
# Unlike Python, Sphinx interprets the triple quoted string as a
# docstring for meet.
meet = intersect
"""Alias for intersect.
See Also
--------
intersect
"""
def _join_quadric_subspace(quadric, subspace):
"""Wrapper for :py:func:`join_quadric_subspace` that attempts
to join a quadric and a subspace.
Raises
------
Exception
If there is an error during the joining process, suggesting to try
joining objects in a different order.
"""
try:
join = join_quadric_subspace(quadric=quadric, subspace=subspace)
except Exception as error:
args = error.args
error.args = (f"{args[0]}\nTry joining objects in a different order.",) + args[
1:
]
raise
return join
[docs]def join(*objects, resolve=True):
"""Join any number of supported geometric objects.
Parameters
----------
*objects : Iterable of ddg.geometry.Subspace or ddg.geometry.Quadric
An arbitrary number of quadrics and subspaces can be joined.
Returns
-------
ValueError
If no objects are handed to the function for joining.
NotImplementedError
* If the objects are of any other type than ddg.geometry.Subspace or
ddg.geometry.Quadric,
* If at any point it is attempted to join two ddg.geometry.Quadrics,
* If at any point it is attempted to join a ddg.geometry.Quadric and a
ddg.geometry.Subspace which do not fulfill one of the three following cases:
1) The intersection of the subspace of the quadric and the subspace is
empty,
2) The intersection is non-empty but the subspace is of the type
ddg.geometry.Point,
3) The intersection is non-empty but the subspace contains the subspace of
the quadric itself.
See Also
--------
ddg.geometry.intersect
"""
if len(objects) >= 1 and (
isinstance(objects[0], Subspace) or isinstance(objects[0], Quadric)
):
join = objects[0]
# Consecutively go through the list and join with every element.
for obj in objects[1:]:
if isinstance(join, Subspace) and isinstance(obj, Subspace):
join = join_subspaces(join, obj)
elif isinstance(join, Quadric) and isinstance(obj, Subspace):
join = _join_quadric_subspace(quadric=join, subspace=obj)
elif isinstance(join, Subspace) and isinstance(obj, Quadric):
join = _join_quadric_subspace(quadric=obj, subspace=join)
else:
raise NotImplementedError("Combination of types not supported.")
else:
raise ValueError("Not enough objects handed for intersection.")
return join