Geometry

enum class Axis : uint8_t

Axis enumeration for 3D space.

Values:

enumerator X
enumerator Y
enumerator Z
enum class ShapeType : uint8_t

Kind of geometry shape, stored as a one-byte tag.

DEAD marks a deleted or unused registry slot; the remaining values name the 0D, 1D, and 2D shapes the world can hold.

Values:

enumerator DEAD

Deleted or unused slot.

enumerator POINT
enumerator LINE
enumerator BEZIER

Single cubic Bezier curve.

enumerator TRIANGLE
enumerator RECTANGLE
enumerator SQUARE

Specialization of RECTANGLE with equal side lengths.

enumerator ELLIPSE
enumerator CIRCLE

Specialization of ELLIPSE with equal radii.

enum class DescribeLevel : uint8_t

Level of detail for World::describe_state.

C++ callers pass the enum; the Python binding accepts the equivalent lower-case string.

Values:

enumerator BASIC

Only what the 2D image draws.

enumerator DIAGNOSTICS

BASIC plus derived facts: intersections, degeneracies.

template<typename T>
class Bezier3d : public solvcon::NumberBase<int32_t, T>
#include <bezier.hpp>

Bezier curve up to degree 3 in three-dimensional space.

Template Parameters:

T – floating-point type

Public Functions

inline void mirror_x()

Mirror the Bezier curve with respect to the X axis.

This negates Y and Z coordinates, keeping X unchanged.

inline void mirror_y()

Mirror the Bezier curve with respect to the Y axis.

This negates X and Z coordinates, keeping Y unchanged.

inline void mirror_z()

Mirror the Bezier curve with respect to the Z axis.

This negates X and Y coordinates, keeping Z unchanged.

template<typename T>
class CurvePad : public solvcon::NumberBase<int32_t, T>, public std::enable_shared_from_this<CurvePad<T>>
#include <bezier.hpp>

Store curves that are compatible to SVG https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths.

Template Parameters:

T

Public Functions

inline void mirror_x()

Mirror the curve pad with respect to the X axis.

This negates Y and Z coordinates of all control points, keeping X unchanged.

inline void mirror_y()

Mirror the curve pad with respect to the Y axis.

This negates X and Z coordinates of all control points, keeping Y unchanged.

inline void mirror_z()

Mirror the curve pad with respect to the Z axis.

This negates X and Y coordinates of all control points, keeping Z unchanged.

template<typename T>
class CubicBezierSampler
#include <bezier.hpp>

Sample cubic Bezier curves into connected line segments.

Each curve is approximated by straight segments stored in a SegmentPad. The number of segments follows the chord length divided by a target segment length.

Template Parameters:

T – floating-point type

template<typename T>
class Point3d : public solvcon::NumberBase<int32_t, T>
#include <coord.hpp>

Point in three-dimensional space.

Template Parameters:

T – floating-point type

Public Functions

inline std::string value_string() const

Return the values of the point object.

Do not include the opening and closing parentheses. Example: p.value_string(): 0.1234, -2.421, 0

Returns:

String of the values separated by comma.

inline void mirror_x()

Mirror the point with respect to the X axis.

This negates Y and Z coordinates, keeping X unchanged.

inline void mirror_y()

Mirror the point with respect to the Y axis.

This negates X and Z coordinates, keeping Y unchanged.

inline void mirror_z()

Mirror the point with respect to the Z axis.

This negates X and Y coordinates, keeping Z unchanged.

inline void mirror(Axis axis)

Mirror the point with respect to the specified axis.

Parameters:

axis – The axis to mirror with respect to (X, Y, or Z)

Throws:

std::invalid_argument – if an invalid axis is provided

template<typename T>
class PointPad : public solvcon::NumberBase<int32_t, T>, public std::enable_shared_from_this<PointPad<T>>
#include <coord.hpp>

Container of points in two- or three-dimensional space.

Coordinates are stored as separate per-axis arrays (x, y, and, for three dimensions, z), so the layout is structure-of-arrays. The dimensionality (2 or 3) is fixed at construction and cannot change.

Template Parameters:

T – floating-point type

