Block Geometry

Introduction

Block Coordinate

Coordinate is the signed saturating coordinate type used by block geometry. Arithmetic saturates at the coordinate limits, while sizes still clamp their dimensions to non-negative values.

Coordinate Span

CoordinateSpan represents a half-open range on one physical axis as an origin and a non-negative extent. Reversing a non-empty span reflects its discrete cells about coordinate zero and preserves their membership.

Block Direction

Direction represents the eight compass directions on a block grid, plus None. Direction strings use text::String for parsing and text::StringLiteral backed values for canonical output.

Block Margins

Margins stores top, right, bottom and left offsets for block rectangles. Positive margins expand outward; negative margins inset or reduce geometry where the consuming API supports it. Its horizontal(), vertical(), and component() accessors return a MarginPair.

Margin Pair

MarginPair stores leading and trailing offsets along one axis. Use extent() for the total positive space consumed, delta() for the signed sum, and spacing() for the largest positive side. Direction reversal exchanges the leading and trailing values.

Block Position

Position stores an x and y coordinate for block grids. It is useful both as an absolute position and as a small vector for block-based arithmetic.

Block Size

Size stores a non-negative width and height. Negative inputs are clamped to zero, even though the underlying coordinate type itself supports negative values.

Block Rectangle

Rectangle stores an axis-aligned rectangle as a top-left position and a Size. Position transforms use the size transform in local rectangle coordinates and translate the result back to global coordinates. Horizontal mirroring exchanges left and right, vertical mirroring exchanges top and bottom.

Interface

struct AlignedSource

Effective source and target rectangles after alignment.

See: Block Geometry

Public Members

Rectangle targetRect

The target rectangle inside the alignment box.

Rectangle sourceRect

The source rectangle after alignment-based cropping.

using erbsland::block::Coordinate = math::SatInt32

Represents a coordinate value with saturation arithmetic.

class CoordinateSpan

A one-dimensional half-open coordinate span represented by an origin and a non-negative extent.

See: Block Geometry

Public Types

using AxisComponent = CoordinateSpan

The component type used for axis mapping.

Public Functions

constexpr CoordinateSpan() noexcept = default

Create an empty span at the origin.

inline constexpr CoordinateSpan(const Coordinate origin, const Coordinate extent) noexcept

Create a span from an origin and extent.

Negative extents are clamped to zero.

Parameters:
  • origin – The first coordinate in the span.

  • extent – The number of coordinates in the span.

inline constexpr CoordinateSpan(const int origin, const int extent) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

bool operator==(const CoordinateSpan&) const noexcept = default

Compare two coordinate spans.

bool operator!=(const CoordinateSpan&) const noexcept = default

Compare two coordinate spans.

inline constexpr bool isEmpty() const noexcept

Test whether this span contains no coordinates.

inline bool contains(const Coordinate coordinate) const noexcept

Test whether a coordinate lies in this half-open span.

Parameters:

coordinate – The coordinate to test.

Returns:

true if origin() <= coordinate < end().

inline constexpr Coordinate origin() const noexcept

Get the first coordinate in the span.

inline constexpr void setOrigin(const Coordinate origin) noexcept

Set the first coordinate in the span.

inline constexpr void setOrigin(const int origin) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate extent() const noexcept

Get the non-negative extent.

inline constexpr void setExtent(const Coordinate extent) noexcept

Set the extent, clamping negative values to zero.

inline constexpr void setExtent(const int extent) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline Coordinate end() const noexcept

Get the first excluded coordinate using saturated arithmetic.

inline constexpr CoordinateSpan component(const geometry::Axis axis) const

Get this one-dimensional component.

Parameters:

axis – The requested axis, which must be X.

Throws:

err::ParameterError – if axis is not X.

Returns:

This span.

inline CoordinateSpan component(const geometry::SignedAxis axis) const

Get this one-dimensional component with an optional reversal.

Parameters:

axis – The signed axis, which must select X.

Throws:

err::ParameterError – if axis does not select X.

Returns:

This span, reversed when requested.

inline CoordinateSpan reversed() const noexcept

Reverse this span about coordinate zero while preserving discrete cell membership.

Returns:

The reversed span with the same extent.

Public Static Attributes

static constexpr auto cDimensionality = geometry::Dimensionality::One

The number of dimensions represented by this type.

class Direction

A direction in a block like grid.

See: Block Geometry

Public Types

enum Enum

The enum for the direction.

Values:

enumerator None

No direction.

enumerator North

North.

enumerator NorthEast

North-east.

enumerator East

East.

enumerator SouthEast

South-east.

enumerator South

South.

enumerator SouthWest

South-west.

enumerator West

West.

enumerator NorthWest

North-west.

enumerator _EnumCount

The number of directions enums.

Public Functions

constexpr Direction() noexcept = default

Create a direction with value None.

inline constexpr Direction(const Enum value) noexcept

Create a direction from an enum value.

inline Direction &operator=(const Enum value) noexcept

Assign an enum value.

inline constexpr operator Enum() const noexcept

Convert to the enum value.

constexpr bool operator==(const Direction&) const noexcept = default

Compare two directions.

inline constexpr bool operator==(const Enum value) const noexcept

Compare with an enum value.

bool contains(Direction direction) const noexcept

