ddg.math.grids module

This module provides functions to create quad and triangle grids.

ddg.math.grids.quad_grid(shape)[source]

Create a rectangular grid of the input shape.

Returns the quad faces and points of a box grid in Z^2 or Z^3.

Parameters:
shapetuple of length 2 or 3

Shape of the grid. The first entry defines the number of vertices in the first coordinate axis, the second the number of vertices in the second coordinate axid and the third (if given) the number of vertices in the third coordinate axis.

Returns:
facesnp.ndarray of shape (k, 4)

The quad faces of the grid, where k is the number of faces.

coordinatesnp.ndarray

Default coordinates which start at (0,0) (or (0,0,0)) and expand to the specified values of shape.

The shape of the array is (n, 2) if the input shape has length 2, otherwise it is (n, 3).

Raises:
ValueError

If the given shape does not have .ndim 2 or 3.

Examples

>>> from ddg.math.grids import quad_grid
>>> faces, coords = quad_grid((2, 3))
>>> faces
array([[0, 1, 3, 2],
       [2, 3, 5, 4]])
>>> coords
array([[0, 0],
       [1, 0],
       [0, 1],
       [1, 1],
       [0, 2],
       [1, 2]])

In the 3D case we get

>>> from ddg.math.grids import quad_grid
>>> faces, coords = quad_grid((2, 2, 2))
>>> faces
array([[0, 1, 3, 2],
       [4, 5, 7, 6],
       [0, 1, 5, 4],
       [2, 3, 7, 6],
       [0, 2, 6, 4],
       [1, 3, 7, 5]])
>>> coords
array([[0, 0, 0],
       [1, 0, 0],
       [0, 1, 0],
       [1, 1, 0],
       [0, 0, 1],
       [1, 0, 1],
       [0, 1, 1],
       [1, 1, 1]])
ddg.math.grids.triangulate_quads(quads)[source]

Subdivide quads into lower left and upper right triangles.

Parameters:
quadsnp.ndarray of shape (n, 4)

The quad faces of the grid, where n is the number of faces.

Returns:
np.ndarray of shape (n*2, 3)

The triangle faces of the given quad faces, where n*2 is the number of triangle faces.

Examples

>>> import numpy as np
>>> from ddg.math.grids import triangulate_quads
>>> quad_faces = np.array([[0, 1, 4, 3], [1, 2, 5, 4]])
>>> triangulate_quads(quad_faces)
array([[0, 1, 4],
       [1, 2, 5],
       [0, 4, 3],
       [1, 5, 4]])
ddg.math.grids.triangle_grid(shape)[source]

Create a triangle grid of the input shape.

The input shape defines the amount of vertices in each direction. Both 2D and 3D are supported. Returns the faces and default coordinates. Currently, the 3D version only supports (m, n, 1) for the shape.

A shape of (2, 3) will return the following combinatorics

      o-----o
     / \   /
    /   \ /
   o-----o
  / \   /
 /   \ /
o-----o
Parameters:
shapetuple of length 2 or 3

Shape of the grid. The first entry defines the number of vertices in the first coordinate axis, the second the number of vertices in the second coordinate axid and the third (if given) the number of vertices in the third coordinate axis.

Returns:
facesnp.ndarray of shape (k, 3)

The faces of the triangle grid, where k is the number of faces.

coordinatesnp.ndarray

The default coordinates which start at (0,0) (or (0,0,0)) and expand to the specified values of shape.

The shape of the array is (n, 2) if the input shape has length 2, otherwise it is (n, 3).

The coordinates get spanned by the basis vectors

\[b_1 = (2, 0), \quad b_2 = (1, 2)\]

See examples for more detail.

Raises:
ValueError

If the given shape has .ndim 3 and shape[2] != 1.

ValueError

If the given shape does not have .ndim 2 or 3.

Notes

Currently supports planar 3D grids only. Meaning you can only put in a shape of (m, n, 1) or use (m, n) for 2D grids.

Examples

>>> from ddg.math.grids import triangle_grid
>>> faces, coords = triangle_grid((2, 3))
>>> faces
array([[0, 1, 2],
       [2, 3, 4],
       [1, 3, 2],
       [3, 5, 4]])
>>> coords
array([[0, 0],
       [2, 0],
       [1, 2],
       [3, 2],
       [2, 4],
       [4, 4]])

In the 3D case we get

>>> faces, coords = triangle_grid((2, 3, 1))
>>> faces
array([[0, 1, 2],
       [2, 3, 4],
       [1, 3, 2],
       [3, 5, 4]])
>>> coords
array([[0, 0, 0],
       [2, 0, 0],
       [1, 2, 0],
       [3, 2, 0],
       [2, 4, 0],
       [4, 4, 0]])
ddg.math.grids.triangulated_quad_grid(shape)[source]

Create a triangled quad grid of the input shape.

The input shape defines the number of vertices in each direction. Both 2D and 3D are supported. Returns the faces and default coordinates.

A shape of (2, 3) will return the following combinatorics

o-----o
|   / |
| /   |
o-----o
|   / |
| /   |
o-----o
Parameters:
shapetuple of length 2 or 3

Shape of the grid. The first entry defines the number of vertices in the first coordinate axis, the second the number of vertices in the second coordinate axid and the third (if given) the number of vertices in the third coordinate axis.

Returns:
facesnp.ndarray of shape (k, 3)

The faces of the triangle grid, where k is the number of faces.

coordinatesnp.ndarray

The default coordinates which start at (0,0) (or (0,0,0)) and expand to the specified values of shape.

