Quick Start

Basic Usage

Create a sketch, add geometry and constraints, then solve:

from planegcs import Sketch, SolveStatus

s = Sketch()

# Add three points
p1 = s.add_fixed_point(0, 0)
p2 = s.add_point(5, 0)
p3 = s.add_point(2.5, 4)

# Connect with lines
l1 = s.add_line(p1, p2)
l2 = s.add_line(p2, p3)
l3 = s.add_line(p3, p1)

# Constraints: equilateral triangle
s.equal_length(l1, l2)
s.equal_length(l2, l3)
s.horizontal(l1)

# Fix side length
s.set_p2p_distance(p1, p2, 5.0)

# Solve
status = s.solve()
assert status == SolveStatus.Success

# Read results
print(s.get_point(p1))  # (0.0, 0.0)
print(s.get_point(p2))  # (5.0, 0.0)
print(s.get_point(p3))  # (~2.5, ~4.33)

Key Concepts

IDs: Every geometry element and parameter is identified by an integer ID returned by add_* methods.

Typed IDs: Each add_* method returns a typed ID (PointId, LineId, ParamId, etc.). These are NewType wrappers around int — no runtime cost, but static type checkers will catch mix-ups.

Parameters: Standalone doubles used as constraint values (distances, angles, radii) or as free unknowns.

  • add_param(value) creates a free parameter the solver may adjust.

  • add_fixed_param(value) (or add_param(value, fixed=True)) creates a driving parameter the solver will not change.

For driving constraint values, prefer add_fixed_param: d = add_fixed_param(5.0); p2p_distance(p1, p2, d).

Many constraints also have set_* convenience methods that accept a float directly and create a fixed parameter internally (e.g. set_p2p_distance(p1, p2, 5.0)).

Note

Point coordinates created by add_point() are always free. add_fixed_point() is a convenience that creates a point and then fixes both coordinates.

Constraints: Return a ConstraintTag that can be used to query errors or remove the constraint.

Solving: Call solve() to find a solution. Returns a SolveStatus enum.

Circles and Arcs

s = Sketch()

center = s.add_fixed_point(0, 0)
radius_id = s.add_param(5.0)

c = s.add_circle(center, radius_id)

# Constrain radius
s.set_circle_radius(c, 5.0)

# Put a point on the circle
pt = s.add_point(5, 0)
s.point_on_circle(pt, c)

status = s.solve()
assert status == SolveStatus.Success

Low-Level API

For advanced use, access the SketchSolver directly:

from planegcs import SketchSolver, SolveStatus

solver = SketchSolver()
p1 = solver.add_point(0, 0)
p2 = solver.add_point(5, 3)
d = solver.add_param(10.0, fixed=True)
solver.p2p_distance(p1, p2, d)
status = solver.solve()