0
# Measurement and Analysis
1
2
Standalone functions for computing geometric properties and triangle analysis capabilities including areas, volumes, triangle classification, and spatial relationships.
3
4
## Capabilities
5
6
### Area and Volume Functions
7
8
Standalone measurement functions for computing areas and volumes from point coordinates without creating spatial object instances.
9
10
```python { .api }
11
def area_triangle(point_a, point_b, point_c) -> np.float64:
12
"""
13
Calculate area of triangle from three vertices.
14
15
The points are the vertices of the triangle and must be 3D or less.
16
17
Parameters:
18
- point_a: array-like, first vertex
19
- point_b: array-like, second vertex
20
- point_c: array-like, third vertex
21
22
Returns:
23
Area of the triangle using cross product formula
24
25
References:
26
http://mathworld.wolfram.com/TriangleArea.html
27
"""
28
29
def volume_tetrahedron(point_a, point_b, point_c, point_d) -> np.float64:
30
"""
31
Calculate volume of tetrahedron from four vertices.
32
33
The points are the vertices of the tetrahedron and must be 3D or less.
34
35
Parameters:
36
- point_a: array-like, first vertex
37
- point_b: array-like, second vertex
38
- point_c: array-like, third vertex
39
- point_d: array-like, fourth vertex
40
41
Returns:
42
Volume of the tetrahedron using scalar triple product
43
44
References:
45
http://mathworld.wolfram.com/Tetrahedron.html
46
"""
47
48
def area_signed(points) -> float:
49
"""
50
Calculate signed area of 2D polygon using shoelace formula.
51
52
A positive area is returned for counter-clockwise vertex sequences.
53
54
Parameters:
55
- points: array-like, 2D coordinates of polygon vertices
56
57
Returns:
58
Signed area of the polygon
59
60
Raises:
61
ValueError if points are not 2D or fewer than 3 points provided
62
63
References:
64
https://en.wikipedia.org/wiki/Shoelace_formula
65
"""
66
```
67
68
**Usage Example:**
69
```python
70
from skspatial.measurement import area_triangle, volume_tetrahedron, area_signed
71
72
# Calculate triangle area
73
area = area_triangle([0, 0], [0, 1], [1, 0]) # 0.5
74
75
# Calculate triangle area in 3D
76
area_3d = area_triangle([3, -5, 1], [5, 2, 1], [9, 4, 2]) # 12.54
77
78
# Calculate tetrahedron volume
79
volume = volume_tetrahedron([0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]) # 0.167
80
81
# Calculate signed area of polygon
82
# Counter-clockwise gives positive area
83
area_ccw = area_signed([[0, 0], [1, 0], [0, 1]]) # 0.5
84
# Clockwise gives negative area
85
area_cw = area_signed([[0, 0], [0, 1], [1, 0]]) # -0.5
86
```
87
88
### Triangle Analysis
89
90
Comprehensive triangle analysis including geometric properties, classification, and special point calculations.
91
92
```python { .api }
93
class Triangle:
94
"""
95
A triangle defined by three vertices.
96
97
Parameters:
98
- point_a: array-like, first vertex
99
- point_b: array-like, second vertex
100
- point_c: array-like, third vertex
101
"""
102
def __init__(self, point_a, point_b, point_c): ...
103
104
@property
105
def point_a(self) -> Point:
106
"""First vertex of the triangle."""
107
108
@property
109
def point_b(self) -> Point:
110
"""Second vertex of the triangle."""
111
112
@property
113
def point_c(self) -> Point:
114
"""Third vertex of the triangle."""
115
116
@property
117
def dimension(self) -> int:
118
"""Dimension of the triangle."""
119
120
def multiple(self, name_method, inputs) -> tuple:
121
"""
122
Apply method to multiple inputs.
123
124
Parameters:
125
- name_method: str, name of method to apply
126
- inputs: sequence, inputs to apply method to
127
128
Returns:
129
Tuple of results from applying method to each input
130
"""
131
132
def normal(self) -> Vector:
133
"""
134
Calculate normal vector to triangle plane.
135
136
Returns:
137
Normal vector using cross product of edge vectors
138
"""
139
140
def area(self) -> np.float64:
141
"""
142
Calculate area of the triangle.
143
144
Returns:
145
Triangle area using cross product formula
146
"""
147
148
def perimeter(self) -> np.float64:
149
"""
150
Calculate perimeter of the triangle.
151
152
Returns:
153
Sum of all three side lengths
154
"""
155
156
def point(self, vertex) -> Point:
157
"""
158
Get vertex by letter designation.
159
160
Parameters:
161
- vertex: str, vertex letter ('A', 'B', or 'C')
162
163
Returns:
164
Corresponding vertex point
165
"""
166
167
def line(self, side) -> Line:
168
"""
169
Get line along specified side.
170
171
Parameters:
172
- side: str, side letter ('a', 'b', or 'c')
173
'a' is opposite vertex A (BC edge)
174
'b' is opposite vertex B (AC edge)
175
'c' is opposite vertex C (AB edge)
176
177
Returns:
178
Line along the specified side
179
"""
180
181
def length(self, side) -> np.float64:
182
"""
183
Get length of specified side.
184
185
Parameters:
186
- side: str, side letter ('a', 'b', or 'c')
187
188
Returns:
189
Length of the specified side
190
"""
191
192
def angle(self, vertex) -> float:
193
"""
194
Calculate interior angle at specified vertex.
195
196
Parameters:
197
- vertex: str, vertex letter ('A', 'B', or 'C')
198
199
Returns:
200
Interior angle in radians at the vertex
201
"""
202
203
def centroid(self) -> Point:
204
"""
205
Calculate centroid (center of mass) of triangle.
206
207
Returns:
208
Centroid point (average of vertices)
209
"""
210
211
def altitude(self, vertex) -> Line:
212
"""
213
Get altitude line from specified vertex.
214
215
Parameters:
216
- vertex: str, vertex letter ('A', 'B', or 'C')
217
218
Returns:
219
Altitude line from vertex perpendicular to opposite side
220
"""
221
222
def orthocenter(self, **kwargs) -> Point:
223
"""
224
Calculate orthocenter (intersection of altitudes).
225
226
Parameters:
227
- **kwargs: additional keywords passed to line intersection
228
229
Returns:
230
Orthocenter point where altitudes meet
231
"""
232
233
def classify(self, **kwargs) -> str:
234
"""
235
Classify triangle by side lengths.
236
237
Parameters:
238
- **kwargs: additional keywords passed to numpy.allclose
239
240
Returns:
241
Classification string: 'equilateral', 'isosceles', or 'scalene'
242
"""
243
244
def is_right(self, **kwargs) -> bool:
245
"""
246
Check if triangle is a right triangle.
247
248
Parameters:
249
- **kwargs: additional keywords passed to math.isclose
250
251
Returns:
252
True if triangle has a right angle (90 degrees)
253
"""
254
255
def plot_2d(self, ax_2d, part='points', **kwargs):
256
"""
257
Plot triangle in 2D.
258
259
Parameters:
260
- ax_2d: matplotlib Axes, 2D plotting axes
261
- part: str, what to plot ('points', 'edges', or 'all')
262
- **kwargs: additional keywords passed to plotting functions
263
"""
264
265
def plot_3d(self, ax_3d, part='points', **kwargs):
266
"""
267
Plot triangle in 3D.
268
269
Parameters:
270
- ax_3d: matplotlib Axes3D, 3D plotting axes
271
- part: str, what to plot ('points', 'edges', or 'all')
272
- **kwargs: additional keywords passed to plotting functions
273
"""
274
```
275
276
**Usage Example:**
277
```python
278
from skspatial.objects import Triangle
279
import numpy as np
280
281
# Create triangle from three vertices
282
triangle = Triangle([0, 0], [3, 0], [1.5, 2.6])
283
284
# Calculate basic properties
285
area = triangle.area() # 3.9
286
perimeter = triangle.perimeter() # ~9.2
287
centroid = triangle.centroid() # Point([1.5, 0.87])
288
289
# Get vertices and sides
290
vertex_a = triangle.point('A') # Point([0, 0])
291
side_a = triangle.line('a') # Line from B to C
292
length_a = triangle.length('a') # Length of BC
293
294
# Calculate angles
295
angle_a = triangle.angle('A') # Angle at vertex A in radians
296
angle_degrees = np.degrees(angle_a) # Convert to degrees
297
298
# Classify triangle
299
classification = triangle.classify() # 'scalene'
300
is_right = triangle.is_right() # False
301
302
# Special points
303
orthocenter = triangle.orthocenter()
304
altitude_a = triangle.altitude('A') # Altitude from A to BC
305
306
# Right triangle example
307
right_triangle = Triangle([0, 0], [3, 0], [0, 4])
308
is_right = right_triangle.is_right() # True
309
classification = right_triangle.classify() # 'scalene' (3-4-5 triangle)
310
311
# Equilateral triangle example
312
import math
313
height = math.sqrt(3) / 2
314
equilateral = Triangle([0, 0], [1, 0], [0.5, height])
315
classification = equilateral.classify() # 'equilateral'
316
angle_60 = equilateral.angle('A') # π/3 radians (60 degrees)
317
```