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 | |
parent | 251f03c22057f93daea2f38c6d8f693970cfc19f (diff) |
alles afgemaakt
-rw-r--r-- | circrect.py | 53 | ||||
-rw-r--r-- | circrect.tex | 59 | ||||
-rw-r--r-- | refs.bib | 18 |
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} @@ -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}, +} + |