Skip to content

Sweetspot module

ray

A ray \(R\) in three-dimensional space ( \(\mathbb{R}^3\) ).

Author: Audun Skau Hansen (audunsh4@gmail.com), 2022

Defined as the set of all points \(\mathbf{P}\) on a line segment extending to infinity from the cartesian origin vector \(\mathbf{O}\) in the normalized direction \(\mathbf{D}\): $$ \mathbf{P} = \mathbf{O} + a \mathbf{D}, ag{1} $$ where \(a\) is a real, positive number.

Arguments Description
origin a 3-component numpy-array defining the rays origin
direction a 3-component numpy array defining the direction of the ray (will be normalized automatically)
Source code in sweetspot/core.py
 2
 3
 4
 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
class ray():
    """
    A *ray* $R$ in three-dimensional space ( $\mathbb{R}^3$ ).

    Author: Audun Skau Hansen (audunsh4@gmail.com), 2022 

    Defined as the set of all points $\mathbf{P}$  on a line 
    segment extending to infinity from the cartesian origin 
    vector $\mathbf{O}$ in the normalized *direction* $\mathbf{D}$:
    $$ \mathbf{P} = \mathbf{O} + a \mathbf{D},  \tag{1} $$
    where $a$ is a real, positive number.

    | Arguments      | Description |
    | ----------- | ----------- |
    | origin     | a 3-component numpy-array defining the rays origin   |
    | direction   | a 3-component numpy array defining the direction of the ray   (will be normalized automatically)  |

    """
    def __init__(self, origin:np.ndarray, direction:np.ndarray)->None:
        self.origin = origin

        # note that direction is automatically normalized
        self.direction = direction/np.dot(direction, direction)**.5

    def get_point_at(self, a: float)->np.ndarray:
        """
        Returns the point:

        $$\mathbf{P}(a) = \mathbf{O} + a \mathbf{D}$$

        """
        assert(a>=0), "Requested point is outside ray"
        return self.origin + self.direction*a

get_point_at(a)

Returns the point:

\[\mathbf{P}(a) = \mathbf{O} + a \mathbf{D}\]
Source code in sweetspot/core.py
26
27
28
29
30
31
32
33
34
def get_point_at(self, a: float)->np.ndarray:
    """
    Returns the point:

    $$\mathbf{P}(a) = \mathbf{O} + a \mathbf{D}$$

    """
    assert(a>=0), "Requested point is outside ray"
    return self.origin + self.direction*a

triangle

A triangle in three-dimensional space ( \(\mathbb{R}^3\) ).

Author: Audun Skau Hansen (audunsh4@gmail.com), 2022

Arguments Description
x1,x2,x3 3-component numpy-arrays defining the vertices of the triangle
Source code in sweetspot/core.py
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
class triangle():
    """
    A triangle in three-dimensional space ( $\mathbb{R}^3$ ).

    Author: Audun Skau Hansen (audunsh4@gmail.com), 2022

    | Arguments      | Description |
    | ----------- | ----------- |
    | x1,x2,x3     |  3-component numpy-arrays defining the vertices of the triangle   |

    """
    def __init__(self, x1:np.ndarray, x2:np.ndarray, x3:np.ndarray):
        self.X = [x1,x2,x3]

    def compute_norm(self):
        """
        computes the norm (normalized) of the triangle
        """
        n = np.cross(self.X[0]- self.X[1], self.X[0]-self.X[2])
        return n/np.dot(n,n)**.5

    def compute_distance_to_origin(self)->float:
        """
        Compute distance from (0,0,0) to the plane spanned by the triangle.
        """
        return self.compute_norm().dot(self.X[0])

    def compute_edge_vector(self,i,j)->np.ndarray:
        """
        Computes the edge-vector between vertex $i$ and $j$.
        """
        return self.X[i] - self.X[j]

    def compute_area(self, points = None)->np.ndarray:
        """
        Computes the area of the triangle.
        """
        if points is None:
            points = self.X

        A_ = np.cross(points[1]-points[0], points[2]-points[0])
        return .5*np.dot(A_, A_)**.5


    def compute_barycentric_coordinates_area(self, point)->np.ndarray:
        """
        Compute the barycentric coordinates of point,
        assuming it is on the plane spanne by triangle
        using the area method
        [https://en.wikipedia.org/wiki/Barycentric_coordinate_system#Barycentric_coordinates_on_triangles]
        """
        x1,x2,x3 = self.X

        W  = self.compute_area()
        u1 = self.compute_area(points = [x1,x2,point])/W
        u2 = self.compute_area(points = [x2,x3,point])/W
        u3 = 1-u1-u2
        #w3 = self.compute_area(points = [x1,x2,point])
        return np.array([u1,u2,u3])

    def compute_barycentric_coordinates(self, point)->np.ndarray:
        """
        Compute the barycentric coordinates of point,
        assuming it is on the plane spanned by triangle
        using Cramer's rule 
        [http://lavalle.pl/vr/node206.html]
        """
        x1,x2,x3 = self.X
        e1,e2 = x2-x1, x3-x1
        w = point-x1

        # compute matrix elements
        d00 = e1.dot(e1)
        d01 = e1.dot(e2)
        d02 = e1.dot(w)
        d11 = e2.dot(e2)
        d12 = e2.dot(w)

        det = 1/(d00*d11 - d01*d01)

        u2 = det*(d00*d12 - d01*d02)
        u1 = det*(d11*d02 - d01*d12)
        u0 = 1-u2-u1
        return np.array([u0,u1,u2])



    def get_corner(self, i)->np.ndarray:
        """
        Returns the corner $i$.
        """
        return self.X[i]