template<typename T>
class Segment3d : public solvcon::NumberBase<int32_t, T>
#include <coord.hpp>

Segment in three-dimensional space.

Template Parameters:

T – floating-point type

template<typename T>
class SegmentPad : public solvcon::NumberBase<int32_t, T>, public std::enable_shared_from_this<SegmentPad<T>>
#include <coord.hpp>

Container of line segments in two- or three-dimensional space.

Each segment is stored as a pair of endpoints, held in two PointPad objects (one for each endpoint). The dimensionality (2 or 3) comes from the underlying point pads.

Template Parameters:

T – floating-point type

Public Functions

inline void mirror_x()

Mirror the segment pad with respect to the X axis.

This negates Y and Z coordinates, keeping X unchanged. Handles both 2D and 3D segments.

inline void mirror_y()

Mirror the segment pad with respect to the Y axis.

This negates X and Z coordinates, keeping Y unchanged. Handles both 2D and 3D segments.

inline void mirror_z()

Mirror the segment pad with respect to the Z axis.

This negates X and Y coordinates, keeping Z unchanged. Only works for 3D segments.

Throws:

std::out_of_range – if ndim is not 3

template<typename T>
class Trapezoid3d : public solvcon::NumberBase<int32_t, T>
#include <polygon.hpp>

Trapezoid in three-dimensional space.

Stores the four corner points (p0, p1, p2, p3) as twelve scalar coordinates in a flat buffer.

Template Parameters:

T – floating-point type

template<typename T>
class TrapezoidPad : public solvcon::NumberBase<int32_t, T>, public std::enable_shared_from_this<TrapezoidPad<T>>
#include <polygon.hpp>

Container for many trapezoids stored as four parallel point columns.

The four corner points (p0, p1, p2, p3) of every trapezoid are kept in four separate PointPad instances, so trapezoid i is read by gathering element i from each column. The pad works for both 2 and 3 dimensional points.

Template Parameters:

T – floating-point type

template<typename T>
class TrapezoidalDecomposer
#include <polygon.hpp>

Helper class for trapezoidal decomposition of polygons.

This class implements the sweep line algorithm to decompose polygons into trapezoids. The decomposition is used for polygon boolean operations.

Template Parameters:

T – floating-point type

Public Functions

std::pair<size_t, size_t> decompose(size_t polygon_id, std::vector<point_type> const &points)

Decompose a polygon into trapezoids using vertical sweep line algorithm.

Parameters:
  • polygon_id – ID of the polygon to decompose

  • points – Vector of polygon vertices in order

Returns:

Pair of begin and end indices into the trapezoid pad, where the begin index is inclusive and the end index is exclusive

template<typename T>
class AreaBooleanUnion
#include <polygon.hpp>

This class implements the union algorithm for two polygons by decomposing them into trapezoids and merging overlapping regions.

Template Parameters:

T – floating-point type

Public Functions

std::shared_ptr<polygon_pad_type> compute(const std::shared_ptr<polygon_pad_type> &pad, size_t polygon_id1, size_t polygon_id2)

Compute union of two polygons.

Parameters:
  • pad – Polygon container holding both polygons

  • polygon_id1 – ID of first polygon

  • polygon_id2 – ID of second polygon

Returns:

polygon pad containing the union of the two polygons

template<typename T>
class AreaBooleanIntersection
#include <polygon.hpp>

This class implements the intersection algorithm for two polygons by decomposing them into trapezoids and finding overlapping regions.

Template Parameters:

T – floating-point type

Public Functions

std::shared_ptr<polygon_pad_type> compute(const std::shared_ptr<polygon_pad_type> &pad, size_t polygon_id1, size_t polygon_id2)

Compute intersection of two polygons.

Parameters:
  • pad – Polygon container holding both polygons

  • polygon_id1 – ID of first polygon

  • polygon_id2 – ID of second polygon

Returns:

polygon pad containing polygons forming the intersection

template<typename T>
class AreaBooleanDifference
#include <polygon.hpp>

This class implements the difference algorithm for two polygons (p1 - p2) by decomposing them into trapezoids and removing overlapping regions.

Template Parameters:

T – floating-point type

Public Functions

