.. _spheres: Spheres ======= For us, a sphere is any subset of :math:`\RP^n` defined by a center, some kind of radius and optionally a containing subspace. Each sphere is associated with a :ref:`geometry model `, which determines how spheres are defined. In particular, the radius must be interpreted. The usual case is that the radius is interpreted in terms of a metric, but there are other ways. Cayley-Klein spheres are a generalization that we will look at below. In terms of the API, functionality that is common to all spheres is described in the interface :py:class:`.SphereLike`. All spheres in all geometries without exception implement this interface. .. contents:: Topics :local: :backlinks: none Example: Euclidean spheres -------------------------- Spheres are created using the factory method :py:meth:`~.SphereFactory.sphere` of the geometry they live in. For example, to create the unit sphere in 3D Euclidean space: .. doctest:: >>> import ddg >>> euc = ddg.geometry.euclidean(3) >>> unit_sphere = euc.sphere([0, 0, 0, 1], 1.0) >>> print(unit_sphere) Sphere in geometry/model: euclidean_models.ProjectiveModel(3) Center: [0. 0. 0. 1.] Radius: 1.0 To create some circle in the x-y-plane (using :py:func:`.subspace_from_affine_points` so we can think in terms of usual cartesian coordinates): .. doctest:: >>> from ddg.geometry.subspaces import subspace_from_affine_points as sfap >>> xy_plane = sfap([0, 0, 0], [1, 0, 0], [0, 1, 0]) >>> c = sfap([0.5, 0.8, 0]) >>> r = 1.8 >>> circ = euc.sphere(c, r, subspace=xy_plane) >>> circ.dimension 1 >>> circ.ambient_dimension 3 >>> circ.is_circle() True >>> circ.is_hypersphere() False >>> p1 = sfap([2.3, 0.8, 0]) >>> p2 = sfap([1.1, 0.8, 0]) >>> p1 in circ True >>> p2 in circ False >>> circ == unit_sphere False >>> circ <= unit_sphere # set containment False Use the :py:attr:`~.SphereLike.geometry` attribute to check what geometry your sphere belongs to: .. doctest:: >>> circ.geometry euclidean_models.ProjectiveModel(3) The spheres we have in our library are all special cases of quadrics. Convert a sphere to a quadric using the method :py:meth:`~.QuadricConvertible.quadric`: .. doctest:: >>> type(circ.quadric()) For some types of spheres, the conversion in the other direction is possible as well, namely if the geometry implements a method ``quadric_to_sphere``. This is currently only possible for standard Euclidean spheres: If you have a quadric that happens to be equal to a Euclidean sphere, you can use :py:meth:`.euclidean_models.ProjectiveModel.quadric_to_sphere` to convert it to a sphere: .. doctest:: >>> import numpy as np >>> import ddg >>> unit_sphere_as_quadric = ddg.geometry.quadrics.Quadric(np.diag([1, 1, 1, -1])) >>> unit_sphere = euc.quadric_to_sphere(unit_sphere_as_quadric) >>> print(unit_sphere) Sphere in geometry/model: euclidean_models.ProjectiveModel(3) Center: [0. 0. 0. 1.] Radius: 1.0 Cayley-Klein spheres -------------------- The classes :py:class:`~.MetricCayleyKleinSphere`, :py:class:`~.CayleyKleinSphere` and :py:class:`~.GeneralizedCayleyKleinSphere` are related, increasingly general definitions of spheres in certain so-called (metric) Cayley-Klein geometries. They all implement the interface :py:class:`.CayleyKleinSphereLike`. .. note:: Metric Cayley-Klein spheres behave exactly like spheres defined in terms of any other metric. You don't have to understand all of this to use them. Let's take a closer look. For the preliminaries, i.e. Cayley-Klein distances and metrics see :ref:`geometries`. Metric Cayley-Klein spheres ~~~~~~~~~~~~~~~~~~~~~~~~~~~ These are the standard spheres in Cayley-Klein geometries. This is just a metric sphere whose radius is interpreted in terms of a Cayley-Klein metric. Cayley-Klein spheres ~~~~~~~~~~~~~~~~~~~~ Let :math:`Q` be the absolute. A Cayley-Klein sphere with center :math:`[c]` and Cayley-Klein radius :math:`r \in \R` is defined as the set of all :math:`[x] \in \RP^n` that satisfy .. math:: \langle x, c \rangle_Q^2 - r \langle c, c \rangle_Q \langle x, x \rangle_Q = 0. This is based on the definition of the Cayley-Klein distance .. math:: K_Q([x], [y]) \coloneqq \frac{\langle x, y \rangle_Q^2} {\langle x, x \rangle_Q \langle y, y\rangle_Q} but since :math:`K_Q` is only defined on :math:`\RP^n \setminus Q`, it makes sense to use the first formula to also allow for points on the absolute. Generalized Cayley-Klein spheres and horospheres ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The above definition of Cayley-Klein spheres does not give interesting results for centers on the absolute quadric :math:`Q` (Exercise: Try it. What do we get?). We therefore define a generalized Cayley-Klein sphere with generalized radius :math:`r` as the set of :math:`[x] \in \RP^n` that satisfy .. math:: \langle x, c \rangle_Q^2 - r \langle x, x \rangle_Q = 0. This is still independent of the representative of :math:`[x]`, but now depends on both the representatives of the center :math:`[c]` and on the representative matrix of :math:`Q`. What we get in return for giving this up is that we can now defined so-called `Cayley-Klein horospheres` with center on the absolute. Keeping all representatives the same, a CKS with Cayley-Klein radius :math:`r` is the same as the generalized CKS with generalized radius :math:`r\langle c, c \rangle`. Conversion and common handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All three of these types have the methods :py:meth:`~.CayleyKleinSphereLike.metric_radius`, :py:meth:`~.CayleyKleinSphereLike.cayley_klein_radius` :py:meth:`~.CayleyKleinSphereLike.generalized_radius`. These will attempt to convert the stored radius to the radius of another type. See the API documentation, e.g. :py:meth:`.MetricCayleyKleinSphere.cayley_klein_radius` for detailed information on when these methods will succeed. Example: Hyperbolic spheres ~~~~~~~~~~~~~~~~~~~~~~~~~~~ For metric Cayley-Klein spheres, the creation using the ``sphere`` factory method applies. Additionally, there are the methods :py:meth:`~.CayleyKleinSphereFactory.cayley_klein_sphere` and :py:meth:`~.CayleyKleinSphereFactory.generalized_cayley_klein_sphere` to create the other types in a certain :py:class:`.CayleyKleinGeometry`. .. doctest:: >>> import ddg >>> hyp = ddg.geometry.hyperbolic(3) >>> cks = hyp.cayley_klein_sphere([0, 0.5, 0, 1], 1.3) >>> print(cks) Cayley-Klein sphere in geometry/model: hyperbolic_models.ProjectiveModel(3) Center: [0. 0.5 0. 1. ] Cayley-Klein radius: 1.3 >>> cks.radius 1.3 >>> cks.cayley_klein_radius() 1.3 >>> cks.metric_radius() 0.523... >>> cks.generalized_radius() -0.975... >>> dist_curve = hyp.cayley_klein_sphere([0, 0.5, 0, 1], -1.3) >>> dist_curve.metric_radius() Traceback (most recent call last): ... ValueError: Cayley-Klein distance must be in [1, inf[ to correspond to a metric distance in hyperbolic geometry. Advanced: Direct instantiation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For more advanced applications, ``CayleyKleinSphere`` and ``GeneralizedCayleyKleinSphere`` can be instantiated directly, giving an absolute quadric ``absolute`` and optionally a :py:class:`.MetricCayleyKleinGeometry` object ``geometry``. If such a geometry is given, its methods :py:meth:`~.CayleyKleinGeometry.metric_to_cayley_klein_distance` and :py:meth:`~.CayleyKleinGeometry.cayley_klein_distance_to_metric` are used to convert between the Cayley-Klein radius and the metric radius. If it is not given, no metric radius can be computed. .. doctest:: >>> import numpy as np >>> import ddg >>> absolute = ddg.geometry.quadrics.Quadric(np.diag([1, 1, -1, -1])) >>> cks = ddg.geometry.spheres.CayleyKleinSphere( ... [0, 0.3, 0, 1], 1.8, absolute=absolute ... ) >>> print(cks) Cayley-Klein sphere with absolute: quadric in 3D projective space signature: (2, 2) matrix: [[ 1. 0. 0. 0.] [ 0. 1. 0. 0.] [ 0. 0. -1. 0.] [ 0. 0. 0. -1.]] Center: [0. 0.3 0. 1. ] Cayley-Klein radius: 1.8 >>> print(cks.geometry) None >>> cks.metric_radius() Traceback (most recent call last): ... AttributeError: No MetricCayleyKleinGeometry to convert between metric and Cayley-Klein distance was provided. >>> cks.generalized_radius() -1.638... ``MetricCayleyKleinSphere`` can also be instantiated directly in this way, but here the ``geometry`` becomes mandatory because the metric radius must be converted to a Cayley-Klein radius to be able to be interpreted. Visualization in Blender ------------------------ A guide on how to visualize Spheres in Blender can be found here: :ref:`Visualizing Spheres `.