Test if this direction contains (lexically) another direction.

Examples:

  • NW contains N

  • NW contains W

  • NW contains NW

  • NW does not contain S

  • NW does not contain SW (they just overlap).

inline std::size_t hash() const noexcept

Get a hash for this direction.

Position toDelta() const noexcept

Convert this direction into a position delta.

Returns:

The unit delta for this direction, or (0,0) for None.

text::String toString() const noexcept

Convert this direction into a canonical lowercase string.

Returns:

The normalized direction name.

Public Static Functions

static Direction fromDelta(Position delta) noexcept

Convert a position delta into a direction.

Only tests the signs of the x and y value in the given position.

Parameters:

delta – The position delta to convert.

Returns:

The direction for the given delta, or None if the delta is zero.

static bool isValidString(const text::String &text) noexcept

Test if text can be parsed as a direction.

Accepts empty text, abbreviations and normalized names.

Parameters:

text – The direction text.

Returns:

true if fromString() accepts the text.

static Direction fromString(const text::String &text) noexcept

Parse a direction from text.

Accepts empty text, abbreviations and normalized names.

Parameters:

text – The direction text.

Returns:

The parsed direction, or None if the text is invalid.

Public Static Attributes

static constexpr auto cCount = static_cast<std::size_t>(_EnumCount)

The number of directions enums.

Friends

inline friend constexpr bool operator==(const Enum value, const Direction &direction) noexcept

Compare an enum value with a direction.

class MarginPair

Leading and trailing margins along one axis.

See: Block Geometry

Public Types

using AxisComponent = MarginPair

The component type used for axis mapping.

Public Functions

constexpr MarginPair() noexcept = default

Create zero leading and trailing margins.

inline explicit constexpr MarginPair(const Coordinate both) noexcept

Create equal leading and trailing margins.

Parameters:

both – The value for both margins.

inline explicit constexpr MarginPair(const int both) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr MarginPair(const Coordinate leading, const Coordinate trailing) noexcept

Create separate leading and trailing margins.

Parameters:
  • leading – The leading margin.

  • trailing – The trailing margin.

inline constexpr MarginPair(const int leading, const int trailing) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

bool operator==(const MarginPair&) const noexcept = default

Compare two margin pairs.

bool operator!=(const MarginPair&) const noexcept = default

Compare two margin pairs.

inline constexpr MarginPair operator-() const noexcept

Negate both margins.

inline constexpr Coordinate leading() const noexcept

Get the leading margin.

inline constexpr void setLeading(const Coordinate leading) noexcept

Set the leading margin.

inline constexpr void setLeading(const int leading) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate trailing() const noexcept

Get the trailing margin.

inline constexpr void setTrailing(const Coordinate trailing) noexcept

Set the trailing margin.

inline constexpr void setTrailing(const int trailing) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr MarginPair component(const geometry::Axis axis) const

Get this one-dimensional component.

Parameters:

axis – The requested axis, which must be X.

Throws:

err::ParameterError – if axis is not X.

Returns:

This pair.

inline constexpr MarginPair component(const geometry::SignedAxis axis) const

Get this one-dimensional component with an optional reversal.

Parameters:

axis – The signed axis, which must select X.

Throws:

err::ParameterError – if axis does not select X.

Returns:

This pair, reversed when requested.

inline Coordinate extent() const noexcept

Get the space consumed by positive margins.

inline Coordinate delta() const noexcept

Get the signed size delta caused by both margins.

inline constexpr Coordinate spacing() const noexcept

Get the greatest positive margin.

inline constexpr MarginPair reversed() const noexcept

Exchange the leading and trailing margins.

inline constexpr MarginPair &expandTo(const MarginPair other) noexcept

Expand both margins to at least the matching margins in another pair.

Parameters:

other – The minimum margins.

Returns:

This pair.

inline constexpr MarginPair &limitTo(const MarginPair other) noexcept

Limit both margins to the matching margins in another pair.

Parameters:

other – The maximum margins.

Returns:

This pair.

inline constexpr MarginPair &expandPositive() noexcept

Clamp both margins to zero or positive values.

Returns:

This pair.

inline constexpr MarginPair expandedWith(const MarginPair other) const noexcept

Create a copy expanded to at least the matching margins in another pair.

Parameters:

other – The minimum margins.

Returns:

The expanded pair.

inline constexpr MarginPair limitedWith(const MarginPair other) const noexcept

Create a copy limited to the matching margins in another pair.

Parameters:

other – The maximum margins.

Returns:

The limited pair.

inline constexpr MarginPair expandedPositive() const noexcept

Create a copy clamped to zero or positive values.

Public Static Attributes

static constexpr auto cDimensionality = geometry::Dimensionality::One

The number of dimensions represented by this type.

class Margins

Represents margins (top, right, bottom, left) around a rectangle.

See: Block Geometry

Public Types

enum class Side : uint8_t

The side of the margin.

Values:

enumerator Top

The top side.

enumerator Right

The right side.

enumerator Bottom

The bottom side.

enumerator Left

The left side.

using AxisComponent = MarginPair

The component type used for axis mapping.

Public Functions

constexpr Margins() noexcept = default

Create zero margins.

inline explicit constexpr Margins(const Coordinate allSides) noexcept