std::shared_ptr<polygon_pad_type> compute(const std::shared_ptr<polygon_pad_type> &pad, size_t polygon_id1, size_t polygon_id2)

Compute difference of two polygons (p1 - p2).

Parameters:
  • pad – Polygon container holding both polygons

  • polygon_id1 – ID of first polygon

  • polygon_id2 – ID of second polygon to subtract

Returns:

polygon pad containing polygons forming the difference

template<typename T>
class Triangle3d : public solvcon::NumberBase<int32_t, T>
#include <polygon.hpp>

Triangle in three-dimensional space.

Stores the three corner points (p0, p1, p2) as nine scalar coordinates in a flat buffer.

Template Parameters:

T – floating-point type

Public Functions

inline void mirror_x()

Mirror the triangle with respect to the X axis.

This negates Y and Z coordinates, keeping X unchanged.

inline void mirror_y()

Mirror the triangle with respect to the Y axis.

This negates X and Z coordinates, keeping Y unchanged.

inline void mirror_z()

Mirror the triangle with respect to the Z axis.

This negates X and Y coordinates, keeping Z unchanged.

template<typename T>
class TrianglePad : public solvcon::NumberBase<int32_t, T>, public std::enable_shared_from_this<TrianglePad<T>>
#include <polygon.hpp>

Container for many triangles stored as three parallel point columns.

The three corner points (p0, p1, p2) of every triangle are kept in three separate PointPad instances, so triangle i is read by gathering element i from each column. The pad works for both 2 and 3 dimensional points.

Template Parameters:

T – floating-point type

Public Functions

inline void mirror_x()

Mirror the triangle pad with respect to the X axis.

This negates Y and Z coordinates, keeping X unchanged. Handles both 2D and 3D triangles.

inline void mirror_y()

Mirror the triangle pad with respect to the Y axis.

This negates X and Z coordinates, keeping Y unchanged. Handles both 2D and 3D triangles.

inline void mirror_z()

Mirror the triangle pad with respect to the Z axis.

This negates X and Y coordinates, keeping Z unchanged. Only works for 3D triangles.

Throws:

std::out_of_range – if ndim is not 3

template<typename T>
class Polygon3d
#include <polygon.hpp>

Forward declaration of Polygon3d for use in helper classes.

Polygon3d handle class - lightweight view into a polygon stored in PolygonPad.

This is a lightweight handle that references a polygon stored in a PolygonPad container. The handle keeps the underlying PolygonPad alive by holding a shared pointer to it. Polygons are defined by an ordered list of nodes following the right-hand rule: counter-clockwise for positive area, clockwise for negative.

The handle uses polygon_id as public API, with internal offset/count for efficient access.

Template Parameters:

T – floating-point type

template<typename T>
class PolygonPad : public solvcon::NumberBase<int32_t, T>, public std::enable_shared_from_this<PolygonPad<T>>
#include <polygon.hpp>

Forward declaration of PolygonPad for use in Polygon3d handle class.

PolygonPad - container for multiple polygons stored as node lists.

Polygons are stored efficiently as sequences of nodes in a shared PointPad, with each polygon defined by a range [start, end) in the node list. This avoids memory duplication compared to storing line segments.

Note that PolygonPad assumes polygons are in a XY plane currently. TODO: Extend to 3D polygons in arbitrary planes.

All nodes follow the right-hand rule:

  • Counter-clockwise ordering = positive area polygon

  • Clockwise ordering = negative area polygon (holes)

Future: Will integrate with trapezoidal map for polygon boolean operations. Reference: http://www0.cs.ucl.ac.uk/staff/m.slater/Teaching/CG/1997-98/Solutions/Trap/

Template Parameters:

T – floating-point type

Public Functions

polygon_type add_polygon(std::vector<point_type> const &nodes)

Add a polygon from a list of nodes.

Nodes must follow right-hand rule: counter-clockwise for positive area.

Parameters:

nodes – Vector of points defining the polygon boundary

Returns:

Polygon3d handle to the newly added polygon

polygon_type add_polygon_from_segments(std::shared_ptr<segment_pad_type> const &segments)

Add a polygon from a SegmentPad by extracting nodes.

Assumes segments form a connected chain.

