-
-
Notifications
You must be signed in to change notification settings - Fork 50.5k
Expand file tree
/
Copy pathshoelace_area.py
More file actions
70 lines (55 loc) · 1.76 KB
/
shoelace_area.py
File metadata and controls
70 lines (55 loc) · 1.76 KB
1
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
35
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
"""
Shoelace formula (Gauss's area formula) for polygon area.
The function accepts an iterable of (x, y) pairs and returns the polygon area
as a non-negative float.
References:
- https://en.wikipedia.org/wiki/Shoelace_formula
"""
from __future__ import annotations
from collections.abc import Iterable, Sequence
def shoelace_area(points: Iterable[tuple[float, float]]) -> float:
"""
Compute the area of a simple polygon using the shoelace formula.
Parameters
----------
points:
Iterable of (x, y) coordinate pairs. Points may be ints or floats.
The polygon is assumed closed (the function will wrap the last point
to the first).
Returns
-------
float
Non-negative area of the polygon.
Raises
------
ValueError
If fewer than 3 points are provided.
TypeError
If points are not pairs of numbers.
Examples
>>> shoelace_area([(0, 0), (4, 0), (0, 3)])
6.0
>>> shoelace_area([(0, 0), (1, 0), (1, 1), (0, 1)])
1.0
>>> shoelace_area(list(reversed([(0, 0), (2, 0), (2, 2), (0, 2)])))
4.0
>>> shoelace_area([(0, 0), (2, 0), (2, 2), (0, 2)])
4.0
"""
pts = list(points)
n = len(pts)
if n < 3:
raise ValueError("At least 3 points are required to form a polygon")
try:
coords: Sequence[tuple[float, float]] = [(float(x), float(y)) for x, y in pts]
except Exception as exc:
raise TypeError("points must be an iterable of (x, y) numeric pairs") from exc
s = 0.0
for i in range(n):
x1, y1 = coords[i]
x2, y2 = coords[(i + 1) % n]
s += x1 * y2 - x2 * y1
return abs(s) / 2.0
if __name__ == "__main__":
example = [(0, 0), (4, 0), (0, 3)]
print("example area:", shoelace_area(example))