.. _envelope_orth_trajectory_circles: ------------------------------------------------------------ Envelopes and Orthogonal Trajectories of Families of Circles ------------------------------------------------------------ .. image:: all_combined.jpg :width: 70% :align: center This example shows different ways of finding envelopes and orthogonal trajectories of a one-parameter family of circles, once in the smooth case and once in the discrete case. We start with a one-parameter family of circles where neighbouring circles intersect. The top left image shows a smooth family of circles, the top right image a discrete family of circles. The first envelope is constructed by connecting intersection points of consecutive circles. The first orthogonal trajectory is constructed by choosing an arbitrary starting point and iteratively applying sphere inversions in the circles. These two are shown in the second and third row of the image above. Secondly, envelopes and orthogonal trajectories are constructed by choosing a starting point on a circle and applying sphere inversions in the mid-circles of neighbouring circles. Executing the code in the script will visualize the smooth and the discrete examples, separated in distinct Blender collections. We will go through the discrete example in this guide. Download the full script here: :download:`envelope_orth_trajectory_circles.py <../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py>`. .. contents:: :local: :backlinks: none Setup ===== We start off by importing the necessary libraries. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [setup-1] :end-before: [setup-1] We are also going to clear the whole scene. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [setup-2] :end-before: [setup-2] We initialize the projective and the Moebius geometric model of two dimensional Euclidean space. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [setup-3] :end-before: [setup-3] First Envelope and Orthogonal Trajectory ======================================== The main script starts by defining a lot of helper functions. In the end the examples will be generated only by suitable composition of these functions. A lot of the functions are straight forward, and we will not explicitly include all of them here. Now lets get started by defining a discrete curve outside the Moebius quadric :math:`M` and some initial values. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [example-1] :end-before: [example-1] .. image:: m_and_e_discrete.jpg :width: 80% :align: center The vertices of the discrete net are points outside the Moebius quadric (points with positive scalar square with respect to the Möbius scalar product) and therefore represent Euclidean circles. We can find the corresponding circles in the following way. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [example-2] :end-before: [example-2] The visualization is also done by using helper functions and can be found as the last section of this guide. Next we want to create an envelope consisting of consecutive intersection points of circles. Inside the helper function `m_envelope` we find a way of consistently determining the right choice of the next intersection point (see script). .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [example-3] :end-before: [example-3] .. image:: m_and_e_discrete_env_1.jpg :width: 80% :align: center For the first orthogonal trajectory we define a function representing a sphere inversion in a given circle. Let :math:`[c]` be the representation of a circle as point outside of :math:`M` and :math:`[x]` be a point on :math:`M`. The formula :math:`x - 2 * \langle x, c \rangle / \langle c, c \rangle * c` determines a point :math:`x'`, resp. :math:`[x']` in M, which corresponds to the inversion of the point :math:`x` in the circle :math:`c`. Additionally the script supplies a function `m_iterative_sphere_inversions`, applying this inversion iteratively to a family of circles. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [example-4] :end-before: [example-4] .. image:: m_and_e_discrete_orth_1.jpg :width: 80% :align: center Second Envelope and Orthogonal Trajectory ========================================= For the second envelope and orthogonal trajectory we need to find the mid-circles, the circle of similitude and the circle of anti-similitude, between two neighbouring circles. Circles with center :math:`c` and radius :math:`r` can explicitly be lifted to the homogeneous coordinates :math:`\frac{1}{r}(c, \frac{1}{2}(||c||^2 - r^2 + 1) , \frac{1}{2}(||c||^2 - r^2 - 1))`, or equivalently to :math:`\frac{1}{r}(c + e_0 + (||c||^2-r^2) e_\infty)` in the basis :math:`e_1, ...., e_3 e_0, e_\infty`. If two circles are given in these homogeneous coordinates, say :math:`c` and :math:`d`, the mid-circles are represented by :math:`[c + d]` and :math:`[c-d]`. The two helper functions `m_points_of_similitude_from_homogeneous_lift` and `m_points_of_anti_similitude_from_homogeneous_lift` return these points while the initial circles can be lifted using the function `m_homogeneous_lift_fct`. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [example-5] :end-before: [example-5] .. image:: m_and_e_discrete_midcircles.jpg :width: 80% :align: center With this it is easy to define the corresponding envelopes and orthogonal trajectories. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [example-6] :end-before: [example-6] .. image:: m_and_e_discrete_env_2.jpg :width: 80% :align: center .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [example-7] :end-before: [example-7] .. image:: m_and_e_discrete_orth_2.jpg :width: 80% :align: center Visualization ============= With all this setup done, we can now visualize this in Blender. We start by defining some colors and helper functions. For some functions the discrete domain may be clipped at the start or at the end. For this we also use a helper function. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [visualization-1] :end-before: [visualization-1] For each example ("smooth"/"discrete") we add a set of collections ... .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [visualization-2] :end-before: [visualization-2] ... and visualize the Moebius geometric part ... .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [visualization-3] :end-before: [visualization-3] ... and the Euclidean part. .. literalinclude:: ../../../../examples/blender/geometry/envelope_orth_trajectory_circles.py :language: python :start-after: [visualization-4] :end-before: [visualization-4] The script further includes adding lights and cameras and setting up the scene for rendering.