.. _geometry-introduction: Introduction to geometry ======================== The projective approach ----------------------- Our library takes an approach to geometry following Felix Klein's Erlangen program.\ [#]_ In the following paragraphs, we will attempt to introduce this approach to those unfamiliar with it: We consider all of our geometric objects (everything that is defined in the ``ddg.geometry`` package) as subsets of a projective space :math:`\RP^n` or in some special cases of :math:`\CP^n`. All other geometries, including Euclidean, hyperbolic and spherical geometry, are realized as subgeometries of projective geometry. This means that the model space for them is a subset of :math:`\RP^n` and they define additional structure like angles and distances. For example, Euclidean geometry is :math:`\R^n \subset \RP^n` (identified with the points "not at infinity", see the `Conventions`_ section below) together with the usual Euclidean metric and angles. More abstractly, *a geometry* can be thought of as a set :math:`X` called the model space together with a group :math:`G` of transformations acting on the space, which preserves the relevant structure like distances and angles. Euclidean geometry could be defined in this way as :math:`\R^n` together with the group of isometries :math:`x \mapsto Ax + b` with :math:`A \in \operatorname{O}(n)` and :math:`b \in \R^n`. A subgeometry is then a subset :math:`Y \subseteq X` together with a subgroup :math:`H < G`. It turns out that projective geometry, i.e. :math:`\RP^n` together with the group of projective transformations :math:`\operatorname{PGL}(n+1,\R)`, contains many other familiar geometries as subgeometries. This is the motivation for our approach. Conventions ----------- In the geometry package, all points are assumed to be given in homogeneous coordinates, unless stated otherwise. Exceptions are functions like :py:func:`.subspace_from_affine_points`. When switching from homogeneous coordinates to affine coordinates, we follow the convention of homogenizing and dehomogenizing with respect to the last component: .. doctest:: >>> import numpy as np >>> from ddg.math.projective import homogenize, dehomogenize >>> print(homogenize(np.array([1.0, 2.0, 3.0]))) [1. 2. 3. 1.] >>> print(dehomogenize(np.array([1.0, 2.0, 3.0, 1.0]))) [1. 2. 3.] >>> print(dehomogenize(np.array([2.0, 4.0, 6.0, 2.0]))) [1. 2. 3.] So "points at infinity" for us are points whose last component is 0. To see what an object would look like in a different affine chart, use the method :py:meth:`~.LinearTransformable.change_affine_picture` of :py:class:`ddg.abc.LinearTransformable` objects to transform the object with an appropriate projective transformation before visualizing it in the usual way. .. rubric:: Footnotes .. [#] Felix Klein's original text *Vergleichende Betrachtungen über neuere geometrische Forschungen (A comparative review of recent researches in geometry)* is available in the original `German `_ and in `English `_. `Wikipedia `_ offers a slightly different, more modern point of view.