The input is interpreted as an ordered chain. Nodes are extracted from segments->p0(i) for i in [0, size). The last closing segment is not validated; it is the caller’s responsibility to provide a consistent chain.

Parameters:

segmentsSegmentPad containing connected line segments

Returns:

Polygon3d handle to the newly added polygon

polygon_type add_polygon_from_curves(std::shared_ptr<curve_pad_type> const &curves, value_type sample_length)

Add a polygon from a CurvePad by sampling.

Parameters:
  • curvesCurvePad to sample

  • sample_length – Sampling interval

Returns:

Polygon3d handle to the newly added polygon

polygon_type add_polygon_from_segments_and_curves(std::shared_ptr<segment_pad_type> const &segments, std::shared_ptr<curve_pad_type> const &curves, value_type sample_length)

Add a polygon from both segments and curves.

Parameters:
  • segmentsSegmentPad containing line segments

  • curvesCurvePad to sample

  • sample_length – Sampling interval for curves

Returns:

Polygon3d handle to the newly added polygon

inline polygon_type get_polygon(size_t polygon_id) const

Get a polygon handle by polygon_id.

Parameters:

polygon_id – ID of the polygon

Returns:

Polygon3d handle

size_t get_num_nodes(size_t polygon_id) const

Get number of nodes in a specific polygon.

point_type get_node(size_t polygon_id, size_t node_index) const

Get a node from a specific polygon.

Parameters:
  • polygon_id – Index of the polygon

  • node_index – Index of the node within the polygon

Returns:

Point at the specified position

segment_type get_edge(size_t polygon_id, size_t edge_index) const

Get an edge (segment) from a specific polygon.

Edge i connects node i to node (i+1) % nnode.

Parameters:
  • polygon_id – Index of the polygon

  • edge_index – Index of the edge within the polygon

Returns:

Segment representing the edge

value_type compute_signed_area(size_t polygon_id) const

Compute signed area of a polygon using the shoelace formula.

Positive area indicates counter-clockwise node ordering (right-hand rule). Negative area indicates clockwise ordering.

This currently uses only x and y coordinates (i.e., the signed area of the polygon projected onto the XY plane). For ndim()==2, this is the usual 2D signed area. For ndim()==3, this is meaningful only when the polygon is planar and aligned with the XY plane.

Parameters:

polygon_id – Index of the polygon

Returns:

Signed area (positive = CCW, negative = CW)

inline bool is_counter_clockwise(size_t polygon_id) const

Check if polygon nodes are ordered counter-clockwise (right-hand rule).

BoundBox3d<T> calc_bound_box(size_t polygon_id) const

Calculate bounding box for a specific polygon.

inline void search_segments(BoundBox3d<T> const &box, std::vector<segment_type> &output) const

Search for segments within a bounding box across all polygons.

Returns segments from all polygons that intersect the query box.

Parameters:
  • box – Query bounding box

  • output – Vector to store found segments

void rebuild_rtree()

Rebuild the spatial index (RTree) for all polygons.

The R-tree is updated incrementally when polygons are added through this class. If in the future polygon nodes become mutable (e.g., via exposing direct access to m_points), call rebuild_rtree() after any mutation so search_segments() remains correct.

std::pair<size_t, size_t> decompose_to_trapezoid(size_t polygon_id)

Decompose a polygon into trapezoids using vertical sweep line algorithm.

Parameters:

polygon_id – ID of the polygon to decompose

Throws:

std::out_of_range – if polygon_id is invalid

Returns:

Pair of begin and end indices into the decomposer’s trapezoid pad

inline std::shared_ptr<TrapezoidPad<T>> decomposed_trapezoids()

Access the trapezoid pad produced by the decomposer.

Valid after calling decompose_to_trapezoid().

inline std::shared_ptr<polygon_pad_type> boolean_union(polygon_type const &p1, polygon_type const &p2)

Compute union of two polygons using trapezoidal decomposition.

Parameters:
  • p1 – First polygon

  • p2 – Second polygon

Returns:

polygon pad forming the union

inline std::shared_ptr<polygon_pad_type> boolean_intersection(polygon_type const &p1, polygon_type const &p2)