Construct margins with the same value on all sides.

Parameters:

allSides – Value applied to top, right, bottom and left.

inline explicit constexpr Margins(const int allSides) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Margins(const Coordinate horizontal, const Coordinate vertical) noexcept

Construct margins with separate horizontal and vertical values.

Parameters:
  • horizontal – Value applied to left and right.

  • vertical – Value applied to top and bottom.

inline constexpr Margins(const int horizontal, const int vertical) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Margins(const MarginPair horizontal, const MarginPair vertical) noexcept

Construct margins from horizontal and vertical margin pairs.

Parameters:
  • horizontal – The left/right margins as leading/trailing values.

  • vertical – The top/bottom margins as leading/trailing values.

inline constexpr Margins(const Coordinate top, const Coordinate right, const Coordinate bottom, const Coordinate left) noexcept

Construct margins with individually specified sides.

Parameters:
  • top – Top margin.

  • right – Right margin.

  • bottom – Bottom margin.

  • left – Left margin.

inline constexpr Margins(const int top, const int right, const int bottom, const int left) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

bool operator==(const Margins&) const noexcept = default

Compare two margin sets.

bool operator!=(const Margins&) const noexcept = default

Compare two margin sets.

inline constexpr Margins operator-() const noexcept

Negate every margin.

inline constexpr Coordinate operator[](const Side side) const noexcept

Get the margin at a side.

inline constexpr Coordinate top() const noexcept

Get the top margin.

inline constexpr void setTop(const Coordinate value) noexcept

Set the top margin.

inline constexpr void setTop(const int value) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate right() const noexcept

Get the right margin.

inline constexpr void setRight(const Coordinate value) noexcept

Set the right margin.

inline constexpr void setRight(const int value) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate bottom() const noexcept

Get the bottom margin.

inline constexpr void setBottom(const Coordinate value) noexcept

Set the bottom margin.

inline constexpr void setBottom(const int value) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate left() const noexcept

Get the left margin.

inline constexpr void setLeft(const Coordinate value) noexcept

Set the left margin.

inline constexpr void setLeft(const int value) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate at(const Side side) const noexcept

Get the margin at a side.

inline constexpr void set(const Side side, const Coordinate value) noexcept

Set the margin at a side.

inline constexpr void set(const Side side, const int value) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr MarginPair horizontal() const noexcept

Get the horizontal left/right margin pair.

inline constexpr void setHorizontal(const MarginPair margins) noexcept

Set the horizontal left/right margin pair.

inline constexpr MarginPair vertical() const noexcept

Get the vertical top/bottom margin pair.

inline constexpr void setVertical(const MarginPair margins) noexcept

Set the vertical top/bottom margin pair.

inline constexpr MarginPair component(const geometry::Orientation orientation) const noexcept

Get the margin pair for an orientation.

inline constexpr void setComponent(const geometry::Orientation orientation, const MarginPair margins) noexcept

Set the margin pair for an orientation.

inline constexpr MarginPair component(const geometry::Axis axis) const

Get the margin pair for a physical axis.

Parameters:

axis – The physical axis to select.

Throws:

err::ParameterError – if axis is Z.

Returns:

The selected margin pair.

inline constexpr void setComponent(const geometry::Axis axis, const MarginPair margins)

Set the margin pair for a physical axis.

Parameters:
  • axis – The physical axis to select.

  • margins – The new margin pair.

Throws:

err::ParameterError – if axis is Z.

inline constexpr MarginPair component(const geometry::SignedAxis axis) const

Get the margin pair for a signed physical axis.

Parameters:

axis – The signed physical axis to select.

Throws:

err::ParameterError – if axis selects Z.

Returns:

The selected pair, reversed when requested.

inline Size extent() const noexcept

Get the positive horizontal and vertical extents.

inline constexpr Size spacing() const noexcept

Get the horizontal and vertical spacing.

inline constexpr Margins &expandTo(const Margins other) noexcept

Expand all sides to at least the matching sides in another margin set.

Parameters:

other – The minimum margins.

Returns:

This margin set.

inline constexpr Margins &expandTo(const Margins other, const geometry::Orientation orientation) noexcept

Expand both sides of one orientation.

Parameters:
  • other – The minimum margins.

  • orientation – The orientation to modify.

Returns:

This margin set.

inline constexpr Margins &expandTo(const Margins other, const Side side) noexcept

Expand one side.

Parameters:
  • other – The minimum margins.

  • side – The side to modify.

Returns:

This margin set.

inline constexpr Margins &expandPositive() noexcept

Clamp all margins to zero or positive values.

Returns:

This margin set.

inline constexpr Margins &limitTo(const Margins other) noexcept

Limit all sides to the matching sides in another margin set.

Parameters:

other – The maximum margins.

Returns:

This margin set.

inline constexpr Margins &limitTo(const Margins other, const geometry::Orientation orientation) noexcept

Limit both sides of one orientation.

Parameters:
  • other – The maximum margins.

  • orientation – The orientation to modify.

Returns:

This margin set.

inline constexpr Margins &limitTo(const Margins other, const Side side) noexcept

Limit one side.

Parameters:
  • other – The maximum margins.

  • side – The side to modify.

Returns:

This margin set.

