Skip to main content

reuleaux logo

reuleaux

The exact area of the common overlap of three circles: stable, complete, and fast.

Three overlapping circles with the common overlap, its boundary arcs, vertices and centroid

Given any three circles, reuleaux returns the area (and centroid, boundary arcs and vertices) of the region that lies inside all of them. It is the missing building block for mutual transits and eclipses of planets, moons and stars, and for area-proportional Venn diagrams.

Why it is useful

  • Complete. One proof reduces the geometry to five topologies (empty, disk, lens, circular triangle, circular quadrilateral), resolved by a single directed walk along the boundary arcs. No case tree.
  • Correct for arcs longer than π. The classical closed forms (Fewell 2006, Kipping 2011) fail when the overlap contains more than half of a disk, by up to 66% of the area.
  • Backward stable. Against 50-digit references for 21,568 configurations (thin lenses, microscopic triangles, hierarchical star-planet-moon geometries), the error never exceeds 2.01 times the condition number times the unit roundoff.
  • Fast. 45 ns per configuration on average on one CPU core (0.26 µs in the hardest topology) with Numba.
  • Robust against the alternatives. Five public packages (gefera, eulerr, venn.js, matplotlib-venn, Shapely) fail on 121 to 21,568 of 40,000 test configurations through undefined values, missing topologies or lost precision. reuleaux fails on none.

Installation

pip install git+https://github.com/hippke/reuleaux
pip install numba        # optional, 50-500x faster; first call compiles and caches the kernels

Requires Python ≥ 3.9 and NumPy. Matplotlib is only needed for plotting.

Usage

The figure above takes ten lines:

import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Polygon
import reuleaux as rx

circles = [(0, 0, 1.0), (1.05, 0.15, 0.85), (0.45, -0.95, 0.9)]   # (x, y, r)
ov = rx.overlap(*circles)
print(ov.area, ov.case)                                           # 0.2772820698 triangle

fig, ax = plt.subplots()
for (x, y, r), c in zip(circles, ["C0", "C1", "C3"]):
    ax.add_patch(Circle((x, y), r, color=c, alpha=0.3))
ax.add_patch(Polygon(ov.boundary(), color="k", alpha=0.8))        # the common overlap
ax.scatter(*ov.vertices.T)                                        # its corners
ax.set_aspect("equal"); ax.autoscale_view(); plt.show()

The full figure with coloured arcs and labels is made by examples/hero.py.

Just the number:

rx.overlap_area((0, 0, 1), (0.8, 0.3, 0.6), (0.5, -0.4, 0.7))     # 0.357820532455879

A whole light curve at once (NumPy arrays broadcast; a moon crossing a planet on the stellar limb):

import numpy as np
x = np.linspace(0.8, 1.15, 100)
areas = rx.overlap_area_batch(0, 0, 1.0,   0.98, 0, 0.10,   x, 0.02, 0.05)

Everything the result knows:

ov = rx.overlap(c1, c2, c3)
ov.area, ov.case, ov.n_vertices, ov.reflex   # reflex: some boundary arc is longer than pi
ov.vertices, ov.arcs, ov.centroid, ov.boundary()

Command line:

python -m reuleaux area 0 0 1  0.8 0.3 0.6  0.5 -0.4 0.7
python -m reuleaux selftest      # validate against an independent quadrature
python -m reuleaux bench

More in examples/examples.py (exomoon eclipse ratio, degenerate input, the historical Fewell error) and examples/plot_overlaps.py (all paper figures as vector PDFs).

How it works

  1. Drop any disk contained in another; return a disk, a lens or zero if fewer than three remain or a pair is disjoint.
  2. The vertices are the pairwise crossings that lie strictly inside the third disk. There are 0, 2, 3 or 4 of them.
  3. Walk the boundary counter-clockwise, arc by arc.
  4. Apply Green's theorem per arc. The central angle comes from one atan2, so long arcs need no special case, and thin segments use a Taylor series so nothing cancels.

The derivation, proofs and benchmarks are in paper/paper.pdf; working notes are in docs/notes.md.

Tests and benchmarks

pip install -e ".[test]" && pytest
python paper/bench/run_accuracy.py     # regenerate the accuracy study
python paper/bench/make_figures.py     # paper figures

The name reuleaux

The common overlap of three circles whose centres form an equilateral triangle, each circle passing through the other two centres, is a Reuleaux triangle: the curve of constant width named after Franz Reuleaux (1829-1905). It is the prototype of the shape this code computes, in all its deformed variants.

Citing

Please cite the accompanying paper (in preparation); details are in CITATION.cff.

About

Licensed under the GNU General Public License v3.0 (see LICENSE). Developed for the exomoon code Pandora.

Metadata

Release files for reuleaux 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for reuleaux 0.1.0
File Size Uploaded
reuleaux-0.1.0.tar.gz 35.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for reuleaux 0.1.0
File Interpreter ABI Platform
reuleaux-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 68.0 kB

Release files / reuleaux-0.1.0.tar.gz

Download URL reuleaux-0.1.0.tar.gz
Size 35.2 kB
Tags Source
SHA-256 checksum
How to use checksums
1b5f82623bbd1776df8466c9ad2e67b85bf88c0750c618975b2c68a40f7d104f
BLAKE2b-256 checksum
How to use checksums
24ccf5f534764e7b5d9e3d9244817a60072061e4fc7662a13cbb82be85f04b03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.2

Release files / reuleaux-0.1.0-py3-none-any.whl

Download URL reuleaux-0.1.0-py3-none-any.whl
Size 32.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b49a4c6c07ade569834234e3d879cb6668b81b967778008516cd511a3755e5a4
BLAKE2b-256 checksum
How to use checksums
f342daf785623e4fb19a3ddd53dd40f4e3869212c8dd28a3563382341e277cbb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.2

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page