.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/viz_tesseract.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_viz_tesseract.py: ====================================================================== Tesseract (Hypercube) ====================================================================== A tesseract is a four-dimensional cube. A tesseract can be unfolded into eight cubes, Just as a cube can be unfolded into eight squares. .. GENERATED FROM PYTHON SOURCE LINES 11-12 First, import some useful functions .. GENERATED FROM PYTHON SOURCE LINES 12-18 .. code-block:: default import numpy as np from fury import utils, actor, window from fury.ui import TextBlock2D import itertools .. GENERATED FROM PYTHON SOURCE LINES 19-23 Let's define some variables and their descriptions: Use `wireframe = True` to show wireframe like representation of the tesseract `wireframe = False` will render it with point actor on each vertex. .. GENERATED FROM PYTHON SOURCE LINES 23-39 .. code-block:: default wireframe = False # p_color: color of the point actor (default: (0, 0.5, 1, 1)) # e_color: color of the line actor (default: (1, 1, 1, 1)) # dtheta: change in `angle` on each iteration. It determines the "speed" of the # animation. Increase dtheta to increase speed of rotation, It may # result in less smoother rotation (default: 0.02) # angle: defines the angle to be rotated to perform the animation, It changes # as we run the `callback` method later on. (initial value: 0) p_color = np.array([0, 0.5, 1, 1]) e_color = np.array([1, 1, 1, 1]) dtheta = 0.02 angle = 0 .. GENERATED FROM PYTHON SOURCE LINES 40-42 Let's define vertices for our 4D cube, `verts4D` contains the coordinates of our 4D tesseract. .. GENERATED FROM PYTHON SOURCE LINES 42-60 .. code-block:: default verts3D = np.array( [[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1], [-1, 1, -1], [1, 1, -1], [1, -1, -1], [-1, -1, -1]] ) # We can use primitive.box alternatively to get the cube's 3-D vertices. u = np.insert(verts3D, 3, 1, axis=1) v = np.insert(verts3D, 3, -1, axis=1) verts4D = np.append(u, v, axis=0) .. GENERATED FROM PYTHON SOURCE LINES 61-64 We define a `rotate4D` function that takes 4D matrix as parameter and rotates it in XY plane (Z axis) and ZW plane (an imaginary axis), projects it to the 3D plane so that we can render it in a scene. .. GENERATED FROM PYTHON SOURCE LINES 64-95 .. code-block:: default def rotate4D(verts4D): cos = np.cos(angle) sin = np.sin(angle) rotation4d_xy = np.array( [[cos, -sin, 0, 0], [sin, cos, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) rotation4d_zw = np.array( [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, cos, -sin], [0, 0, sin, cos]]) distance = 2 projected_marix = np.zeros((16, 3)) for i, vert in enumerate(verts4D): rotated_3D = np.dot(rotation4d_xy, vert) rotated_3D = np.dot(rotation4d_zw, rotated_3D) w = 1 / (distance - rotated_3D[3]) proj_mat4D = np.array( [[w, 0, 0, 0], [0, w, 0, 0], [0, 0, w, 0]] ) projeced_mat3D = np.dot(proj_mat4D, rotated_3D) projected_marix[i] = projeced_mat3D # vertices to be proj (3D) return projected_marix .. GENERATED FROM PYTHON SOURCE LINES 96-98 Now, We have 4D points projected to 3D. Let's define a function to connect lines. .. GENERATED FROM PYTHON SOURCE LINES 98-121 .. code-block:: default def connect_points(verts3D): lines = np.array([]) len_vert = len(verts3D) for i in range(len_vert-1): if i < 8: lines = np.append(lines, [verts3D[i], verts3D[i+8]]) if i == 7: pass else: lines = np.append(lines, [verts3D[i], verts3D[i+1]]) if i % 4 == 0: lines = np.append(lines, [verts3D[i], verts3D[i+3]]) for i in range(3): lines = np.append(lines, [verts3D[i], verts3D[i+5]]) lines = np.append(lines, [verts3D[i+8], verts3D[i+5+8]]) return np.reshape(lines, (-1, 2, 3)) .. GENERATED FROM PYTHON SOURCE LINES 122-123 Creating a scene object and configuring the camera's position .. GENERATED FROM PYTHON SOURCE LINES 123-131 .. code-block:: default scene = window.Scene() scene.set_camera(position=(0, 10, -1), focal_point=(0.0, 0.0, 0.0), view_up=(0.0, 0.0, 0.0)) showm = window.ShowManager(scene, size=(1920, 1080), order_transparent=True) .. GENERATED FROM PYTHON SOURCE LINES 132-133 Creating vertices and points actors .. GENERATED FROM PYTHON SOURCE LINES 133-144 .. code-block:: default verts3D = rotate4D(verts4D) if not wireframe: points = actor.point(verts3D, colors=p_color) point_verts = utils.vertices_from_actor(points) no_vertices = len(point_verts) / 16 initial_verts = point_verts.copy() - \ np.repeat(verts3D, no_vertices, axis=0) scene.add(points) .. GENERATED FROM PYTHON SOURCE LINES 145-146 Connecting points with lines actor .. GENERATED FROM PYTHON SOURCE LINES 146-155 .. code-block:: default lines = connect_points(verts3D) edges = actor.line(lines=lines, colors=e_color, lod=False, fake_tube=True, linewidth=4) lines_verts = utils.vertices_from_actor(edges) initial_lines = lines_verts.copy() - np.reshape(lines, (-1, 3)) scene.add(edges) .. GENERATED FROM PYTHON SOURCE LINES 156-157 Initializing text box to display the name .. GENERATED FROM PYTHON SOURCE LINES 157-162 .. code-block:: default tb = TextBlock2D(text="Tesseract", position=(900, 950), font_size=20) showm.scene.add(tb) .. GENERATED FROM PYTHON SOURCE LINES 163-165 Define a timer_callback in which we'll update the vertices of point and lines actor using `rotate4D`. .. GENERATED FROM PYTHON SOURCE LINES 165-190 .. code-block:: default counter = itertools.count() end = 200 def timer_callback(_obj, _event): global verts3D, angle cnt = next(counter) verts3D = rotate4D(verts4D) if not wireframe: point_verts[:] = initial_verts + \ np.repeat(verts3D, no_vertices, axis=0) utils.update_actor(points) lines = connect_points(verts3D) lines_verts[:] = initial_lines + \ np.reshape(lines, (-1, 3)) utils.update_actor(edges) showm.render() angle += dtheta if cnt == end: showm.exit() .. GENERATED FROM PYTHON SOURCE LINES 191-192 Run every 20 milliseconds .. GENERATED FROM PYTHON SOURCE LINES 192-197 .. code-block:: default showm.add_timer_callback(True, 20, timer_callback) showm.start() window.record(showm.scene, size=(600, 600), out_path="viz_tesseract.png") .. image-sg:: /auto_examples/images/sphx_glr_viz_tesseract_001.png :alt: viz tesseract :srcset: /auto_examples/images/sphx_glr_viz_tesseract_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 4.692 seconds) .. _sphx_glr_download_auto_examples_viz_tesseract.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: viz_tesseract.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: viz_tesseract.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_