compute_area(points=None)

Computes the area of the triangle.

Source code in sweetspot/core.py
69
70
71
72
73
74
75
76
77
def compute_area(self, points = None)->np.ndarray:
    """
    Computes the area of the triangle.
    """
    if points is None:
        points = self.X

    A_ = np.cross(points[1]-points[0], points[2]-points[0])
    return .5*np.dot(A_, A_)**.5

compute_barycentric_coordinates(point)

Compute the barycentric coordinates of point, assuming it is on the plane spanned by triangle using Cramer's rule [http://lavalle.pl/vr/node206.html]

Source code in sweetspot/core.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
def compute_barycentric_coordinates(self, point)->np.ndarray:
    """
    Compute the barycentric coordinates of point,
    assuming it is on the plane spanned by triangle
    using Cramer's rule 
    [http://lavalle.pl/vr/node206.html]
    """
    x1,x2,x3 = self.X
    e1,e2 = x2-x1, x3-x1
    w = point-x1

    # compute matrix elements
    d00 = e1.dot(e1)
    d01 = e1.dot(e2)
    d02 = e1.dot(w)
    d11 = e2.dot(e2)
    d12 = e2.dot(w)

    det = 1/(d00*d11 - d01*d01)

    u2 = det*(d00*d12 - d01*d02)
    u1 = det*(d11*d02 - d01*d12)
    u0 = 1-u2-u1
    return np.array([u0,u1,u2])

compute_barycentric_coordinates_area(point)

Compute the barycentric coordinates of point, assuming it is on the plane spanne by triangle using the area method [https://en.wikipedia.org/wiki/Barycentric_coordinate_system#Barycentric_coordinates_on_triangles]

Source code in sweetspot/core.py
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def compute_barycentric_coordinates_area(self, point)->np.ndarray:
    """
    Compute the barycentric coordinates of point,
    assuming it is on the plane spanne by triangle
    using the area method
    [https://en.wikipedia.org/wiki/Barycentric_coordinate_system#Barycentric_coordinates_on_triangles]
    """
    x1,x2,x3 = self.X

    W  = self.compute_area()
    u1 = self.compute_area(points = [x1,x2,point])/W
    u2 = self.compute_area(points = [x2,x3,point])/W
    u3 = 1-u1-u2
    #w3 = self.compute_area(points = [x1,x2,point])
    return np.array([u1,u2,u3])

compute_distance_to_origin()

Compute distance from (0,0,0) to the plane spanned by the triangle.

Source code in sweetspot/core.py
57
58
59
60
61
def compute_distance_to_origin(self)->float:
    """
    Compute distance from (0,0,0) to the plane spanned by the triangle.
    """
    return self.compute_norm().dot(self.X[0])

compute_edge_vector(i, j)

Computes the edge-vector between vertex \(i\) and \(j\).

Source code in sweetspot/core.py
63
64
65
66
67
def compute_edge_vector(self,i,j)->np.ndarray:
    """
    Computes the edge-vector between vertex $i$ and $j$.
    """
    return self.X[i] - self.X[j]

compute_norm()

computes the norm (normalized) of the triangle

Source code in sweetspot/core.py
50
51
52
53
54
55
def compute_norm(self):
    """
    computes the norm (normalized) of the triangle
    """
    n = np.cross(self.X[0]- self.X[1], self.X[0]-self.X[2])
    return n/np.dot(n,n)**.5

get_corner(i)

Returns the corner \(i\).

Source code in sweetspot/core.py
123
124
125
126
127
def get_corner(self, i)->np.ndarray:
    """
    Returns the corner $i$.
    """
    return self.X[i]