Basic trigonometry

For example, the circumcenter of a triangle, which is the position of the dual Voronoi vertex.

Coding style notes

Throughout, we will (attempt to) provide a type signature for all functions. To do so for array-based functions, we use jaxtyping.

JAX

The aim is to create a triangulation datastructure compatible with the JAX library for automatic differentiation and numerical computing. In practice, this means that we use jnp (=jax.numpy) instead of numpy, and make sure our code follows JAX’s functional programming paradigm (see JAX- the sharp bits).


source

get_polygon_area


def get_polygon_area(
    pts:Float[Array, 'n_vertices 2']
)->Float[Array, '']:

Area of 2D polygon assuming no self-intersection.


source

get_triangle_area


def get_triangle_area(
    a:Float[Array, 'dim'], b:Float[Array, 'dim'], c:Float[Array, 'dim']
)->Float[Array, '']:

Unoriented area of triangle with vertices a, b, c. Works in dim 2 or 3.


source

get_oriented_triangle_area


def get_oriented_triangle_area(
    a:Float[Array, 'dim'], b:Float[Array, 'dim'], c:Float[Array, 'dim']
)->Float[Array, '*']:

Signed area of triangle with vertices a, b, c. If d=2, returns a scalar, if d=3, a vector.


source

get_circumcenter


def get_circumcenter(
    a:Float[Array, 'dim'], b:Float[Array, 'dim'], c:Float[Array, 'dim'], zero_clip:float=1e-10
)->Float[Array, 'dim']:

Return circumcenter coordinates of triangle with vertices a, b, c


source

get_cot_between_vectors


def get_cot_between_vectors(
    a:Float[Array, 'dim'], b:Float[Array, 'dim']
)->Float[Array, '']:

Cotangent of angle between two vectors


source

get_angle_between_vectors


def get_angle_between_vectors(
    a:Float[Array, 'dim'], b:Float[Array, 'dim']
)->Float[Array, '']:

Angle between two vectors


source

get_signed_angle_between_vectors


def get_signed_angle_between_vectors(
    a:Float[Array, '2'], b:Float[Array, '2']
)->Float[Array, '']:

Signed angle between two 2d vectors


source

get_oriented_voronoi_corner_area


def get_oriented_voronoi_corner_area(
    a:Float[Array, 'dim'], b:Float[Array, 'dim'], c:Float[Array, 'dim'], zero_clip:float=1e-10
)->Float[Array, '*']:

Compute oriented Voronoi area at corner a of triangle abc. Returns a vector in 3d. Returns zero for a degenerate triangle.


source

get_voronoi_corner_area


def get_voronoi_corner_area(
    a:Float[Array, 'dim'], b:Float[Array, 'dim'], c:Float[Array, 'dim'], zero_clip:float=1e-10
)->Float[Array, '*']:

Compute Voronoi area at corner a of triangle abc. Returns zero for a degenerate triangle.

get_voronoi_corner_area(jnp.array([0.,0.]), jnp.array([0.,1.]),  jnp.array([1.,0.]))
Array(-0.25, dtype=float64)
get_circumcenter(jnp.array([0.,0.]), jnp.array([0.,1.]),  jnp.array([1.,0.]))
Array([0.5, 0.5], dtype=float64)
get_signed_angle_between_vectors(jnp.array([1.,0.]), jnp.array([0.5,0.5])) * (180/jnp.pi)
Array(45., dtype=float64)
get_polygon_area(jnp.array([[0.,0.], [0.,1.], [1.,0.]]) ), get_triangle_area(*jnp.array([[0.,0.], [0.,1.], [1.,0.]]) )
(Array(0.5, dtype=float64), Array(0.5, dtype=float64))
get_circumcenter(jnp.array([0.,0.]), jnp.array([0.,1.]),  jnp.array([1.,0.]))
Array([0.5, 0.5], dtype=float64)
get_circumcenter(jnp.array([1.,0.]), jnp.array([1.,0.]),  jnp.array([0.,1.]))
Array([0., 0.], dtype=float64)
get_circumcenter(jnp.array([1.,0.]), jnp.array([2.,0.]),  jnp.array([1.,0.]))
Array([0., 0.], dtype=float64)
get_voronoi_corner_area(jnp.array([0.,0.]), jnp.array([0.,1.]),  jnp.array([1.,0.]))
Array(-0.25, dtype=float64)

Normals and rotation matrices in 3D


source

quaternion_to_rot_max


def quaternion_to_rot_max(
    q:Float[Array, '4']
)->Float[Array, '3 3']:

Convert unit quaternion into a 3d rotation matrix.

See https://fr.wikipedia.org/wiki/Quaternions_et_rotation_dans_l%27espace


source

get_triangle_normal


def get_triangle_normal(
    a:Float[Array, '3'], b:Float[Array, '3'], c:Float[Array, '3']
)->Float[Array, '3']:

Compute unit normal vector of triangle abc.


source

get_perp_2d


def get_perp_2d(
    x:Float[Array, '... 2']
)->Float[Array, '... 2']:

Get perpendicular vector.


source

get_rot_mat


def get_rot_mat(
    theta:float
)->Float[Array, '2 2']:

Get 2D rotation matrix from angle in radians.

Barycentric coordinates


source

get_barycentric_coordinates


def get_barycentric_coordinates(
    point:Float[Array, 'dim'], a:Float[Array, 'dim'], b:Float[Array, 'dim'], c:Float[Array, 'dim'],
    zero_clip:float=1e-10, normalize:bool=True
)->Float[Array, '3']:

Compute barycentric coordinates of point with respect to triangle abc.

vertices = jnp.array([[0., 0 ], [0., 1.], [1., 0.]])
point1 = jnp.array([0.5, 0.2])

get_barycentric_coordinates(point1, *vertices, normalize=False)
Array([0. , 0.2, 0.5], dtype=float64)
vertices2 = jnp.array([[0., 0, 0], [0., 1., 0], [1., 0., 0]])
point2 = jnp.array([0.5, 0.2, 0.])

get_barycentric_coordinates(point2, *vertices2, normalize=False)
Array([0. , 0.2, 0.5], dtype=float64)
point3 = jnp.array([0.5, 0.2, 1.])

get_barycentric_coordinates(point3, *vertices2, normalize=False)
Array([0. , 0.2, 0.5], dtype=float64)