Exact Symbolic Demonstrations¶
100% Exact SymPy Polynomial Proofs & geometor.model Compass-and-Straightedge Constructions
Unlike floating-point dynamic geometry sketches, every theorem in Euler (1765) and Feuerbach (1822) is executed and verified symbolically in geometor.feuerbach with zero floating-point approximations.
Canonical Heronian (15, 13, 14) Rational Locus¶
Placing the vertices of the acute scalene Heronian triangle with sides \(a = 15, b = 13, c = 14\) (area \(\Delta = 84\), semiperimeter \(s = 21\)) at integer Cartesian coordinates A = (0, 0), B = (14, 0), C = (5, 12) places all classical centers, tritangent centers, and Feuerbach tangencies strictly inside \(\mathbb{Q}^2\):
Incenter & Incircle: S = X1
= (6, 4), inradius \(r = 4\).Centroid:
F = G = X(2) = (19/3, 4).Circumcenter & Circumcircle:
H = K = X(3) = (7, 33/8), circumradius \(R = \frac{65}{8}\).Orthocenter & Orthic Inradius:
E = O = X(4) = (5, 15/4), orthic inradius \(\rho = \frac{99}{52}\).Nine-Point Center & Circle: L = X5
= (6, 63/16), radius \(R_9 = \frac{65}{16}\).Internal Tangency (Feuerbach Point): X11
= (6, 8), where \(Q(X_5, X_1) = \left(\frac{65}{16} - 4\right)^2 = \frac{1}{256}\).Three External Excircle Tangencies: Fea
= (2709/289, 1792/289), Feb= (553/233, 1344/233), and Fec= (1672/257, -24/257), forming the Feuerbach Triangle \triangle Fea Feb Fec.
Demonstration I: demos/euler_1765_identities.py¶
Verifies all 30 polynomial residuals across Euler (1765) and Feuerbach (1822), solves Euler’s inverse cubic reconstruction \(z^3 - 18z^2 + 107z - 210 = 0\) on (5, 6, 7), and constructs Euler’s four centers by pure compass-and-straightedge:
1"""Executable demonstration of Leonhard Euler's 1765 memoir (E325, §§ 1–34).
2
3Verifies:
41. All six squared mutual center distances (§ 18, I–VI) as exact rational functions of (a, b, c).
52. Collinearity of E = X(4), F = X(2), H = X(3) with EH = (3/2)*EF and FH = (1/2)*EF.
63. Stewart's collinearity law 4*GH^2 + 2*EG^2 = 3*EF^2 + 6*FG^2.
74. Euler's inverse cubic reconstruction z^3 - p*z^2 + q*z - r = 0 on (5, 6, 7).
85. Compass-and-straightedge Model construction on Heronian (15, 13, 14).
9"""
10
11from __future__ import annotations
12
13from rich.console import Console
14from rich.table import Table
15
16from geometor.feuerbach.euler import (
17 construct_euler_1765_centers,
18 prove_euler_1765_identities,
19)
20
21
22def run_demo() -> None:
23 """Execute and print the Euler 1765 symbolic proof and construction report."""
24 console = Console()
25 report = prove_euler_1765_identities()
26 constructed = construct_euler_1765_centers()
27
28 id_table = Table(title="Euler (1765/1767, E325) — Symbolic Polynomial Identities")
29 id_table.add_column("Identity Key", style="cyan")
30 id_table.add_column("Residual", style="bold green")
31 for key, res in report.symbolic_residuals.items():
32 if key.startswith("euler_"):
33 id_table.add_row(key, str(res))
34 console.print(id_table)
35
36 cub = report.euler_cubic_567
37 console.print(
38 f"\n[bold]Euler §§ 21–24 Reconstruction on {cub.sides_expected}:[/bold] "
39 f"EF²={cub.ef_sq}, FG²={cub.fg_sq}, GH²={cub.gh_sq}, EG²={cub.eg_sq}\n"
40 f"Recovered (p, q, r) = ({cub.p_sum}, {cub.q_pairs}, {cub.r_prod}) -> "
41 f"{cub.cubic_poly} = 0 -> roots {cub.recovered_roots}"
42 )
43
44 h = report.heronian_15_13_14
45 console.print(
46 f"\n[bold]Canonical Heronian {h.sides}:[/bold] Δ={h.area}, R={h.circumradius}, r={h.inradius}\n"
47 f"E = X(4) = ({constructed.x4_orthocenter_E.x}, {constructed.x4_orthocenter_E.y}), "
48 f"F = X(2) = ({constructed.x2_centroid_F.x}, {constructed.x2_centroid_F.y}), "
49 f"G = X(1) = ({constructed.x1_incenter_G.x}, {constructed.x1_incenter_G.y}), "
50 f"H = X(3) = ({constructed.x3_circumcenter_H.x}, {constructed.x3_circumcenter_H.y})"
51 )
52
53
54if __name__ == "__main__":
55 run_demo()
Demonstration II: demos/feuerbach_tangency.py¶
Constructs the nine-point circle, all four tritangent circles, X(11), and Fea, Feb, Fec via Model(..., auto_intersect=False) and model.intersect(...), verifying the harmonic Euler cross-ratio (X4, X2; X5, X3) = -1 and exporting the four interactive .euclid-graphic SVGs:
1"""Executable demonstration of Karl Wilhelm Feuerbach's Theorem (1822, § 57).
2
3Constructs the nine-point circle, the four tritangent circles, the Feuerbach point X(11),
4and the three excircle tangency points Fea, Feb, Fec in exact rational coordinates on
5A = (0, 0), B = (14, 0), C = (5, 12) using geometor.model.Model(..., auto_intersect=False),
6and exports interactive .euclid-graphic SVGs.
7"""
8
9from __future__ import annotations
10
11from pathlib import Path
12
13from geometor.model import quadrance
14from rich.console import Console
15from rich.table import Table
16
17from geometor.feuerbach.render import export_all_codex_svgs
18from geometor.feuerbach.tangency import construct_feuerbach_tangency
19
20
21def run_demo(svg_dir: Path | None = None) -> None:
22 """Execute the exact Feuerbach tangency construction and print verified invariants."""
23 console = Console()
24 res = construct_feuerbach_tangency()
25
26 table = Table(title="Feuerbach (1822, § 57) — Exact Rational Locus on (15, 13, 14)")
27 table.add_column("Element", style="bold cyan")
28 table.add_column("Exact Coordinates / Radius", style="green")
29 table.add_column("Tangency / Incidence Check", style="yellow")
30
31 r9 = res.nine_point_circle.radius
32 r_in = res.incircle.radius
33 table.add_row(
34 "Nine-Point Circle (X5)",
35 f"center=({res.x5_nine_point_center.x}, {res.x5_nine_point_center.y}), R₉={r9}",
36 "9 canonical points verified",
37 )
38 table.add_row(
39 "Incircle (X1) & X(11)",
40 f"X₁=({res.x1_incenter.x}, {res.x1_incenter.y}), r={r_in}, X₁₁=({res.x11_feuerbach_point.x}, {res.x11_feuerbach_point.y})",
41 f"Q(X₅,X₁)={quadrance(res.x5_nine_point_center, res.x1_incenter)} == (R₉-r)²={(r9 - r_in) ** 2}",
42 )
43 for name, ctr, circ, fe_pt in zip(
44 ("Excircle A", "Excircle B", "Excircle C"),
45 res.excenters,
46 res.excircles,
47 res.excircle_tangencies,
48 strict=True,
49 ):
50 rk = circ.radius
51 table.add_row(
52 f"{name} & {res.model[fe_pt].ID}",
53 f"J=({ctr.x}, {ctr.y}), r={rk}, Fe=({fe_pt.x}, {fe_pt.y})",
54 f"Q(X₅,J)={quadrance(res.x5_nine_point_center, ctr)} == (R₉+r)²={(r9 + rk) ** 2}",
55 )
56 table.add_row(
57 "Harmonic Euler Range",
58 f"(X₄, X₂; X₅, X₃) = {res.harmonic_cross_ratio}",
59 f"{len(res.model.steps)} deductive Model steps",
60 )
61 console.print(table)
62
63 if svg_dir is not None:
64 written = export_all_codex_svgs(svg_dir)
65 for slug, path in written.items():
66 console.print(f"[green]Wrote SVG[/green] {slug} -> {path}")
67
68
69if __name__ == "__main__":
70 default_out = Path(__file__).resolve().parents[1] / "docsrc" / "_static" / "constructions"
71 run_demo(default_out)