inline constexpr Margins expandedWith(const Margins other) const noexcept

Create a copy expanded to at least the matching sides in another margin set.

Parameters:

other – The minimum margins.

Returns:

The expanded margins.

inline constexpr auto expandedWith(const Margins other, const geometry::Orientation orientation) const noexcept -> Margins

Create a copy expanded along one orientation.

Parameters:
  • other – The minimum margins.

  • orientation – The orientation to modify.

Returns:

The expanded margins.

inline constexpr Margins expandedWith(const Margins other, const Side side) const noexcept

Create a copy expanded on one side.

Parameters:
  • other – The minimum margins.

  • side – The side to modify.

Returns:

The expanded margins.

inline constexpr Margins expandedPositive() const noexcept

Create a copy clamped to zero or positive values.

inline constexpr Margins limitedWith(const Margins other) const noexcept

Create a copy limited to the matching sides in another margin set.

Parameters:

other – The maximum margins.

Returns:

The limited margins.

inline constexpr auto limitedWith(const Margins other, const geometry::Orientation orientation) const noexcept -> Margins

Create a copy limited along one orientation.

Parameters:
  • other – The maximum margins.

  • orientation – The orientation to modify.

Returns:

The limited margins.

inline constexpr Margins limitedWith(const Margins other, const Side side) const noexcept

Create a copy limited on one side.

Parameters:
  • other – The maximum margins.

  • side – The side to modify.

Returns:

The limited margins.

Public Static Attributes

static constexpr auto cDimensionality = geometry::Dimensionality::Two

The number of dimensions represented by this type.

class Position

Represents a 2D integer position or vector (x, y).

  • Lightweight value type with default construction to (0,0).

  • Useful both for coordinates in a grid and for 2D vector arithmetic.

    See: Block Geometry

Public Types

using AxisComponent = Coordinate

The component type used for axis mapping.

Public Functions

Position() = default

Default construct to (0,0).

inline constexpr Position(const Coordinate x, const Coordinate y) noexcept

Construct from explicit coordinates.

Parameters:
  • x – The x-coordinate.

  • y – The y-coordinate.

inline constexpr Position(const int x, const int y) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

bool operator==(const Position &other) const noexcept = default

Equality comparison (component-wise).

bool operator!=(const Position &other) const noexcept = default

Inequality comparison (component-wise).

inline Position operator+(const Position &other) const noexcept

Vector addition (component-wise).

Parameters:

other – The other position to add.

Returns:

A Position with coordinates (_x + other._x, _y + other._y).

inline Position operator-(const Position &other) const noexcept

Vector subtraction (component-wise).

Parameters:

other – The other position to subtract.

Returns:

A Position with coordinates (_x - other._x, _y - other._y).

inline Position &operator+=(const Position &other) noexcept

Add another position to this one in-place.

Parameters:

other – The other position to add.

Returns:

Reference to this position.

inline Position &operator-=(const Position &other) noexcept

Subtract another position from this one in-place.

Parameters:

other – The other position to subtract.

Returns:

Reference to this position.

inline constexpr Coordinate x() const noexcept

Get the x coordinate.

void setX(Coordinate x) noexcept

Set the x coordinate.

Parameters:

x – New x value.

inline void setX(int x) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate y() const noexcept

Get the y coordinate.

void setY(Coordinate y) noexcept

Set the y coordinate.

Parameters:

y – New y value.

inline void setY(int y) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate component(const geometry::Orientation orientation) const noexcept

Get the component for the selected orientation.

Parameters:

orientation – The orientation that selects the x or y component.

Returns:

x() for geometry::Orientation::Horizontal, otherwise y().

inline constexpr Coordinate component(const geometry::Axis axis) const

Get the component for a physical axis.

Parameters:

axis – The physical axis to select.

Throws:

err::ParameterError – if axis is Z.

Returns:

The selected coordinate.

inline constexpr Coordinate component(const geometry::SignedAxis axis) const

Get the component for a signed physical axis.

Parameters:

axis – The signed physical axis to select.

Throws:

err::ParameterError – if axis selects Z.

Returns:

The selected coordinate, negated for a reversed axis.

inline std::size_t hash() const noexcept

Get a hash for this position.

This hash is designed to be fast and uniform for both 32-bit and 64-bit platforms. It is not only optimized to be used in a map but also as a source for pseudo-randomness.

Coordinate distanceTo(Position other) const noexcept

Manhattan (L1) distance to another position.

Parameters:

other – The other position.

Returns:

|x - other.x| + |y - other.y|.

inline Position componentMax(Position other) const noexcept

Component-wise maximum with another position.

Parameters:

other – The other position.

Returns:

A Position containing the max of each component.

inline Position componentMin(Position other) const noexcept

Component-wise minimum with another position.

Parameters:

other – The other position.

Returns:

A Position containing the min of each component.

inline std::array<Position, 4> cardinalFour() const noexcept

Get the four cardinal positions, relative to this one.

Order: right, down, left, up

template<typename Fn>
uint32_t cardinalFourBitmask(Fn fn) const noexcept

Create a bitmask testing the four cardinal positions.

Parameters:

fn – The function to test each cardinal delta position, relative to this one.

inline std::array<Position, 8U> ringEight() const noexcept