Compute intersection of two polygons using trapezoidal decomposition.

Parameters:
  • p1 – First polygon

  • p2 – Second polygon

Returns:

polygon pad forming the intersection

inline std::shared_ptr<polygon_pad_type> boolean_difference(polygon_type const &p1, polygon_type const &p2)

Compute difference of two polygons (p1 - p2).

Parameters:
  • p1 – First polygon

  • p2 – Second polygon to subtract

Returns:

polygon pad forming the difference

template<typename T>
struct RTreeValueOps<Segment3d<T>, BoundBox3d<T>>
#include <polygon.hpp>

RTreeValueOps specialization that bounds Segment3d items with BoundBox3d.

Teaches the RTree how to compute the axis-aligned bounding box of a single segment and of a group of segments, used when indexing polygon edges.

Template Parameters:

T – floating-point type

template<typename T>
class BoundBox3d : public solvcon::NumberBase<int32_t, T>
#include <rtree.hpp>

Bounding box for 2D and 3D objects, e.g., Point3d, Segment3d, Triangle3d, etc.

For 2D usage, callers pass min_z = max_z = 0 explicitly.

Template Parameters:

T – Floating-point coordinate type.

Public Functions

inline BoundBox3d(value_type min_x_in, value_type min_y_in, value_type min_z_in, value_type max_x_in, value_type max_y_in, value_type max_z_in)

construct a bounding box with given min and max coordinates

inline BoundBox3d(const BoundBox3d &a, const BoundBox3d &b)

construct a bounding box that encloses two bounding boxes

inline value_type calc_area() const

2D area (dx*dy) when z-extent = 0, else 3D volume (dx*dy*dz).

Do not mix 2D and 3D boxes in one RTree: the split heuristic needs a monotonic measure within a single tree.

template<typename E, typename B>
struct RTreeValueOps
#include <rtree.hpp>

Value operations traits for the R-tree.

Template Parameters:
  • E – Item type to be stored in the R-tree.

  • B – Bounding box type associated with the item E.

Public Static Functions

static B calc_bound_box(E const &item)

Calculate bounding box for the given item.

static B calc_group_bound_box(std::vector<E> const &items)

Calculate bounding box for a group of items.

template<typename E, typename B, typename ValueOpsType>
struct RTreeNode
#include <rtree.hpp>

R-tree node structure.

A node is a leaf when it holds items and an internal node when it holds child nodes; the two vectors are not populated at the same time.

Template Parameters:
  • E – Item type to be stored in the R-tree.

  • B – Bounding box type associated with the item E.

  • ValueOpsType – Value operations traits for E and B.

Public Functions

inline void recalculate_bound_box()

Recalculate bounding box based on contained items and nodes.

template<typename E, typename B, typename ValueOps = RTreeValueOps<E, B>, int MAX_ITEMS_PER_NODE = 64>
class RTree
#include <rtree.hpp>

R-tree spatial index based on Guttman’s 1984 R-tree paper.

Supports insert, search by bounding box, and remove. A node holds at most MAX_ITEMS_PER_NODE entries and splits when it overflows.

Template Parameters:
  • E – Item type to be stored in the R-tree.

  • B – Bounding box type associated with E.

  • ValueOps – Value operations traits for E and B.

  • MAX_ITEMS_PER_NODE – Maximum number of entries per R-tree node.

Public Functions

inline void insert(E const &item)

Insert item into R-tree.

inline void search(const B &box, std::vector<E> &output) const

Search for items intersecting the given bounding box.

Parameters:
  • box – the bounding box to search

  • output – the vector to store found items

inline void remove(E const &item)

Remove item from R-tree.

template<typename T>
class ViewTransform2d
#include <ViewTransform2d.hpp>

Affine view transform for a strictly 2D canvas.

Maps math-convention world coordinates (+Y up) to Qt screen coordinates (+Y down). The mapping is:

screen_x = zoom * world_x + pan_x
screen_y = pan_y - zoom * world_y      // +Y-up flip
The class is intentionally Qt-free so the math can be unit-tested in the test_nopython gtest target without linking Qt.

Public Functions

inline value_type pan_x() const

