Skip to content

Examples Gallery

A collection of examples demonstrating Geolet's capabilities.

Basic Shapes

Triangle

"""Simple triangle example using the Triangle class."""

from geolet import Midpoint, Point, Triangle, autofigure


@autofigure
def triangle():
    A = Point("A", 0, 0)
    B = Point("B", 4, 0)
    C = Point("C", 1.5, 3)

    # Triangle automatically draws all three sides
    T = Triangle(A, B, C)

    # Midpoint of AB (using side accessor)
    M = Midpoint(T.side12.p1, T.side12.p2, label="M", label_dir="S")

Triangle


Line

"""Line example - infinite line through two points."""

from geolet import Line, Point, figure


@figure
def line():
    A = Point("A", 0, 0, label_dir="SW")
    B = Point("B", 2, 1, label_dir="NE")

    return [
        A,
        B,
        Line(A, B, color="blue"),
    ]

Line


Circle with Radius

"""Circle with radius example."""

from geolet import CircleWithRadius, Point, figure


@figure
def circle_radius():
    O = Point("O", 0, 0, label_dir="S")

    return [
        O,
        CircleWithRadius(O, 2.0, color="red"),
    ]

Circle with Radius


Triangle Centers

Centroid

The centroid is the intersection of the medians.

"""Centroid example - intersection of medians."""

from geolet import Centroid, Point, Segment, figure


@figure
def centroid():
    A = Point("A", 0, 4, label_dir="N")
    B = Point("B", 0, 0, label_dir="SW")
    C = Point("C", 5, 0, label_dir="SE")

    return [
        A,
        B,
        C,
        Segment(A, B),
        Segment(B, C),
        Segment(C, A),
        # Centroid (intersection of medians)
        Centroid(A, B, C, label="G", color="red"),
    ]

Centroid


Orthocenter

The orthocenter is the intersection of the altitudes.

"""Orthocenter example - intersection of altitudes."""

from geolet import Orthocenter, Point, Segment, figure


@figure
def orthocenter():
    A = Point("A", 1, 4, label_dir="N")
    B = Point("B", 0, 0, label_dir="SW")
    C = Point("C", 5, 0, label_dir="SE")

    return [
        A,
        B,
        C,
        Segment(A, B),
        Segment(B, C),
        Segment(C, A),
        # Orthocenter (intersection of altitudes)
        Orthocenter(A, B, C, label="H", color="red"),
    ]

Orthocenter


Incenter & Incircle

The incenter is the intersection of angle bisectors. The incircle is tangent to all sides.

"""Incenter and Incircle example - intersection of angle bisectors."""

from geolet import Incenter, Incircle, Point, Segment, figure


@figure
def incenter():
    A = Point("A", 1, 4, label_dir="N")
    B = Point("B", 0, 0, label_dir="SW")
    C = Point("C", 5, 0, label_dir="SE")

    return [
        A,
        B,
        C,
        Segment(A, B),
        Segment(B, C),
        Segment(C, A),
        # Incenter (intersection of angle bisectors)
        Incenter(A, B, C, label="I", color="red"),
        # Incircle (inscribed circle)
        Incircle(A, B, C, color="blue"),
    ]

Incenter


Circumcircle

The circumcircle passes through all three vertices.

"""Circumcircle example - circle through 3 points."""

from geolet import Circle, Point, Segment, figure


@figure
def circumcircle():
    A = Point("A", 0, 0, label_dir="SW")
    B = Point("B", 4, 0, label_dir="SE")
    C = Point("C", 1.5, 3, label_dir="N")

    return [
        A,
        B,
        C,
        Segment(A, B),
        Segment(B, C),
        Segment(C, A),
        Circle(A, B, C, color="blue"),
    ]

Circumcircle


Euler Line

The orthocenter (H), centroid (G), and circumcenter (O) are collinear.

"""Euler line example - line through orthocenter, centroid, and circumcenter."""

from geolet import Line, Point, Triangle, autofigure


