Skip to content

slab_tangent_triangles

slab_tangent_triangles(C, R, F)

Triangles tangent to the three spheres of each medial slab.

A medial face spans a medial slab, the convex hull of its three spheres. Its boundary consists of two triangles tangent to all three spheres (one on each side of the face) and of pieces of the medial cones of its edges. Rendering these triangles is a quick way to visualize the shape represented by a medial mesh.

Parameters:

Name Type Description Default
C (n,3) numpy double array

Sphere centers.

required
R (n,) numpy double array

Sphere radii.

required
F (f,3) numpy int array

Medial faces.

required

Returns:

Name Type Description
T0 (f,3,3) numpy double array

Tangent triangle on the side of the face normal (right-hand rule over F[i]). Corner T0[i, k] touches sphere F[i, k], so T0[i] is oriented like F[i], with its normal pointing away from the slab.

T1 (f,3,3) numpy double array

Tangent triangle on the other side. Corner T1[i, k] touches sphere F[i, k]; use T1[:, [0, 2, 1]] for normals pointing away from the slab.

valid (f,) numpy bool array

False where the tangent triangles do not exist (e.g. coincident spheres); those rows are zero.

Notes

C++: void libmat::slab_tangent_triangles(C, R, F, T0, T1, valid) in <libmat/slab_tangent_triangles.h>, with T0, T1 stored as #F by 9.

Examples:

import numpy as np
import libmat
V, R, E, F = libmat.read_ma("data/bug.ma")
T0, T1, valid = libmat.slab_tangent_triangles(V, R, F)
# as an outward oriented triangle soup
tris = np.concatenate([T0[valid], T1[valid][:, [0, 2, 1]]])
SV = tris.reshape(-1, 3)
SF = np.arange(len(SV)).reshape(-1, 3)

C++

#include <libmat/slab_tangent_triangles.h>

// For every medial face (slab) spanned by three spheres, compute the two
// triangles that are tangent to all three spheres. Together with the medial
// cones they form the boundary of the medial slab, i.e. the reconstructed
// surface of a medial mesh.
//
// Inputs:
//   C  #V by 3 sphere centers
//   R  #V sphere radii
//   F  #F by 3 medial faces
// Outputs:
//   T0     #F by 9 tangent triangle on the side of the face normal (right-hand
//          rule over F), as (x0 y0 z0 x1 y1 z1 x2 y2 z2); corner k touches
//          sphere F(i, k), so T0 is oriented like F (normal pointing away
//          from the slab)
//   T1     #F by 9 tangent triangle on the other side, corner k touches
//          sphere F(i, k) (flip corners 1 and 2 for an outward normal)
//   valid  #F 1 if the tangent triangles exist, 0 otherwise (e.g. one sphere
//          contains another one); invalid rows are filled with zeros
void slab_tangent_triangles(const Eigen::MatrixXd& C, const Eigen::VectorXd& R,
                            const Eigen::MatrixXi& F, Eigen::MatrixXd& T0,
                            Eigen::MatrixXd& T1, Eigen::VectorXi& valid);