The shape of the array is (n, 2) if the input shape has length 2, otherwise it is (n, 3).

Examples

>>> from ddg.math.grids import triangulated_quad_grid
>>> faces, coords = triangulated_quad_grid((2, 3))
>>> faces
array([[0, 1, 3],
       [2, 3, 5],
       [0, 3, 2],
       [2, 5, 4]])
>>> coords
array([[0, 0],
       [1, 0],
       [0, 1],
       [1, 1],
       [0, 2],
       [1, 2]])

In the 3D case we get

>>> faces, coords = triangulated_quad_grid((2, 2, 2))
>>> faces
array([[0, 1, 3],
       [4, 5, 7],
       [0, 1, 5],
       [2, 3, 7],
       [0, 2, 6],
       [1, 3, 7],
       [0, 3, 2],
       [4, 7, 6],
       [0, 5, 4],
       [2, 7, 6],
       [0, 6, 4],
       [1, 7, 5]])
>>> coords
array([[0, 0, 0],
       [1, 0, 0],
       [0, 1, 0],
       [1, 1, 0],
       [0, 0, 1],
       [1, 0, 1],
       [0, 1, 1],
       [1, 1, 1]])
ddg.math.grids.quad_grid_with_periodicity(shape, periodicity=(0, 0))[source]

Create a quad grid of the input shape with a given periodicity.

A quad grid with periodicity (0, 0) is the box in Z^2 with lower-left corner (0, 0) and upper-right corner (shape[0] - 1, shape[1] - 1). In other words, the vertices are (i_0, i_1) with 0 <= i_0 <= shape[0] - 1 and 0 <= i_1 <= shape[1] - 1. A quad grid with periodicity not equal to (0, 0) is obtained from the quad grid with periodicity (0, 0) by gluing the boundary edges as described in the table below.

Parameters:
shapetuple of length 2

Shape of the grid. The first entry defines the number of vertices in the first coordinate axis, the second the number of vertices in the second coordinate axis.

periodicitytuple of length 2 (default=(0,0))

The periodicity of the grid.

Periodicity

Topology

Gluing Axis

(0, 0)

Disk

None

(1, 0)

Cylinder

along the first axis

(0, 1)

Cylinder

along the second axis

(1, 1)

Torus

along both axes

(-1, 0)

Moebius Band

along the first axis in reversed orientation

(0, -1)

Moebius Band

along the second axis in reversed orientation

Returns:
facesnumpy.ndarray of shape (k, 4)

The faces of the quad grid, where k is the number of faces.

coordinatesnumpy.ndarray

The default coordinates. The shape of the array is (n, 2).

uv_coordinatesnumpy.ndarray

Returned only if periodicity != (0, 0). Stores the corresponding coordinates in Z^2. The shape of the array is (n, 2).

Raises:
ValueError

If shape or periodicity doesn’t have the correct length or invalid values.

See also

ddg.math.grids.quad_grid

Sub-grids of Z^n without any gluing.

Examples

>>> from ddg.math.grids import quad_grid_with_periodicity
>>> faces, coords, uv_coords = quad_grid_with_periodicity((2, 3), (1, 0))
>>> faces
array([[0, 1, 3, 2],
       [2, 3, 5, 4],
       [0, 1, 3, 2],
       [2, 3, 5, 4]])
>>> coords
array([[ 1.0000000e+00,  0.0000000e+00,  0.0000000e+00],
       [-1.0000000e+00,  0.0000000e+00,  1.2246468e-16],
       [ 1.0000000e+00,  1.0000000e+00,  0.0000000e+00],
       [-1.0000000e+00,  1.0000000e+00,  1.2246468e-16],
       [ 1.0000000e+00,  2.0000000e+00,  0.0000000e+00],
       [-1.0000000e+00,  2.0000000e+00,  1.2246468e-16]])
ddg.math.grids.quad_grid_sandwich(shape)[source]

Create faces for a rectangle folded in half with overlapping boundaries identified.

Start with a rectangle of shape (2*m-1, n). Fold the rectangle along the line (m, *). Identify overlapping boundary vertices and edges. Topologically the result is a sphere.

For a shape of (3,3) one obtains

-  7--8--9--8--7
|  |  |  |  |  |
n  3--4--5--6--3
|  |  |  |  |  |
-  0--1--2--1--0

   |--m--|
   |---2*m-1---|

where vertices with equal numbers are identified.

Parameters:
shapetuple of length 2

Shape of the folded rectangle viewed from the top. Should be of the form (m, n) with m >= 2, n >= 3.

Returns:
facesnp.ndarray of shape (F, 4)

The faces of the quad grid, where F is the number of faces.

uvnp.ndarray of shape (V, 2)

Integer square grid coordinates for the vertices, where V is the number of vertices.

uv_facesnp.ndarray of shape (F, 2)

Half-integer square grid coordinates for the faces, where F is the number of faces.

Examples

>>> from ddg.math.grids import quad_grid_sandwich
>>> faces, uv, uv_faces = quad_grid_sandwich((2, 3))
>>> faces
array([[0, 1, 3, 2],
       [1, 0, 2, 3],
       [2, 3, 5, 4],
       [3, 2, 4, 5]])
>>> uv
array([[0, 0],
       [1, 0],
       [0, 1],
       [1, 1],
       [0, 2],
       [1, 2]])
>>> uv_faces
array([[1.5, 0.5],
       [1.5, 0.5],
       [1.5, 1.5],
       [1.5, 1.5]])