@autofigure
def euler_line():
    A = Point("A", 0, 0, label_dir="SW")
    B = Point("B", 6, 0, label_dir="SE")
    C = Point("C", 2, 5, label_dir="N")

    T = Triangle(A, B, C)

    # Orthocenter (intersection of altitudes)
    H = T.orthocenter(label="H", label_dir="S", color="red")

    # Centroid (intersection of medians)
    G = T.centroid(label="G", label_dir="S", color="blue")

    # Circumcenter (intersection of perpendicular bisectors)
    O = T.circumcenter(label="O", label_dir="S", color="green")

    # Euler line through H and O (also passes through G)
    euler = Line(H, O, color="purple", style="dashed")

Euler Line


Intersections

Segment Intersection

"""Segment intersection example - intersection of two segments."""

from geolet import Intersection, Point, Segment, figure


@figure
def segment_intersection():
    A = Point("A", 0, 0, label_dir="SW")
    B = Point("B", 3, 2, label_dir="NE")
    C = Point("C", 0, 2, label_dir="NW")
    D = Point("D", 3, 0, label_dir="SE")

    seg1 = Segment(A, B)
    seg2 = Segment(C, D)

    return [
        A,
        B,
        C,
        D,
        seg1,
        seg2,
        Intersection(seg1, seg2, label="P", label_dir="N", color="red"),
    ]

Segment Intersection


Circle-Circle Intersection

"""Circle-circle intersection example - where two circles intersect."""

from geolet import CircleWithRadius, Intersection, Point, figure


@figure
def circle_circle_intersection():
    O1 = Point("O_1", 0, 0, label_dir="S")
    O2 = Point("O_2", 2.5, 0, label_dir="S")

    circle1 = CircleWithRadius(O1, 2.0, color="blue")
    circle2 = CircleWithRadius(O2, 2.0, color="green")

    return [
        O1,
        O2,
        circle1,
        circle2,
        Intersection(circle1, circle2, label="P", index=0, label_dir="N", color="red"),
        Intersection(circle1, circle2, label="Q", index=1, label_dir="S", color="red"),
    ]

Circle-Circle Intersection


Circle-Segment Intersection

"""Circle-segment intersection example - where a segment crosses a circle."""

from geolet import CircleWithRadius, Intersection, Point, Segment, figure


@figure
def circle_segment_intersection():
    O = Point("O", 0, 0, label_dir="S")
    A = Point("A", -3, -1, label_dir="SW")
    B = Point("B", 3, 1, label_dir="NE")

    circle = CircleWithRadius(O, 2.0, color="blue")
    segment = Segment(A, B, style="dashed")

    return [
        O,
        A,
        B,
        circle,
        segment,
        Intersection(circle, segment, label="P", index=0, label_dir="NW", color="red"),
        Intersection(circle, segment, label="Q", index=1, label_dir="SE", color="red"),
    ]

Circle-Segment Intersection


Tangent Lines

"""Tangent example - drawing tangent lines from external point to circle."""

from geolet import CircleWithRadius, Point, Segment, Tangent, TangentPoint, autofigure


@autofigure
def tangent():
    # Circle with center O and radius 2
    O = Point("O", 0, 0)
    c = CircleWithRadius(O, 2, color="gray")

    # External point P
    P = Point("P", 5, 0)

    # Two tangent lines from P to circle c
    t1 = Tangent(P, c, index=0, label="t_1", label_dir="S", color="blue")
    t2 = Tangent(P, c, index=1, label="t_2", label_dir="N", color="red")

    # Tangent points - where each tangent line touches the circle
    T1 = TangentPoint(P, c, index=0, label="T_1", label_dir="SW", color="blue")
    T2 = TangentPoint(P, c, index=1, label="T_2", label_dir="NW", color="red")

    # Segments from P to tangent points (these have equal length)
    Segment(P, T1, style="dashed", color="blue")
    Segment(P, T2, style="dashed", color="red")

Tangent


Tangent Point

"""TangentPoint example - finding where tangent lines touch a circle."""

from geolet import CircleWithRadius, Point, Segment, TangentPoint, autofigure


@autofigure
def tangent_point():
    # Circle with center O and radius 2
    O = Point("O", 0, 0)
    c = CircleWithRadius(O, 2, color="gray")

    # External point P
    P = Point("P", 5, 0)

    # Tangent points - where tangent lines from P touch the circle
    T1 = TangentPoint(P, c, index=0, label="T_1", label_dir="SW", color="blue")
    T2 = TangentPoint(P, c, index=1, label="T_2", label_dir="NW", color="red")

    # Segments from external point to tangent points
    # These segments have equal length (property of tangent lines)
    s1 = Segment(P, T1, color="blue")
    s2 = Segment(P, T2, color="red")

    # Segments from center to tangent points (radii, perpendicular to tangents)
    r1 = Segment(O, T1, style="dashed", color="gray")
    r2 = Segment(O, T2, style="dashed", color="gray")

