# lodim library

Fast pixel accurate fixed-point 2D geometry with minimum approximations.

## Usage

Most of the library is built around Pos, a fixed-point (integer-based) 2D vector class. It's used to represent positions, directions, distances, and offsets in a 2D space:

``````// Creating a position at (4, 2).
final pos = Pos(4, 2);

final other = Pos(1, 3);
print(pos + other); // => Pos(5, 5)

// Negating a position.
print(-pos); // => Pos(-4, -2)

// Calculating the distance between two positions.
final a = Pos(10, 20);
final b = Pos(30, 40);
print(a.distanceTo(b, using: euclideanSquared)); // => 500

// Rotating a position.
final rotated = pos.rotate90();
print(rotated); // => Pos(-2, 4)
``````

### Directions

Direction is a specialization of Pos with a fixed set of 8 directions; either Direction.ordinal (horizontal/vertical), Direction.cardinal (diagonal), or Direction.all (all 8 directions), with useful constants:

``````// Getting the direction to the right.
print(Direction.right); // => Pos(1, 0)

// Moving a rotation with a direction.
final pos = Pos(4, 2);
final direction = Direction.right;
print(pos + direction); // => Pos(5, 2)

// Or, multiple times.
print(pos + direction * 3); // => Pos(7, 2)
``````

### Rectangles

Rect is a rectangle class, similar to Pos, but with a width and height (or bottom-right corner) instead of a single point; useful for representing areas, sizes, and ranges, also in fixed-point (integer-based) 2D spaces:

``````// Creating a rectangle at (4, 2) with a size of 3x2.
final rect = Rect.fromLTRB(4, 2, 7, 4);
print(rect.topLeft); // => Pos(4, 2)
print(rect.bottomRight); // => Pos(7, 4)
print(rect.width); // => 3
print(rect.height); // => 2
``````

Similarily, additional methods exist for common operations:

``````// Checking if a position is inside a rectangle.
final pos = Pos(5, 3);
print(rect.contains(pos)); // => true

// Getting the intersection of two rectangles.
final other = Rect.fromLTRB(6, 3, 8, 5);
print(rect.intersect(other)); // => Rect.fromLTRB(6, 3, 7, 4)

// Iterating over all edges of a rectangle.
for (final edge in rect.edges) {
print(edge); // => Pos(x, y)
}
``````

## Classes

Pos Grids
An immutable 2D fixed-point vector.
Rect Grids
An immutable 2D fixed-point rectangle.

## Enums

Octant
An arc of a circle equal to one-eigth of its circumference.

## Extension Types

Direction Graphs Grids
A direction in a 2D space.

## Extensions

IntPair on (int, int)
Extension methods on `(int, int)` tuples for convenience.

## Functions

bresenham(Pos start, Pos end, {bool exclusive = false}) Iterable<Pos>
Calculates positions along a line optimized for fixed-point math.
chebyshev(Pos a, Pos b) int
Calculates the Chebyshev distance between two positions.
diagonal(Pos a, Pos b) int
Calculates the diagonal (ordinal) distance between two positions.
euclideanApproximate(Pos a, Pos b) int
Calculates an approximate Euclidean distance between two positions.
euclideanSquared(Pos a, Pos b) int
Calculates the squared Euclidean distance between two positions.
manhattan(Pos a, Pos b) int
Calculates the Manhattan distance between two positions.
sqrtApproximate(int n) int
Returns an approximation of the integer square root of `n`.
vectorLine(Pos start, Pos end, {bool exclusive = false}) Iterable<Pos>
Calculates positions along a line using a fast 2D vector algorithm.

## Typedefs

Distance = int Function(Pos a, Pos b)
A function that returns an integer distance between two positions.
Line = Iterable<Pos> Function(Pos start, Pos end, {bool exclusive})
A function that returns positions along a line between `start` and `end`.