Get the eight positions that form a ring around this position.

Clockwise order: 0:E, 1:SE, 2:S, 3:SW, 4:W, 5:NW, 6:N, 7:NE

Returns:

An array with all the eight positions.

Public Static Functions

static const std::array<Position, 4> &cardinalFourDeltas() noexcept

Get the four cardinal position deltas.

Order: right, down, left, up

static const std::array<Position, 8U> &ringEightDeltas() noexcept

Get the eight deltas that form a ring around this position.

Clockwise order: 0:E, 1:SE, 2:S, 3:SW, 4:W, 5:NW, 6:N, 7:NE

static inline Position minimum() noexcept

Get the point with the minimum coordinates.

static inline Position maximum() noexcept

Get the point with the maximum coordinates.

Public Static Attributes

static constexpr auto cDimensionality = geometry::Dimensionality::Two

The number of dimensions represented by this type.

class Rectangle

Axis-aligned rectangle represented by a top-left position and size.

Provides geometry utilities such as containment tests, expansion and iteration.

See: Block Geometry

Public Types

using AxisComponent = CoordinateSpan

The component type used for axis mapping.

Public Functions

Rectangle() = default

Construct an empty rectangle at (0,0).

inline constexpr Rectangle(Coordinate x, Coordinate y, Coordinate width, Coordinate height) noexcept

Construct from explicit position and size values.

Parameters:
  • x – X-coordinate of the top-left corner.

  • y – Y-coordinate of the top-left corner.

  • width – BlockRect width.

  • height – BlockRect height.

inline constexpr Rectangle(const int x, const int y, const int width, const int height) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Rectangle(Position pos, Size size) noexcept

Construct from position and size objects.

Parameters:
  • pos – Top-left corner position.

  • size – BlockRect size.

inline constexpr Rectangle(const CoordinateSpan horizontal, const CoordinateSpan vertical) noexcept

Construct from horizontal and vertical coordinate spans.

Parameters:
  • horizontal – The horizontal origin and extent.

  • vertical – The vertical origin and extent.

inline Rectangle(const Position topLeft, const Position bottomRight) noexcept

Construct from a top-left and bottom-right (exclusive) corner position.

If the bottom right is left or above the top-left corner, the rectangle will be empty.

Parameters:
  • topLeft – The top-left corner inside the new rectangle.

  • bottomRight – The bottom-right corner outside the new rectangle.

bool operator==(const Rectangle &other) const noexcept = default

Compare two rectangles.

bool operator!=(const Rectangle &other) const noexcept = default

Compare two rectangles.

Rectangle operator|(const Rectangle &other) const noexcept

Merge two rectangles into a larger one that holds both rectangles.

Rectangle &operator|=(const Rectangle &other) noexcept

Expand this rectangle to include another rectangle.

Parameters:

other – The other rectangle to merge.

Returns:

Reference to this rectangle.

Rectangle operator&(const Rectangle &other) const noexcept

Intersect two rectangles to get only the overlapping part.

If the two rectangles don’t overlap, return an empty rectangle.

Rectangle &operator&=(const Rectangle &other) noexcept

Change this rectangle to the intersection of both rectangles.

If the two rectangles don’t overlap, its size will be (0,0).

inline constexpr Position pos() const noexcept

Get the top-left corner position.

inline void setPos(Position pos) noexcept

Set the top-left corner position.

Parameters:

pos – New position value.

inline constexpr Size size() const noexcept

Get the size of the rectangle.

inline void setSize(Size size) noexcept

Set the size of the rectangle.

Parameters:

size – New size value.

inline constexpr Coordinate x1() const noexcept

Left x-coordinate.

inline constexpr Coordinate y1() const noexcept

Top y-coordinate.

inline Coordinate x2() const noexcept

Right x-coordinate (exclusive).

inline Coordinate y2() const noexcept

Bottom y-coordinate (exclusive).

inline constexpr Position topLeft() const noexcept

Top-left corner position.

Is equivalent to pos().

inline Position topRight() const noexcept

Top-right corner position (x-coordinate exclusive).

inline Position bottomLeft() const noexcept

Bottom-left corner position (y-coordinate exclusive).

inline Position bottomRight() const noexcept

Bottom-right corner position (x-coordinate exclusive, y-coordinate exclusive).

inline constexpr Coordinate width() const noexcept

BlockRect width.

inline constexpr Coordinate height() const noexcept

BlockRect height.

inline constexpr CoordinateSpan component(const geometry::Orientation orientation) const noexcept

Get the coordinate span for an orientation.

Parameters:

orientation – The orientation to select.

Returns:

The selected horizontal or vertical span.

inline constexpr CoordinateSpan component(const geometry::Axis axis) const

Get the coordinate span for a physical axis.

Parameters:

axis – The physical axis to select.

Throws:

err::ParameterError – if axis is Z.

Returns:

The selected coordinate span.

inline constexpr CoordinateSpan component(const geometry::SignedAxis axis) const

Get the coordinate span for a signed physical axis.

Parameters:

axis – The signed physical axis to select.

Throws:

err::ParameterError – if axis selects Z.

Returns:

The selected span, reversed when requested.

Position anchor(geometry::Anchor anchor = geometry::Anchor::TopLeft) const noexcept