Tangent Point


Altitude & Foot

"""Altitude example - foot of perpendicular from vertex to opposite side."""

from geolet import Foot, Point, Segment, figure


@figure
def altitude():
    A = Point("A", 1, 3, label_dir="N")
    B = Point("B", 0, 0, label_dir="SW")
    C = Point("C", 4, 0, label_dir="SE")

    # Triangle sides
    bc = Segment(B, C)

    return [
        A,
        B,
        C,
        Segment(A, B),
        bc,
        Segment(C, A),
        Foot(A, bc, label="H", label_dir="S"),
    ]

Altitude


Perpendicular Line

"""Perpendicular line example - line perpendicular to a segment through a point."""

from geolet import PerpendicularLine, Point, Segment, figure


@figure
def perpendicular():
    A = Point("A", 0, 0, label_dir="SW")
    B = Point("B", 4, 0, label_dir="SE")
    P = Point("P", 2, 2, label_dir="N")

    seg = Segment(A, B)

    return [
        A,
        B,
        P,
        seg,
        PerpendicularLine(P, seg, color="red", style="dashed"),
    ]

Perpendicular


Median

"""Median example - segment from vertex to midpoint of opposite side."""

from geolet import Median, Point, Segment, figure


@figure
def median():
    A = Point("A", 0, 4, label_dir="N")
    B = Point("B", 0, 0, label_dir="SW")
    C = Point("C", 5, 0, label_dir="SE")

    return [
        A,
        B,
        C,
        Segment(A, B),
        Segment(B, C),
        Segment(C, A),
        # Median from A to midpoint of BC
        Median(A, B, C, color="blue"),
    ]

Median


Angle Marking

"""Example showing angle marking in a triangle."""

from geolet import Angle, Foot, Point, Segment, Triangle, autofigure


@autofigure
def angle():
    A = Point("A", 0, 0, label_dir="SW")
    B = Point("B", 5, 0, label_dir="SE")
    C = Point("C", 2, 3, label_dir="N")

    tri = Triangle(A, B, C)

    # Mark angle CAB (at vertex A) with label
    angle_a = Angle(C, A, B, label="\\alpha", color="blue")

    # Mark angle ABC (at vertex B) with double arc (congruent angle notation)
    angle_b = Angle(A, B, C, n=2, color="red")

    # Mark angle BCA (at vertex C) with fill
    angle_c = Angle(B, C, A, fill=True, color="green")

    # Altitude from C to AB
    H = Foot(C, Segment(A, B), label="H", label_dir="S")
    altitude = Segment(C, H, style="dashed", color="gray")

    # Right angle marker at foot of altitude (angle AHC)
    right_angle = Angle(A, H, C, right_angle=True, color="gray")

Angle


Reflections

"""Reflect example - point, segment, and line reflections."""

from geolet import Line, Point, Reflect, Segment, autofigure


@autofigure
def reflect():
    # Original point
    A = Point("A", 1, 1, label_dir="SW")

    # 1. Reflect over a point (central reflection)
    O = Point("O", 2.5, 1.5, label_dir="S", color="red")
    A1 = Reflect(A, O, label="A_1", label_dir="NE", color="red")
    AO = Segment(A, A1, color="red", style="dashed")  # Connect to show symmetry

    # 2. Reflect over a segment
    P = Point("P", 5, 0, label_dir="S")
    Q = Point("Q", 5, 3, label_dir="N")
    seg = Segment(P, Q, color="blue")
    A2 = Reflect(A, seg, label="A_2", label_dir="E", color="blue")

    # 3. Reflect over a line (infinite)
    R = Point("R", 0, 4, label_dir="W")
    S = Point("S", 6, 4, label_dir="E")
    line = Line(R, S, color="green", style="dashed")
    A3 = Reflect(A, line, label="A_3", label_dir="N", color="green")

Reflect


Inversions

Invert Point

"""InvertPoint example - inverting points with respect to a circle."""

