summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2024-01-09 19:52:25 +0100
committerlonkaars <loek@pipeframe.xyz>2024-01-09 19:52:25 +0100
commit8424afbd3636407a4e619b01f7c47a4fa0987947 (patch)
tree6f15d20f816ee102d47a5e180b0ede40b3cbea1c
parent251f03c22057f93daea2f38c6d8f693970cfc19f (diff)
alles afgemaakt
-rw-r--r--circrect.py53
-rw-r--r--circrect.tex59
-rw-r--r--refs.bib18
3 files changed, 96 insertions, 34 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
diff --git a/circrect.tex b/circrect.tex
index 8411fe8..d64e32e 100644
--- a/circrect.tex
+++ b/circrect.tex
@@ -13,6 +13,7 @@
bibencoding=utf8,
]{biblatex}
\usepackage{tikz}
+\usepackage{needspace}
\usetikzlibrary{patterns}
\lstset{
@@ -233,25 +234,64 @@ F\left(x,n\right)&=\int\left(f\left(x\right) + n\right) dx\\
\end{aligned}
\end{equation}
-Nu kan een complete functie $g$ beschreven worden:
-\begin{equation}\label{eq:fn:g}
-g\left(a,b\right) = \text{TODO}
-\end{equation}
+\needspace{3cm}
+Nu kan een nieuwe functie $g$ beschreven worden die alleen afhankelijk is van
+ingevoerde variabelen:
+\begin{align}
+\begin{split}
+o ={}& o_a - o_b
+\end{split}\\
+\begin{split}
+={} &\int_{x_{a_1}}^{x_{a_2}}f_a\left(x\right)dx\\
+ - &\int_{x_{b_1}}^{x_{b_2}}f_b\left(x\right)dx
+\end{split}\\
+\begin{split}
+={} &\int_{x_{a_1}}^{x_{a_2}}\left(f\left(x\right)-a_y\right)dx\\
+ - &\int_{x_{b_1}}^{x_{b_2}}\left(f\left(x\right)-b_y\right)dx
+\end{split}\\
+\begin{split}
+={} &\left(F\left(x_{a_2}, -a_y\right) - F\left(x_{a_1}, -a_y\right)\right)\\
+ - &\left(F\left(x_{b_2}, -b_y\right) - F\left(x_{b_1}, -b_y\right)\right)
+\end{split}\\
+\begin{split}
+={} &F\left(x_{a_2}, -a_y\right) - F\left(x_{a_1}, -a_y\right)\\
+ - &F\left(x_{b_2}, -b_y\right) + F\left(x_{b_1}, -b_y\right)
+\end{split}\\
+\begin{split}\label{eq:fn:g}
+g\left(a,b\right)
+={} &F\left(\clamp\left(a_x,b_x, f\left(a_y\right)\right), -a_y\right)\\
+ - &F\left(\clamp\left(a_x,b_x,-f\left(a_y\right)\right), -a_y\right)\\
+ - &F\left(\clamp\left(a_x,b_x, f\left(b_y\right)\right), -b_y\right)\\
+ + &F\left(\clamp\left(a_x,b_x,-f\left(b_y\right)\right), -b_y\right)
+\end{split}
+\end{align}
De complete oplossing bestaat uit de functie $g$ \'e\'en keer normaal berekenen, en
nog een keer met de rechthoek $ab$ gespiegeld om de $x$-as (vermenigvuldig $a_y$ en
$b_y$ met $-1$). De som van deze twee waarden vormt oppervlak $o$.
+
+Let op dat bij de gespiegelde aanroep van functie $g$, de $y$-co\"ordinaten van de
+punten $a$ en $b$ omgedraaid zijn, om de eisen uit
+\cref{eq:constrain:x,eq:constrain:y} te waarborgen.
\begin{equation}\label{eq:fn:h}
\begin{aligned}[c]
h\left(a,b\right)
- = g\,(&\left(a_x,\max\left(0,a_y\right)\right),\\
- &\left(b_x, \max\left(0,b_y\right)\right))\\
- + g\,(&\left(a_x,\max\left(0,-a_y\right)\right),\\
- &\left(b_x, \max\left(0,-b_y\right)\right)
+ = g\,(&\left(a_x, \max\left(0, a_y\right)\right),\\
+ &\left(b_x, \max\left(0, b_y\right)\right))\\
+ + g\,(&\left(a_x, \max\left(0,-b_y\right)\right),\\
+ &\left(b_x, \max\left(0,-a_y\right)\right)
)
\end{aligned}
\end{equation}
+De Python implementatie in bijlage \ref{attach:python-impl} heeft enkele handige
+toevoegingen:
+\begin{itemize}
+ \item Invoergetallen worden automatisch genormaliseerd
+ \item De formule schaalt het oppervlak $o$ automatisch voor elke willekeurige
+ straal van cirkel $c$
+\end{itemize}
+
\section*{Colofon}
Ik heb geen wiskunde gestudeerd, en kan geen bewijs geven dat de methode die
@@ -266,4 +306,7 @@ beschreven is in dit document foutloos is.
\fontsize{8.5}{12}\selectfont
\lstinputlisting{circrect.py}
+Dit document \autocite{self}, en de bovenstaande broncode \autocite{selfsrc} zijn ook
+online beschikbaar.
+
\end{document}
diff --git a/refs.bib b/refs.bib
index 9535627..83ff217 100644
--- a/refs.bib
+++ b/refs.bib
@@ -8,9 +8,25 @@
@online{circrect2,
title = {circrect2},
- url = {https://www.desmos.com/calculator/zudzhuj9yi},
+ url = {https://www.desmos.com/calculator/e8u2i24zza},
author = {Loek Le Blansch},
date = {2024-01-08},
urldate = {2024-01-08},
}
+@online{self,
+ title = {Exacte berekening van het gedeelde oppervlak van een cirkel en een rechthoek},
+ url = {https://media.pipeframe.xyz/circrect.pdf},
+ author = {Loek Le Blansch},
+ date = {2024-01-09},
+ urldate = {2024-01-09},
+}
+
+@online{selfsrc,
+ title = {circrect repository},
+ url = {https://git.pipeframe.xyz/lonkaars/circrect},
+ author = {Loek Le Blansch},
+ date = {2024-01-09},
+ urldate = {2024-01-09},
+}
+