Position of a given anchor within this rectangle.

Parameters:

anchor – Anchor to query.

Returns:

The position inside this rectangle matching the requested anchor.

inline Position center() const noexcept

Center position.

This is equal to the position of the geometry::Anchor::Center anchor.

bool contains(Position testedPosition) const noexcept

Check if a position is inside the rectangle.

Parameters:

testedPositionPosition to test.

Returns:

true if the position lies inside the rectangle bounds.

bool contains(Rectangle testedRectangle) const noexcept

Checks if another rectangle fits into this one.

Only true if every position of the tested rectangle is inside this one.

Parameters:

testedRectangle – The rectangle to test for containment.

Returns:

true if the tested rectangle is fully contained within this one.

bool overlaps(Rectangle testedRectangle) const noexcept

Check if another rectangle overlaps this one.

Overlapping is when both rectangles share at least one position.

Parameters:

testedRectangle – The rectangle to test for overlap.

bool isFrame(Position testedPosition) const noexcept

Check if a position lies on the rectangle frame.

Parameters:

testedPositionPosition to test.

Returns:

true if the position lies on the outer frame of the rectangle.

inline std::size_t hash() const noexcept

Get a hash for this rectangle.

Position clamp(Position position) const noexcept

Clamp a position to this rectangle.

Parameters:

position – The position to clamp.

Returns:

The clamped position where (x1 <= position.x <= x2) && (y1 <= position.y <= y2)

Rectangle expandedBy(Margins margins) const noexcept

Create a rectangle expanded by the provided margins.

Parameters:

marginsMargins to apply; positive values expand outward.

Returns:

The expanded rectangle.

Rectangle insetBy(Margins margins) const noexcept

Create a rectangle inset by the provided margins.

Parameters:

marginsMargins to remove from each side.

Returns:

The inset rectangle.

Rectangle subRectangle(geometry::Anchor anchor, Size size, Margins margins) const noexcept

Create a sub-rectangle inside this rectangle.

Parameters:
  • anchor – The anchor of the rectangle.

  • size – The size. Zero means full width/height.

  • margins – The margins around the sub rectangle.

Returns:

The aligned sub-rectangle.

Position alignmentOffset(Size contentSize, geometry::Alignment alignment) const noexcept

Compute the position for content aligned inside this rectangle.

If contentSize is larger than this rectangle on an axis, the returned position on that axis lies before topLeft() on that axis.

Parameters:
  • contentSize – The aligned content size.

  • alignment – The alignment for the content.

Returns:

The aligned content position relative to the global coordinate space.

AlignedSource alignedSource(Rectangle sourceRect, geometry::Alignment alignment) const noexcept

Align a source rectangle inside this rectangle and crop the larger side according to the alignment.

If the source is smaller than this rectangle on an axis, the returned target rectangle is moved inside this rectangle. If the source is larger on an axis, the returned source rectangle is cropped on that axis.

Parameters:
  • sourceRect – The source rectangle before alignment and cropping.

  • alignment – The alignment used for placement or cropping.

Returns:

The effective target rectangle and source rectangle after alignment.

int64_t frameIndex(Position testedPosition) const noexcept

Get the clockwise border index for a frame position.

The top-left corner has index 0, then the index increases clockwise around the perimeter. Degenerate rectangles with width or height 1 still produce a continuous index sequence.

Parameters:

testedPosition – The position on the frame.

Returns:

The clockwise border index, or -1 if the position is not on the frame.

Direction frameDirection(Position testedPosition) const noexcept

Get the frame direction for a given position in this rectangle.

Returns:

The direction of the frame at the given position, or Direction::None if the position is not on the frame.

auto gridCells(int rows, int columns, Coordinate horizontalSpacing = Coordinate{0}, Coordinate verticalSpacing = Coordinate{0}) const -> std::vector<Rectangle>

Divide this rectangle into equally spaced grid cells.

Each cell must be at least 1x1 in size, if this isn’t possible, err::ParameterError is thrown.

Parameters:
  • rows – The number of rows. Minimum 1.

  • columns – The number of columns. Minimum 1

  • horizontalSpacing – The spacing between cells horizontally.

  • verticalSpacing – The spacing between cells vertically.

Throws:

err::ParameterError – if rows or columns are less than 1 or the chosen division is impossible.

Returns:

A vector of rectangles representing the grid cells from left to right, top to bottom.

inline auto gridCells(const int rows, const int columns, const int horizontalSpacing, const int verticalSpacing) const -> std::vector<Rectangle>

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Position rotateCCW(const Position &pos, int rotation) const noexcept

Rotate a global position counter-clockwise around this rectangle.

Positions outside the rectangle are transformed by the same affine mapping. Rotation is normalized to 90 degree steps, so negative values rotate clockwise.

Parameters:
  • pos – The global position to rotate.

  • rotation – The number of 90 degree counter-clockwise rotation steps.

Returns:

The transformed global position.

Position mirror(const Position &pos, geometry::Orientation orientation) const noexcept

Mirror a global position horizontally or vertically inside this rectangle.

Horizontal mirroring exchanges left and right. Vertical mirroring exchanges top and bottom.

Parameters:
  • pos – The global position to mirror.

  • orientation – The mirror orientation.

Returns:

