Skip to content

angle_defect_intrinsic

angle_defect_intrinsic(l_sq, F, n=None, use_small_angle_approx=True)

Returns the angle defect at each vertex (except at boundary vertices, where it is 0.). The angle defect is a proxy for integrated Gaussian curvature. This function uses only intrinsic information (halfedge lengths squared)

Parameters:

Name Type Description Default
l_sq (m,3) numpy array

squared halfedge lengths as computed by halfedge_lengths_squared

required
F (m,3) numpy int array

face index list of a triangle mesh

required
n int, optional (default None)

number of vertices in the mesh. If absent, will try to infer from F.

None
use_small_angle_approx bool, optional (default True)

If True, uses a different, more more stable formula for small angles.

True

Returns:

Name Type Description
k (n,) numpy array

angle defect at each vertex.

Examples:

V,F = gpy.read_obj("mesh.obj")
l_sq = gpy.halfedge_lengths_squared(V,F)
k = gpy.angle_defect_intrinsic(l_sq,F)
Source code in src/gpytoolbox/angle_defect_intrinsic.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def angle_defect_intrinsic(l_sq,F,n=None,
    use_small_angle_approx=True):
    """Returns the angle defect at each vertex (except at boundary vertices,
    where it is `0`.).
    The angle defect is a proxy for integrated Gaussian curvature.
    This function uses only intrinsic information (halfedge lengths squared)

    Parameters
    ----------
    l_sq : (m,3) numpy array
        squared halfedge lengths as computed by halfedge_lengths_squared
    F : (m,3) numpy int array
        face index list of a triangle mesh
    n : int, optional (default None)
        number of vertices in the mesh.
        If absent, will try to infer from F.
    use_small_angle_approx : bool, optional (default True)
        If True, uses a different, more more stable formula for small angles.

    Returns
    -------
    k : (n,) numpy array
        angle defect at each vertex.

    Examples
    --------
    ```python
    V,F = gpy.read_obj("mesh.obj")
    l_sq = gpy.halfedge_lengths_squared(V,F)
    k = gpy.angle_defect_intrinsic(l_sq,F)
    ```
    """

    assert F.shape[1] == 3
    assert l_sq.shape == F.shape
    assert np.all(l_sq>=0)

    if n==None:
        n = 0

    α = tip_angles_intrinsic(l_sq,F,
        use_small_angle_approx=use_small_angle_approx)
    α_sum = np.bincount(F.ravel(), α.ravel(), minlength=n)

    k = 2.*np.pi - α_sum
    b = boundary_vertices(F)
    k[b] = 0.

    return k