Screen-pixel x-offset added to scaled world coordinates.

At identity zoom this is the screen column where world x == 0 lands.

inline value_type pan_y() const

Screen-pixel y-offset.

At identity zoom this is the screen row where world y == 0 lands. Combined with the +Y-up flip, increasing screen-y runs downward while increasing world-y runs upward.

inline value_type zoom() const

Scale factor in screen pixels per world unit.

Must stay positive; callers that mutate it directly own the invariant (the widget enforces it via setViewTransform).

void screen_from_world(T world_x, T world_y, T &screen_x, T &screen_y) const

Map world coordinates to Qt screen coordinates.

See the class docstring for the affine formula (note the +Y-up flip on screen_y).

void world_from_screen(T screen_x, T screen_y, T &world_x, T &world_y) const

Inverse of screen_from_world. Undefined when zoom() == 0.

void pan(T dx_screen, T dy_screen)

Translate the view by a screen-pixel delta.

void zoom_at(T factor, T anchor_screen_x, T anchor_screen_y)

Multiply the zoom by factor, anchored at screen point (anchor_screen_x, anchor_screen_y) so the world point currently under that screen point stays put.

factor must be finite and > 0; values

1 zoom in.

void zoom_at_clamped(T factor, T anchor_screen_x, T anchor_screen_y, T min_zoom, T max_zoom)

Cursor-anchored zoom that respects [min_zoom, max_zoom] bounds.

The effective zoom never leaves the band, and when the zoom is already at a limit a request that would push beyond it is a no-op (no pan drift). Non-finite or non-positive factor is ignored.

class WorldShapeState : public solvcon::SerializableItem
#include <World.hpp>

JSON-serializable view of one shape’s rendered 2D geometry: its id, type, bounding box, segment endpoints, and curve control points.

The z component is not rendered, so coordinates are 2D.

class WorldState : public solvcon::SerializableItem
#include <World.hpp>

JSON view of the whole world: shapes plus the bare segments, bare curves, and free points that also render but belong to no shape.

struct ShapeRecord
#include <World.hpp>

Lightweight record mapping a shape ID to the segment and curve ranges it owns in the world’s pads.

A shape may own segments only (triangle, line, rectangle), curves only (ellipse, circle), or both.

Public Types

using bbox_array_type = small_vector<double, 4>

Four corners, (x, y) pairs.

Public Members

size_t segment_offset

First index in SegmentPad.

size_t segment_count

Number of segments this shape occupies.

size_t curve_offset

First index in CurvePad.

size_t curve_count

Number of cubic Beziers this shape occupies.

bbox_array_type obb_x

OBB corner x’s in world coordinates, ordered TL, TR, BR, BL.

bbox_array_type obb_y

OBB corner y’s in world coordinates, ordered TL, TR, BR, BL.

template<typename T>
struct ShapeEntry
#include <World.hpp>

Entry stored in the R-tree: shape ID + bounding box.

template<typename T>
struct RTreeValueOps<ShapeEntry<T>, BoundBox3d<T>>
#include <World.hpp>

RTreeValueOps specialization that gives the R-tree the bounding box of a ShapeEntry.

template<typename T>
class World : public solvcon::NumberBase<int32_t, T>, public std::enable_shared_from_this<World<T>>
#include <World.hpp>

Manage all geometry entities.

Public Types

using coord2_type = small_vector<value_type, 2>

An (x, y) pair.

using bbox_array_type = small_vector<value_type, 4>

As [min_x, min_y, max_x, max_y].

using obb_array_type = small_vector<value_type, 8>

Four corners, (x, y) pairs.

Public Functions

int32_t add_triangle(T x0, T y0, T x1, T y1, T x2, T y2)

Add a triangle by decomposing it into 3 segments in the pad.

Returns the shape ID for later reference.

int32_t add_line(T x0, T y0, T x1, T y1)

Add a line segment as a shape.

One segment in the pad.

int32_t add_rectangle(T x_min, T y_min, T x_max, T y_max)

Add an axis-aligned rectangle by decomposing it into 4 segments.

(x_min, y_min) is the lower-left corner; (x_max, y_max) the upper-right.

int32_t add_square(T x_min, T y_min, T size)

