diff options
author | lonkaars <loek@pipeframe.xyz> | 2024-01-09 19:52:25 +0100 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2024-01-09 19:52:25 +0100 |
commit | 8424afbd3636407a4e619b01f7c47a4fa0987947 (patch) | |
tree | 6f15d20f816ee102d47a5e180b0ede40b3cbea1c /circrect.py | |
parent | 251f03c22057f93daea2f38c6d8f693970cfc19f (diff) |
alles afgemaakt
Diffstat (limited to 'circrect.py')
-rw-r--r-- | circrect.py | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/circrect.py b/circrect.py index e85ed77..a1dd27c 100644 --- a/circrect.py +++ b/circrect.py @@ -1,40 +1,43 @@ from numbers import Number +from math import sqrt, asin def clamp(low: Number, high: Number, num: Number) -> Number: """Limit range of ``num`` between ``low`` and ``high``""" return max(low, min(high, num)) -def circrect(a: Number, b: tuple[Number, Number], c: tuple[Number, Number]) -> Number: +def circrect(a: tuple[Number, Number], b: tuple[Number, Number], c: Number = 1) -> Number: """ - Calculate the area of the overlap between a circle with radius ``a`` and a - rectangle defined by opposing corner points ``b`` and ``c``. + Calculate the area of the overlap between a rectangle defined by opposing + corner points ``a`` and ``b`` and a circle with radius ``c``. Args: - a: circle radius - b: first corner coordinate of rectangle - c: second corner coordinate of rectangle (opposite of b) + a: first corner coordinate of rectangle + b: second corner coordinate of rectangle (opposite of b) + c: circle radius (optional, with default of 1) Returns: Overlap area (square units) """ - - # normalize input variables - a = abs(a) - b, c = ( - (min(b[0], c[0]), min(b[1], c[1])), - (max(b[0], c[0]), max(b[1], c[1])), - ) - b = (clamp(-a, a, b[0]), clamp(-a, a, b[1])) - c = (clamp(-a, a, c[0]), clamp(-a, a, c[1])) - - return 0 - -if __name__ == "__main__": - print( - circrect(1, (-1, -1), (1, 1)), # pi - circrect(1, (1, 1), (-1, -1)), # pi - circrect(-1, (-1, -1), (1, 1)), # pi - circrect(2, (10, 10), (11, 11)), # 0 - circrect(10, (0, 0), (1, 1)), # 1 + # input variable normalization + a, b = ( + (min(a[0], b[0]), min(a[1], b[1])), + (max(a[0], b[0]), max(a[1], b[1])), ) + c = abs(c) + a = (clamp(-1, 1, a[0] / c), clamp(-1, 1, a[1] / c)) + b = (clamp(-1, 1, b[0] / c), clamp(-1, 1, b[1] / c)) + + # can not have shared area if ab already has no area + if a == b: return 0.0 + + f = lambda x: sqrt(1 - x**2) + F = lambda x, n: 0.5 * (2*n*x + sqrt(1 - x**2)*x + asin(x)) + g = lambda a, b: F(clamp(a[0], b[0], f(a[1])), -a[1]) \ + - F(clamp(a[0], b[0], -f(a[1])), -a[1]) \ + - F(clamp(a[0], b[0], f(b[1])), -b[1]) \ + + F(clamp(a[0], b[0], -f(b[1])), -b[1]) + h = lambda a, b: g((a[0], max(0, a[1])), (b[0], max(0, b[1]))) \ + + g((a[0], max(0, -b[1])), (b[0], max(0, -a[1]))) + o = h(a, b) * (c ** 2) + return o |