from math import sqrt

from geolet import CircleWithRadius, InvertPoint, Line, Point, autofigure


@autofigure
def invert_point():
    # Circle of inversion centered at O with radius 2
    O = Point("O", 0, 0, label_dir="SW")
    inv_circle = CircleWithRadius(O, 2, color="gray", style="dashed")

    # Points to invert
    # P is inside the circle (distance 1 from center), on horizontal axis
    P = Point("P", 1, 0, label_dir="S")
    # Q is outside the circle, to the right
    Q = Point("Q", 3, 1, label_dir="N")
    # R is on the circle (distance 2 from center) on the diagonal - maps to itself
    R = Point("R", sqrt(2), sqrt(2), label_dir="NE")

    # Invert the points
    # P at distance 1 maps to P' at distance 4 (1 * 4 = 2^2 = 4)
    P_inv = InvertPoint(
        P, respect_to=inv_circle, label="P'", label_dir="S", color="blue"
    )
    # Q at distance sqrt(10) maps to Q' at distance 4/sqrt(10)
    Q_inv = InvertPoint(
        Q, respect_to=inv_circle, label="Q'", label_dir="N", color="red"
    )
    # R on the circle maps to itself
    R_inv = InvertPoint(
        R, respect_to=inv_circle, label="R'", label_dir="SW", color="green"
    )

    # Draw lines through O connecting original points to their inversions
    line1 = Line(P, P_inv, color="blue", style="dashed")
    line2 = Line(Q, Q_inv, color="red", style="dashed")

Invert Point


Invert Line

"""InvertLine example - inverting lines with respect to a circle."""

from geolet import (
    CircleWithRadius,
    InvertLine,
    InvertLineThroughCenter,
    Line,
    Point,
    autofigure,
)


@autofigure
def invert_line():
    # Circle of inversion centered at O with radius 2
    O = Point("O", 0, 0, label_dir="E")
    inv_circle = CircleWithRadius(O, 2)

    # Case 1: A line that doesn't pass through the center (x = 0.8)
    C = Point("C", 0.8, -2.5, label_dir="SE")
    D = Point("D", 0.8, 2.5, label_dir="NE")
    line_cd = Line(C, D)

    # Invert the line - produces a circle passing through O
    inverted_circle_1 = InvertLine(
        line_cd, respect_to=inv_circle, color="red", style="dashed"
    )
    O_CD = inverted_circle_1.center_point(label="O_{CD}", label_dir="E", color="red")

    # Case 2: A line closer to the edge (x = -1.5) - produces a larger circle
    E = Point("E", -1.5, -2.5, label_dir="W")
    F = Point("F", -1.5, 2.5, label_dir="W")
    line_ef = Line(E, F)

    inverted_circle_2 = InvertLine(
        line_ef, respect_to=inv_circle, color="green", style="dashed"
    )
    O_EF = inverted_circle_2.center_point(label="O_{EF}", label_dir="E", color="green")

    # Case 3: A line through the center (x = 0) maps to itself
    A = Point("A", 0, -2.5, label_dir="SW")
    B = Point("B", 0, 2.5, label_dir="NW")
    line_through_center = Line(A, B)

    # Invert the line through center - stays the same line (dashed to show inversion)
    inverted_same = InvertLineThroughCenter(
        line_through_center, respect_to=inv_circle, color="blue", style="dashed"
    )

Invert Line


Invert Circle

"""InvertCircle example - inverting circles with respect to another circle."""

from geolet import (
    CircleWithRadius,
    InvertCircle,
    InvertCircleThroughCenter,
    Point,
    autofigure,
)