Specialization of add_rectangle with equal side lengths.

Tagged SQUARE.

int32_t add_ellipse(T cx, T cy, T rx, T ry)

Add an axis-aligned ellipse as 4 cubic Bezier curves, one per quadrant, using the standard k = 4*(sqrt(2) - 1)/3 circle approximation.

Ellipses own curves, not segments.

int32_t add_circle(T cx, T cy, T r)

Specialization of add_ellipse with equal radii.

Tagged CIRCLE.

int32_t add_bezier_shape(point_type const &p0, point_type const &p1, point_type const &p2, point_type const &p3)

Add a cubic Bezier controlled by four points.

int32_t add_bezier_shape(bezier_type const &bezier)

Add a cubic Bezier from a bezier_type struct.

void translate_shape(int32_t shape_id, value_type dx, value_type dy)

Translate all segments and curves belonging to a shape by (dx, dy).

void rotate_shape(int32_t shape_id, value_type angle, value_type cx, value_type cy)

Rotate all segments and curves belonging to a shape by angle radians (counter-clockwise in world space) about the pivot (cx, cy).

void remove_shape(int32_t shape_id)

Remove a shape from the R-tree and registry.

Segments and curves remain in their pads as dead data; use clear() to reclaim.

void undo()

Undo the most recent change.

A change is any shape operation: creation, deletion, move, rotate, or a future attribute edit. A no-op when nothing is undoable.

void redo()

Redo the most recently undone change. A no-op when nothing is redoable.

inline bool can_undo() const

Whether a change is available to undo.

False while a compound is open, matching how undo() refuses to run mid-gesture.

inline bool can_redo() const

Whether an undone change is available to redo.

False while a compound is open, matching how redo() refuses to run mid-gesture.

void begin_operation()

Open a compound operation, which groups multiple shape changes into a single undo step.

A no-op if a compound is already open.

void end_operation()

Close a compound operation, which groups multiple shape changes into a single undo step.

A no-op if a compound is not open.

inline bool shape_is_live(int32_t shape_id) const

True if shape_id refers to a live (non-DEAD) shape.

Unlike the accessors above this never throws, so callers can probe a stale id.

inline bbox_array_type shape_bbox(int32_t shape_id) const

Axis-aligned bounding box of a live shape, as [min_x, min_y, max_x, max_y].

inline coord2_type shape_handle(int32_t shape_id) const

World position of a live shape’s rotate-handle anchor (the oriented bounding box’s top-left corner), as [x, y].

Carried by every translate and rotate, so it stays put relative to the shape.

inline obb_array_type shape_obb(int32_t shape_id) const

Oriented bounding box of a live shape: four world corners ordered top-left, top-right, bottom-right, bottom-left.

int32_t pick_shape(value_type x, value_type y, value_type tol) const

Pick the live shape at world point (x, y).

std::vector<int32_t> query_visible(T min_x, T min_y, T max_x, T max_y) const

Query the R-tree for shapes whose bounding box overlaps the viewport.

std::shared_ptr<segment_pad_type> collect_live_segments() const

Collect all segments except those belonging to DEAD shapes.

Includes bare segments (added via add_segment) and live shape segments.

std::shared_ptr<curve_pad_type> collect_live_curves() const

Collect all curves except those belonging to DEAD shapes.

Includes bare curves (added via add_bezier) and live shape curves.

void clear()

Remove all geometry entities (points, segments, curves, shapes) from the world.

Rebuilds pads from scratch to reclaim memory.

std::string describe_state(DescribeLevel level = DescribeLevel::BASIC) const

Describe the world state as a JSON-serializable object.

class WorldIntersection : public solvcon::SerializableItem
#include <WorldDiagnostics.hpp>

One proper crossing between two drawn segments.

class WorldDegeneracy : public solvcon::SerializableItem
#include <WorldDiagnostics.hpp>

One shape (or bare primitive) that has collapsed to a lower dimension.

class WorldDiagnostics : public solvcon::SerializableItem
#include <WorldDiagnostics.hpp>

JSON view of the world’s derived facts: crossings and degeneracies.

The arrays are empty (but present) when nothing is found.