"""Conversion module for geometries.
This module contains functions for conversion between different types of
geometric objects.
"""
from ddg.geometry._intersection import join
from ddg.geometry._quadrics import cayley_klein_sphere, generalized_cayley_klein_sphere
from ddg.geometry._subspaces import Point
[docs]def cayley_klein_sphere_to_quadric(sphere):
"""Convert Cayley-Klein sphere to quadric.
Parameters
----------
sphere : ddg.geometry.spheres.CayleyKleinSphere or
ddg.geometry.spheres.MetricCayleyKleinSphere
Returns
-------
ddg.geometry.Quadric
"""
return cayley_klein_sphere(
sphere.center, sphere.cayley_klein_radius(), absolute=sphere.absolute
)
[docs]def generalized_cayley_klein_sphere_to_quadric(sphere):
"""Convert generalized Cayley-Klein sphere to quadric.
Parameters
----------
sphere : ddg.geometry.spheres.GeneralizedCayleyKleinSphere
Returns
-------
ddg.geometry.Quadric
"""
return generalized_cayley_klein_sphere(
sphere.center, sphere.generalized_radius(), absolute=sphere.absolute
)
[docs]def quadric_to_subspaces(quadric):
"""If a quadric is equal to a finite collection of subspaces, convert it.
This is the case if and only if Q = quadric.matrix is semidefinite or its
rank is less than or equal to 2. In the first case, return ker(Q).
Otherwise, return join(ker(Q), P1) and join(ker(Q), P2), where P1, P2 are
the two points making up the non-degenerate part of the quadric.
Parameters
----------
quadric : ddg.geometry.Quadric
Returns
-------
tuple of ddg.geometry.Subspace
Notes
-----
No non-degenerate quadric with ambient dimension at least 2 is equal to a
collection of subspaces. A degenerate quadric Q is the join of its kernel
with its non-degenerate part, i.e. the quadric obtained by restricting the
quadratic form to a subspace complementary to the kernel. For this set to
be a collection of subspaces, the non-degenerate part must itself be a
collection of subspaces. This is only possible if it is contained in a line
(i.e. the rank of Q is 2) or it is empty (i.e. Q is positive semidefinite).
"""
sgn = quadric.signature()
if sgn.is_semi_definite:
return (quadric.singular_subspace,)
if quadric.rank > 2:
raise ValueError("Quadric is not equal to a collection of subspaces.")
Q = quadric.normalize()
kernel = Q.singular_subspace
# The only case remaining is diag(1, -1, 0,...,0)
v1, v2 = Q.subspace.points[:2]
P1 = Point(v1 + v2)
P2 = Point(v1 - v2)
return join(kernel, P1), join(kernel, P2)