from abc import ABC, abstractmethod
[docs]class ProjectiveObject(ABC):
"""ABC for geometric objects that are subsets of a Projective space RP^n."""
ambient_dimension: int
[docs] @abstractmethod
def at_infinity(self):
"""Whether the object is contained in the hyperplane at infinity.
Returns
-------
bool
"""
raise NotImplementedError
[docs]class Embeddable(ProjectiveObject):
"""ABC for objects that can be embedded in subspaces in a
higher-dimensional projective space.
"""
[docs] @abstractmethod
def embed(self, subspace=None):
"""The embedded object.
We can embed a subset X of n-dimensional projective space into m-dimensional
space (where m >= n) by choosing an n-dimensional subspace S in RP^m together
with a basis B. We then interpret the original homogeneous coordinates as
coordinates w.r.t. this basis B.
More concretely: If M is the `matrix` of S, we define ::
X.embed(S) := { [M @ x] | [x] in X }.
``X.embed(S)`` must be the same kind of object as X, for example if
X is a euclidean sphere, the basis M must be chosen so that
``X.embed(S)`` is also a euclidean sphere.
Parameters
----------
subspace : ddg.geometry.Subspace (default=None)
Subspace in m-dimensional ambient space whose dimension is the ambient
dimension of `self` (where m >= n). The homogeneous coordinates of points
are used as cordinates w.r.t. the given basis of `subspace`.
The default is the coordinate hyperplane {x_n+1 = 0} in (n+1)-dimensional
space, where n is the ambient dimension of `self`. The basis is the standard
basis with the second to last basis vector missing.
Returns
-------
type(self)
Object in m-dimensional ambient space contained in `subspace`.
Raises
------
ValueError
If embedding w.r.t. the given basis would result in an object of a different
type.
"""
raise NotImplementedError
[docs] @abstractmethod
def unembed(self, subspace=None):
"""Inverse of `embed`.
Parameters
----------
subspace : ddg.geometry.Subspace (default=None)
k-dim. subspace to treat as the new ambient space. coordinates of
points will be computed w.r.t. the given basis of `subspace`.
The default is the coordinate hyperplane {x_n = 0} which will fail
if the object is not contained in this subspace.
Returns
-------
type(self)
Object in `k`-dim. ambient space.
Raises
------
ValueError
- If object is not contained in `subspace`.
- If coordinate computation would result in an object of a
different type.
"""
raise NotImplementedError
[docs]class QuadricConvertible(ABC):
"""ABC for objects that can be converted to quadrics."""
[docs] @abstractmethod
def quadric(self):
"""Return object as quadric.
Returns
-------
ddg.geometry.Quadric
"""
raise NotImplementedError
[docs]class SphereFactory(ABC):
"""Factory class for general spheres."""
[docs] @abstractmethod
def sphere(self, center, radius, subspace=None, atol=None, rtol=None):
"""General sphere factory method.
Parameters
----------
center : ddg.geometry.Point
radius : float
subspace : ddg.geometry.Subspace (default=None)
atol, rtol : float (default=None)
Returns
-------
ddg.geometry.spheres.SphereLike
"""
raise NotImplementedError
[docs]class CayleyKleinSphereFactory(ABC):
"""Factory class for (generalized) Cayley-Klein spheres but not Metric
Cayley-Klein spheres, use SphereFactory for those.
"""
[docs] @abstractmethod
def cayley_klein_sphere(self, center, radius, subspace=None, atol=None, rtol=None):
"""Cayley-Klein sphere factory method.
Parameters
----------
center : ddg.geometry.Point
radius : float
subspace : ddg.geometry.Subspace (default=None)
atol, rtol : float (default=None)
Returns
-------
ddg.geometry.spheres.CayleyKleinSphere
"""
raise NotImplementedError
[docs] @abstractmethod
def generalized_cayley_klein_sphere(
self, center, radius, subspace=None, atol=None, rtol=None
):
"""Generalized Cayley-Klein sphere factory method.
Parameters
----------
center : ddg.geometry.Point
radius : float
subspace : ddg.geometry.Subspace (default=None)
atol, rtol : float (default=None)
Returns
-------
ddg.geometry.spheres.GeneralizedCayleyKleinSphere
"""
raise NotImplementedError