The transformed global position.

Position transform(const Position &pos, geometry::Symmetry symmetry) const noexcept

Transform a global position using a block symmetry.

Parameters:
  • pos – The global position to transform.

  • symmetry – The symmetry to apply.

Returns:

The transformed global position.

template<typename Fn>
void forEach(Fn fn) const

Call a function for each position contained in the rectangle.

Template Parameters:

Fn – A callable with signature void(Position). The function definition must be void fn(Position pos).

template<typename Fn>
void forEachInFrame(Fn fn) const

Call a function for each position around the frame, clockwise with index.

Template Parameters:

Fn – A callable with signature void(Position, int). The function definition must be void fn(Position pos, int index).

Public Static Functions

static Rectangle bounds(const PositionList &positions) noexcept

Get the bounds from the given positions.

Parameters:

positions – The positions to get the bounds from.

Returns:

A rectangle that contains all positions.

Public Static Attributes

static constexpr auto cDimensionality = geometry::Dimensionality::Two

The number of dimensions represented by this type.

class Size

A non-negative 2D size (width × height).

  • Width and height are clamped to be >= 0.

  • Many operations assume a grid indexed from (0,0) to (width-1,height-1).

    See: Block Geometry

Public Types

using AxisComponent = Coordinate

The component type used for axis mapping.

Public Functions

Size() = default

Construct a zero size (0 × 0).

inline constexpr Size(const Coordinate width, const Coordinate height) noexcept

Construct a size from explicit width and height.

Negative inputs are clamped to 0.

Parameters:
  • width – The desired width (clamped to >= 0).

  • height – The desired height (clamped to >= 0).

inline constexpr Size(const int width, const int height) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline Size(const Position pos1, const Position pos2) noexcept

Construct a size from the axis-aligned distance between two positions.

Note

The order of the positions does not matter; absolute differences are used.

Parameters:
  • pos1 – First position.

  • pos2 – Second position.

bool operator==(const Size &other) const noexcept = default

Equality comparison on width and height.

bool operator!=(const Size &other) const noexcept = default

Inequality comparison on width and height.

inline Size operator+(const Size &other) const noexcept

Add two sizes using saturated arithmetic.

Parameters:

other – The size to add.

Returns:

The component-wise sum, capped at the maximum coordinate value.

inline Size operator-(const Size &other) const noexcept

Subtract two sizes using saturated arithmetic.

Parameters:

other – The size to subtract.

Returns:

The component-wise difference, clamped to non-negative values.

inline Size &operator+=(const Size &other) noexcept

Add a size using saturated arithmetic.

Parameters:

other – The size to add.

Returns:

This size.

inline Size &operator-=(const Size &other) noexcept

Subtract a size using saturated arithmetic.

Parameters:

other – The size to subtract.

Returns:

This size.

inline constexpr Coordinate width() const noexcept

Get the width (>= 0).

inline void setWidth(Coordinate width) noexcept

Set the width.

Negative values are clamped to 0.

Parameters:

width – New width (clamped to >= 0).

inline void setWidth(const int width) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate height() const noexcept

Get the height (>= 0).

inline void setHeight(Coordinate height) noexcept

Set the height.

Negative values are clamped to 0.

Parameters:

height – New height (clamped to >= 0).

inline void setHeight(const int height) noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline constexpr Coordinate component(const geometry::Orientation orientation) const noexcept

Get the component for the selected orientation.

Parameters:

orientation – The orientation that selects width or height.

Returns:

width() for geometry::Orientation::Horizontal, otherwise height().

inline constexpr Coordinate component(const geometry::Axis axis) const

Get the extent for a physical axis.

Parameters:

axis – The physical axis to select.

Throws:

err::ParameterError – if axis is Z.

Returns:

The selected non-negative extent.

inline constexpr Coordinate component(const geometry::SignedAxis axis) const

Get the extent for a signed physical axis.

Reversing an axis does not change its non-negative extent.

Parameters:

axis – The signed physical axis to select.

Throws:

err::ParameterError – if axis selects Z.

Returns:

The selected non-negative extent.

Position anchor(geometry::Anchor anchor) const noexcept

Compute a position inside the rectangle defined by this size for a given anchor.

Bottom-right resolves to (width-1, height-1), top-left to (0,0), etc.

Parameters:

anchor – The anchor describing the target corner/edge/center.

Returns:

The position inside the [0,width-1]×[0,height-1] grid (or (0,0) for empty dimensions).

Position alignmentOffset(Size contentSize, geometry::Alignment alignment) const noexcept

Compute the offset for content aligned inside this size.

If contentSize is larger than this size on an axis, the returned offset on that axis is negative.

Parameters:
  • contentSize – The aligned content size.

  • alignment – The alignment for the content.

Returns:

The zero-based offset for placing the content inside this size.

inline constexpr bool isZero() const noexcept

Test if this size is zero.

inline bool fitsInto(const Size other) const noexcept

Check if this size fits completely into another size (component-wise <=).

Parameters:

other – The candidate container size.

Returns:

true if width <= other.width and height <= other.height.

inline bool isInRange(const Size minimum, const Size maximum) const noexcept

Test if the width and height of this size is in the given range.

Parameters:
  • minimum – The minimum size.

  • maximum – The maximum size.

