i_float provides numeric primitives for deterministic 2D geometry:
- generic integer points, vectors, and rectangles;
- wide intermediate integer arithmetic;
- conversion between floating-point and integer coordinate spaces;
- fixed-scale unit ratios for interpolation;
- basic triangle predicates;
- optional
serdeandglamintegration.
The crate is no_std and supports i16, i32, and i64 coordinate types.
[dependencies]
i_float = "4.0"The default core feature exposes the complete numeric and geometry API.
IntPoint<T> stores coordinates in T. Subtracting two points produces an
IntVector<T> whose components use the associated wide integer type: i32
coordinates produce an i64 vector, while i64 coordinates produce an
i128 vector.
use i_float::int::point::IntPoint;
use i_float::triangle::Triangle;
let a = IntPoint::new(0_i32, 0);
let b = IntPoint::new(10, 0);
let c = IntPoint::new(0, 10);
let ab = b - a;
assert_eq!(ab.x, 10_i64);
assert_eq!(ab.y, 0_i64);
assert_eq!(Triangle::area_two(a, b, c), 100_i64);
assert!(!Triangle::is_clockwise(a, b, c));Integer geometry intentionally uses a coordinate range narrower than the full range of the underlying integer. Although point differences are widened, dot products, cross products, and squared lengths multiply wide values without widening them again.
A conservative common bound for all point and vector operations is:
-2^(I::BITS - 2) < coordinate < 2^(I::BITS - 2)
For example, i32 coordinates should stay strictly between
-1_073_741_824 and 1_073_741_824. This leaves enough headroom for the
difference of two points and for the sum or difference of two products in
I::Wide. Operations use normal integer arithmetic and do not perform runtime
range checks.
This bound is deliberately universal and conservative. An algorithm may use a
wider range when it proves that its particular intermediate expressions still
fit. Conversely, an IntVector constructed directly from arbitrary wide values
is not covered by the point-coordinate bound.
Floating-point input should normally be mapped with FloatPointAdapter. For an
explicit general-purpose safety margin, use with_coordinate_bits with at most
I::BITS - 3; algorithms with stronger range analysis may select a larger bit
budget.
FloatPointAdapter maps a bounded floating-point coordinate space onto an
integer grid. The same adapter converts results back into the original space.
use i_float::adapter::FloatPointAdapter;
use i_float::float::rect::FloatRect;
use i_float::int::point::IntPoint;
let bounds = FloatRect::new(-10.0_f64, 10.0, -5.0, 5.0);
let adapter = FloatPointAdapter::<[f64; 2], i32>::new(bounds);
let source = [2.5, -1.25];
let point: IntPoint<i32> = adapter.try_float_to_int(&source).unwrap();
let restored = adapter.try_int_to_float(&point).unwrap();
let tolerance = adapter.inv_scale();
assert!((restored[0] - source[0]).abs() <= tolerance);
assert!((restored[1] - source[1]).abs() <= tolerance);Use with_coordinate_bits when an algorithm has an explicit coordinate-bit
budget. The value controls only the converted coordinate magnitude; it does not
prove that every later arithmetic expression is safe. Use try_with_scale or
try_with_scale_and_coordinate_bits when a caller supplies the scale and
invalid or unsafe scales must be rejected.
UnitRatio<I> represents a value in the inclusive range 0..=1. Its stored
integer value uses FixedScale<I>::DENOMINATOR as one. Scaling rounds midpoint
values away from zero.
use i_float::int::number::unit_ratio::UnitRatio;
use i_float::int::point::IntPoint;
let quarter = UnitRatio::<i32>::from_int(1, 4);
let half = UnitRatio::<i32>::half();
assert_eq!(quarter.scale(10), 3);
assert_eq!(quarter.scale(-10), -3);
assert_eq!(quarter.mid(half), UnitRatio::from_int(3, 8));
let point = IntPoint::new(100, -40);
assert_eq!(quarter.scale_point(point), IntPoint::new(25, -10));Constructors currently expect valid input. In particular, new expects a
stored value between zero and DENOMINATOR, from_float expects a finite value
between zero and one, and from_int expects 0 <= numerator <= denominator.
These preconditions are checked by debug assertions.
| Feature | Default | Description |
|---|---|---|
core |
yes | Integer and floating-point primitives, adapters, and triangle predicates |
serde |
no | Enables serialization for supported geometry types and also enables core |
glam |
no | Adds conversions for glam::Vec2, DVec2, and IVec2 and also enables core |
Licensed under the MIT License. See the LICENSE file.