Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/matanlurey/lodim
Fixed-point 2D geometry.
https://github.com/matanlurey/lodim
dart-lang geometry integer
Last synced: about 1 month ago
JSON representation
Fixed-point 2D geometry.
- Host: GitHub
- URL: https://github.com/matanlurey/lodim
- Owner: matanlurey
- License: mit
- Created: 2024-07-05T19:05:38.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2024-09-07T22:28:04.000Z (2 months ago)
- Last Synced: 2024-09-29T16:04:03.504Z (about 1 month ago)
- Topics: dart-lang, geometry, integer
- Language: Dart
- Homepage: https://pub.dev/packages/lodim
- Size: 717 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# lodim
_Fast_ and _pixel accurate_ fixed-point 2D geometry with minimal approximations.
[![CI](https://github.com/matanlurey/lodim/actions/workflows/ci.yaml/badge.svg)](https://github.com/matanlurey/lodim/actions/workflows/ci.yaml)
[![Coverage Status](https://coveralls.io/repos/github/matanlurey/lodim/badge.svg?branch=main)](https://coveralls.io/github/matanlurey/lodim?branch=main)
[![Pub Package](https://img.shields.io/pub/v/lodim.svg)](https://pub.dev/packages/lodim)
[![Dartdoc reference](https://img.shields.io/badge/dartdoc-reference-blue.svg)](https://pub.dev/documentation/lodim/latest/)Optimal for the following use cases:
- 2D game development that uses tile-based or grid-based rendering.
- Graphic rendering of pixel art or other fixed-point rasterized graphics.
- Fixed-point geometry for performance or consistency reasons.## Features
Use `lodim` to quickly work with 2D geometry in a fixed-point space:
- **Fixed-point**: All values and results are _always_ integers.
- **Fast**: AOT and JIT benchmarked on the Dart VM.
- **Pixel accurate**: Minimal[^1] ambiguity or hidden rounding errors.
- **Ergonomics**: Familiar API to `dart:ui` (and similar) for ease of use.
- **Cross-platform**: Works on all Dart platforms, including Flutter and web.[^1]: `lodim` does provide some algorithms that make approximations, such as
`.lineTo`, which uses [Bresenham's line algorithm][bresenham].
However, all of these algorithms are cleanly defined and documented, and
allow user-defined overrides.[bresenham]: https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
### Design Principles
`lodim` is designed to be a low-level, fixed-point geometry library that is not
opionated about how you use it. It is not a game engine, nor does it provide
high-level abstractions for rendering or collections.For example, top-level functions such as `getRect` or `fillRect` operate on
either `Rect` or `Pos` types and either callback methods or a generic linear
buffer. For a higher-level APIs, consider using `lodim` in conjunction with
another library, such as [`package:sector`](https://pub.dev/packages/sector).## Usage
Just add a dependency in your `pubspec.yaml` or run the following command:
```bash
dart pub add lodim
```If you've used another 2D geometry library, such as [`dart:ui`][dart_ui] from
Flutter, you will find `lodim` to be very similar. Work with similar types such
as `Pos` (i.e. `Offset`) and `Rect`:[dart_ui]: https://api.flutter.dev/flutter/dart-ui/dart-ui-library.html
```dart
// Creates a (x, y) position.
final pos = Pos(10, 20);// Creates a rectangle.
final rect = Rect.fromLTWH(0, 0, 100, 100);
```Take advantage of tested and benchmarked common operations:
```dart
// Rotate a position by 135 degrees counter-clockwise.
final rotated = pos.rotate45(-3);// Get the intersection of two rectangles.
final intersection = rect.intersect(a, b);
```Use built-in algorithms for common tasks, or define your own:
```dart
// Determine the distance between two positions.
final distance = pos1.distanceTo(pos2);// Use another algorithm to determine the distance or define your own.
final manhattan = pos1.distanceTo(pos2, using: manhattan);// Draw a line from one position to another.
final line = pos1.lineTo(pos2);// Use your own algorithm to draw a line.
final custom = pos1.lineTo(pos2, using: someOtherAlgorithm);
```## Benchmarks
To run the benchmarks, run:
```shell
dart run benchmark/benchmark.dart# Or, to use AOT:
dart compile exe benchmark/benchmark.dart
./benchmark/benchmark.exe# Or, to profile using devtools:
dart run --pause-isolates-on-start --observe benchmark/benchmark.dart
```In local benchmarks on a M2 Macbook Pro, compared to [baseline][^2] code.
[^2]: What users might write themselves, using `(int, int)` tuples or similar.
**JIT**:
| Benchmark | `lodim` | Baseline | Delta |
| -------------------------- | ------------ | ----------- | ------ |
| 10k allocations positions | 479.8 us | 362.9 us | -25% |
| 10k euclidian distance | 138.3 us | 153.5 us | +11% |
| 10k rotations in 45° steps | 6875.8 us | 13658.7 us | +98% |
| 10k lines drawn | 1340049.5 | - | - |**AOT**:
| Benchmark | `lodim` | Baseline | Delta |
| -------------------------- | ------------ | ----------- | ------ |
| 10k allocations positions | 342.7 us | 463.9 us | +35% |
| 10k euclidian distance | 139.7 us | 132.7 us | -5% |
| 10k rotations in 45° steps | 5858.2 us | 11708.0 us | +100% |
| 10k lines drawn | 1333651.0 us | - | - |**tl;dr**: `lodim` is _faster_ than baseline code, using both JIT and AOT.
Specializing based on fixed-point geometry allows for optimizations that are
not possible with general-purpose code, such as jump-table based rotations.## Contributing
To run the tests, run:
```shell
dart test
```To check code coverage locally, run:
```shell
dart tool/coverage.dart
```To preview `dartdoc` output locally, run:
```shell
dart tool/dartdoc.dart
```