@autofigure
def invert_circle():
    # Circle of inversion centered at O with radius 3
    O = Point("O", 0, 0, label_dir="E")
    inv_circle = CircleWithRadius(O, 3)

    # Case 1: A circle that doesn't pass through the center of inversion
    # This circle centered at (2, 0) with radius 0.5 will invert to another circle
    C1 = Point("C_1", 2, 0, label_dir="E")
    circle1 = CircleWithRadius(C1, 0.7, color="blue")
    circle1_inv = InvertCircle(
        circle1, respect_to=inv_circle, color="blue", style="dashed"
    )
    C1_prime = circle1_inv.center_point(label="C'_1", label_dir="E", color="blue")

    # Case 2: Another circle further from center
    C2 = Point("C_2", 0, -4, label_dir="S")
    circle2 = CircleWithRadius(C2, 0.8, color="green")
    circle2_inv = InvertCircle(
        circle2, respect_to=inv_circle, color="green", style="dashed"
    )
    C2_prime = circle2_inv.center_point(label="C'_2", label_dir="S", color="green")

    # Case 3: A circle passing through the center of inversion maps to a line
    C3 = Point("C_3", 0, 2, label_dir="S")
    circle3 = CircleWithRadius(C3, 2, color="purple")  # passes through O
    circle3_inv = InvertCircleThroughCenter(
        circle3, respect_to=inv_circle, color="purple", style="dashed"
    )

Invert Circle


Advanced Examples

Nine-Point Circle

"""Nine-point circle (Euler circle / Feuerbach circle).

Given triangle ABC with altitudes AD, BE, and CF. Let H be the orthocenter of
triangle ABC. Let MA, MB, and MC be the midpoints of sides BC, CA, and AB
respectively. Let HA, HB, and HC be the midpoints of segments AH, BH, and CH.

Prove that these nine points lie on a single circle:
D, E, F, MA, MB, MC, HA, HB, HC.

The nine points are:
- D, E, F: feet of the altitudes
- MA, MB, MC: midpoints of the sides
- HA, HB, HC: midpoints from vertices to orthocenter
"""

from geolet import (
    Circle,
    Circumcenter,
    Foot,
    Midpoint,
    Orthocenter,
    Point,
    Segment,
    figure,
)


@figure
def nine_point_circle():
    # Triangle vertices
    A = Point("A", 0, 4, label_dir="N")
    B = Point("B", -1, 0, label_dir="SW")
    C = Point("C", 5, 0, label_dir="SE")

    # Triangle sides
    seg_ab = Segment(A, B)
    seg_bc = Segment(B, C)
    seg_ca = Segment(C, A)

    # Orthocenter H
    H = Orthocenter(A, B, C, label="H", label_dir="S")

    # Feet of altitudes (D, E, F)
    D = Foot(A, seg_bc, label="D", label_dir="S")  # Foot from A to BC
    E = Foot(B, seg_ca, label="E", label_dir="NE")  # Foot from B to CA
    F = Foot(C, seg_ab, label="F", label_dir="NW")  # Foot from C to AB

    # Midpoints of sides (MA, MB, MC)
    MA = Midpoint(B, C, label="M_A", label_dir="S")  # Midpoint of BC
    MB = Midpoint(C, A, label="M_B", label_dir="NE")  # Midpoint of CA
    MC = Midpoint(A, B, label="M_C", label_dir="NW")  # Midpoint of AB

    # Midpoints from vertices to orthocenter (HA, HB, HC)
    HA = Midpoint(A, H, label="H_A", label_dir="E")  # Midpoint of AH
    HB = Midpoint(B, H, label="H_B", label_dir="W")  # Midpoint of BH
    HC = Midpoint(C, H, label="H_C", label_dir="E")  # Midpoint of CH

    # Circumcenter O of triangle ABC
    O = Circumcenter(A, B, C, label="O", label_dir="N", color="red")

    # Center of nine-point circle O_9 is the midpoint of O and H
    O_9 = Midpoint(O, H, label="O_9", label_dir="N", color="blue")

    # The nine-point circle passes through all nine points
    # We can define it using any three of them
    nine_pt_circle = Circle(D, E, F, color="blue", style="dashed")

    # Show O_9 is midpoint of O and H with equal length segments
    seg_o_o9 = Segment(O, O_9, color="purple", marks=1)  # O to O_9
    seg_o9_h = Segment(O_9, H, color="purple", marks=1)  # O_9 to H

    return [
        # Triangle
        seg_ab,
        seg_bc,
        seg_ca,
        # Euler line segments O--O_9--H with equal marks
        seg_o_o9,
        seg_o9_h,
        # Nine-point circle
        nine_pt_circle,
        # Triangle vertices
        A,
        B,
        C,
        # Orthocenter
        H,
        # Circumcenter of ABC
        O,
        # Center of nine-point circle (midpoint of O and H)
        O_9,
        # Feet of altitudes
        D,
        E,
        F,
        # Midpoints of sides
        MA,
        MB,
        MC,
        # Midpoints to orthocenter
        HA,
        HB,
        HC,
    ]