Returns:

true If this size is in the range minimum-maximum.

inline constexpr bool contains(const Position &pos) const noexcept

Check if a position lies strictly inside the bounds [0,width) × [0,height).

Parameters:

pos – The position to test.

Returns:

true if 0 <= x < width and 0 <= y < height.

inline Size &add(const Size other) noexcept

Add another size using saturated arithmetic.

Parameters:

other – The size to add.

Returns:

This size.

inline Size &add(const Size other, const geometry::Orientation orientation) noexcept

Add another size only on the selected axis using saturated arithmetic.

Parameters:
  • other – The size to add.

  • orientation – The axis to modify.

Returns:

This size.

inline Size &subtract(const Size other) noexcept

Subtract another size using saturated arithmetic and clamp the result to zero.

Parameters:

other – The size to subtract.

Returns:

This size.

inline Size &subtract(const Size other, const geometry::Orientation orientation) noexcept

Subtract another size only on the selected axis using saturated arithmetic and clamp the result to zero.

Parameters:
  • other – The size to subtract.

  • orientation – The axis to modify.

Returns:

This size.

inline Size &expandTo(const Size other) noexcept

Expand this size so it is at least the given size.

Parameters:

other – The minimum size to cover.

Returns:

This size.

inline Size &expandTo(const Size other, const geometry::Orientation orientation) noexcept

Expand this size so it is at least the given size on the selected axis.

Parameters:
  • other – The minimum size to cover.

  • orientation – The axis to modify.

Returns:

This size.

inline Size &limitTo(const Size other) noexcept

Limit this size so it is at most the given size.

Parameters:

other – The maximum size to respect.

Returns:

This size.

inline Size &limitTo(const Size other, const geometry::Orientation orientation) noexcept

Limit this size so it is at most the given size on the selected axis.

Parameters:
  • other – The maximum size to respect.

  • orientation – The axis to modify.

Returns:

This size.

inline Size expandedWith(const Size other) const noexcept

Create a copy expanded so it is at least the given size.

Parameters:

other – The minimum size to cover.

Returns:

The expanded size.

inline Size expandedWith(const Size other, const geometry::Orientation orientation) const noexcept

Create a copy expanded so it is at least the given size on the selected axis.

Parameters:
  • other – The minimum size to cover.

  • orientation – The axis to modify.

Returns:

The expanded size.

inline Size limitedWith(const Size other) const noexcept

Create a copy limited so it is at most the given size.

Parameters:

other – The maximum size to respect.

Returns:

The limited size.

inline Size limitedWith(const Size other, const geometry::Orientation orientation) const noexcept

Create a copy limited so it is at most the given size on the selected axis.

Parameters:
  • other – The maximum size to respect.

  • orientation – The axis to modify.

Returns:

The limited size.

inline Size clampTo(const Size minimum, const Size maximum) const noexcept

Component-wise clamp with a minimum and maximum size.

Warning

If minimum.width > maximum.width or minimum.height > maximum.height, the behavior is undefined.

Parameters:
  • minimum – The minimum size.

  • maximum – The maximum size.

Returns:

a size (min.width <= width <= max.width, min.height <= height <= max.height)

inline Position clamp(Position position) const noexcept

Clamp a position inside this size.

The resulting position is at least (0, 0) and less than (width, height).

inline constexpr math::SatInt32 area() const noexcept

Compute the area (width * height).

Returns:

The area. Note: returns 0 if either dimension is 0.

inline std::size_t index(const Position &pos) const noexcept

Convert a 2D position to a row-major linear index.

Parameters:

pos – The position. Behavior is undefined if not contained by this size.

Returns:

y * width + x.

Position rotateCCW(const Position &pos, int rotation) const noexcept

Rotate a local position counter-clockwise inside this size.

Positions outside the size are transformed by the same affine mapping. Rotation is normalized to 90 degree steps, so negative values rotate clockwise.

Parameters:
  • pos – The local position to rotate.

  • rotation – The number of 90 degree counter-clockwise rotation steps.

Returns:

The transformed local position.

Position mirror(const Position &pos, geometry::Orientation orientation) const noexcept

Mirror a local position horizontally or vertically inside this size.

Horizontal mirroring exchanges left and right. Vertical mirroring exchanges top and bottom.

Parameters:
  • pos – The local position to mirror.

  • orientation – The mirror orientation.

Returns:

The transformed local position.

Position transform(const Position &pos, geometry::Symmetry symmetry) const noexcept

Transform a local position using a block symmetry.

Parameters:
  • pos – The local position to transform.

  • symmetry – The symmetry to apply.

Returns:

The transformed local position.

template<typename Fn>
void forEach(Fn fn) const

Visit all positions inside the size in row-major order.

Template Parameters:

Fn – A callable taking Position.

Parameters:

fn – The function to invoke for each Position (x from 0..width-1, y from 0..height-1).

Public Static Functions

static inline constexpr Size maximum() noexcept

Get the maximum size that can be represented by this type.

static inline constexpr Size minimum() noexcept

Get the minimum size that can be represented by this type.

static inline constexpr Size zero() noexcept

Get a size.

Public Static Attributes

static constexpr auto cDimensionality = geometry::Dimensionality::Two

The number of dimensions represented by this type.