Nine-Point Circle


IMO 2025 Problem 2

A complex geometry problem showcasing multiple features.

"""IMO 2025 Problem 2 - Circles, circumcenters, and tangent lines.

Let Ω and Γ be circles with centres M and N, respectively, such that the
radius of Ω is less than the radius of Γ. Suppose Ω and Γ intersect at two
distinct points A and B. Line MN intersects Ω at C and Γ at D, so that
C, M, N, D lie on MN in that order. Let P be the circumcentre of triangle ACD.
Line AP meets Ω again at E ≠ A and meets Γ again at F ≠ A. Let H be the
orthocentre of triangle PMN.

Prove that the line through H parallel to AP is tangent to the circumcircle
of triangle BEF.

Proposed by Trần Quang Hùng, Vietnam
"""

from geolet import (
    Circle,
    CircleWithRadius,
    Circumcenter,
    Intersection,
    Line,
    Orthocenter,
    ParallelLine,
    Point,
    Segment,
    figure,
)


@figure
def imo_2025_p2():
    # Circle centers
    M = Point("M", 0, 0, label_dir="SW")
    N = Point("N", 3, 0, label_dir="SE")

    # Circles Ω (blue, radius 2) and Γ (green, radius 2.5)
    omega = CircleWithRadius(M, 2.0, color="blue")
    gamma = CircleWithRadius(N, 2.5, color="green")

    # A, B: intersection points of Ω and Γ
    A = Intersection(omega, gamma, label="A", index=0, label_dir="N")
    B = Intersection(omega, gamma, label="B", index=1, label_dir="S")

    # Line MN for intersections
    line_mn_path = Line(M, N)

    # C: line MN intersects Ω (left of M)
    # D: line MN intersects Γ (right of N)
    C = Intersection(omega, line_mn_path, label="C", index=1, label_dir="W")
    D = Intersection(gamma, line_mn_path, label="D", index=0, label_dir="E")

    # P: circumcenter of triangle ACD
    P = Circumcenter(A, C, D, label="P", label_dir="W")

    # Circumcircle of triangle ACD (center P)
    circle_acd = Circle(A, C, D, color="purple", style="dashed")

    # Line AP (extended) - needed for E, F intersections
    line_ap = Line(A, P, color="purple", style="dashed")

    # E: line AP meets Ω again at E ≠ A (index 1 to get second intersection)
    E = Intersection(omega, line_ap, label="E", index=1, label_dir="NW")

    # F: line AP meets Γ again at F ≠ A (index 1 to get second intersection)
    F = Intersection(gamma, line_ap, label="F", index=1, label_dir="S")

    # H: orthocenter of triangle PMN
    H = Orthocenter(P, M, N, label="H", label_dir="E")

    # Triangle PMN
    seg_pm = Segment(P, M)
    seg_mn = Segment(M, N)
    seg_np = Segment(N, P)

    # Line MN (shown as segment C--D)
    line_mn = Segment(C, D, style="dashed")

    # Triangle ACD
    seg_ac = Segment(A, C)
    seg_cd = Segment(C, D)
    seg_da = Segment(D, A)

    # Circumcircle of BEF (the key circle for the theorem)
    circle_bef = Circle(B, E, F, color="red")

    # Tangent line: through H parallel to AP
    tangent_line = ParallelLine(H, line_ap, color="orange", style="dashed")

    return [
        # Circles
        omega,
        gamma,
        circle_acd,
        circle_bef,
        # Triangle PMN
        seg_pm,
        seg_mn,
        seg_np,
        # Triangle ACD
        seg_ac,
        seg_cd,
        seg_da,
        # Construction lines
        line_mn,
        line_ap,
        tangent_line,
        # Points
        M,
        N,
        A,
        B,
        C,
        D,
        P,
        E,
        F,
        H,
    ]

IMO 2025 P2


Running Examples

Generate output from any example file:

# Generate Asymptote source
geolet generate examples/euler_line.py

# Generate PDF
geolet generate examples/euler_line.py -f pdf

# Generate SVG
geolet generate examples/euler_line.py -f svg

List all available examples:

geolet examples ls

Generate all examples:

geolet examples generate --all -f svg