[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![License][license-shield]][license-url]
Hexing
"Hexagons are the bestagons"
A basic Rust library to manipulate hexagonal grids.
---
`hexing` is a Rust library designed for manipulation and calculations on hexagonal grids. It provides tools for working with hexagonal positions and directions, as well as iterators for exploring hexagonal rings and spirals.
## Features
- **Hexagonal Coordinate Manipulation**: Represent and manipulate positions in a hexagonal grid using axial coordinates.
- **Distance Calculations**: Compute the distance between two hexagonal positions.
- **Pixel Coordinate Conversion**: Convert hexagonal positions to pixel coordinates for graphical use.
- **Reflection and Rotation**: Apply reflection and rotation to hexagonal positions.
- **Ring and Spiral Iterators**: Obtain positions in a ring or spiral around a central position.
- **Bounding**: Calculate if a point is within a hexagonal bounding box.
- **Line Iterators**: Obtain positions along a line between two hexagonal positions.
- **Number Trait**: Allow generic calculations with various numeric types.
- **Serialization and Deserialization**: Serialize and deserialize hexagonal positions and directions with the `serde` feature.
- **Pathfinding**: Find the shortest path between two hexagonal positions using the A* algorithm.
- **Field of view**: Calculate the field of view of a hexagonal grid.
- **Field of movements**: Calculate the movement field of a hexagonal grid.
- **Noise generation**: Generate noise maps for hexagonal grids using the `noise` crate.
**The Serde feature documentation is located in the [docs/serde.md](https://github.com/CoCoSol007/hexing/blob/main/docs/serde.md) file. And documentation for the pathfinding, field of view, field of movement and noise generation features are located in the [docs/layout.md](https://github.com/CoCoSol007/hexing/blob/main/docs/layout.md) file.**
### Number Trait
The library uses the `Number` trait to allow generic calculations with various numeric types. This trait is implemented for several types, including integers and floating-point numbers.
### Main Types
#### `HexPosition`
Represents a position in a hexagonal grid with coordinates `T`. Coordinates are in axial format `(x, y)`.
- **Creation**:
Creates a new [HexPosition] with the given `q` and `r` coordinates in an axial format. Coordinates are explained in this [documentation](https://www.redblobgames.com/grids/hexagons/#coordinates).
```rust
let pos = HexPosition::new(1, 2);
let pos2 = HexPosition(3, 4);
// Constant: The origin of the hexagonal grid.
let origin = HexPosition::ORIGIN;
```
- **Conversion to Pixel Coordinates**:
Converts the current [HexPosition] into a pixel coordinate. Basically, it converts a position in a hexagonal grid to a position in a orthogonal grid.
```rust
let pixel_coords = pos.to_pixel_coordinates();
let pixel_coords2 = HexPosition::from_pixel_coordinates(pixel_coords);
```
- **Distance Calculation**:
Calculates the distance between two hexagonal positions, using the [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry).
```rust
let distance = pos.distance(HexPosition::new(3, 4));
```
- **Rotation**:
Will apply a rotation of 2 x 60 degrees around the origin.
```rust
let rotated_pos = pos.rotation(2);
```
- **Reflection**:
Will apply a central symmetric reflection around the origin.
```rust
let reflected_pos = pos.reflect();
```
- **Ring Iterators**:
A iterator that returns positions in a ring around a central position. The iterator will return positions in a ring with the given radius.
```rust
for ring_pos in pos.ring(2) {
println!("{:?}", ring_pos);
}
```
- **Spiral Iterators**:
A iterator that returns positions in a spiral around a central position. The iterator will return positions in a spiral with the given radius.
```rust
for spiral_pos in pos.spiral(2) {
println!("{:?}", spiral_pos);
}
```
- **Line Iterators**
A iterator that returns positions along a line between two hexagonal positions.
```rust
let a = HexPosition(0, 0);
let b = HexPosition(-2, -1);
for line_pos in a.line(b) {
println!("{:?}", line_pos);
}
```
- **Bounding**:
A utility function that calculates the bounding box of a hexagonal grid.
```rust
use hexing::{utils::HexBound, HexPosition};
let center = HexPosition(0, 0);
let radius = 3;
let bounding_box = HexBound::new(center, radius);
assert!(bounding_box.contains(HexPosition(0, 0)));
assert_eq!(bounding_box.radius(), 3);
assert_eq!(bounding_box.center(), HexPosition(0, 0));
```
#### `HexDirection`
Enum representing the six possible directions in a hexagonal grid.
- **Available Directions**:
- `Right` (1, 0)
- `UpRight` (1, -1)
- `UpLeft` (0, -1)
- `Left` (-1, 0)
- `DownLeft` (-1, 1)
- `DownRight` (0, 1)
- **Convert to Vector**:
You can convert a [HexDirection] to a [HexPosition] by using the `to_vector` method.
```rust
let direction = HexDirection::Right;
let vector = direction.to_vector();
```
## Usage Examples
Here are some examples to illustrate the features of `hexing`.
### Creating Hexagonal Positions
```rust
use hexing::HexPosition;
let pos = HexPosition::new(1, 2);
let pos2 = HexPosition(3, 4);
let origin = HexPosition::ORIGIN;
println!("Position 1: {:?}", pos);
println!("Position 2: {:?}", pos2);
println!("Origin: {:?}", origin);
```
### Conversion to Pixel Coordinates
```rust
use hexing::HexPosition;
let position = HexPosition::new(1, 0);
let pixel_coords = position.to_pixel_coordinates();
println!("Pixel coordinates: {:?}", pixel_coords);
let new_position: HexPosition = HexPosition::from_pixel_coordinates(pixel_coords);
println!("New position: {:?}", new_position);
assert!(position == new_position);
```
### Calculating Distance Between Positions
```rust
use hexing::HexPosition;
let pos1 = HexPosition::new(0, 0);
let pos2 = HexPosition::new(-2, -1);
let dist = pos1.distance(pos2);
println!("Distance: {:?}", dist);
```
### Iterating Over Rings and Spirals
```rust
use hexing::{HexPosition, HexRing, HexSpiral};
let center = HexPosition::new(0, 0);
// Ring of radius 1
let ring = center.ring(1);
for pos in ring {
println!("Ring position: {:?}", pos);
}
// Spiral of radius 2
let spiral = center.spiral(2);
for pos in spiral {
println!("Spiral position: {:?}", pos);
}
```
### Rotation of Hexagonal Position
```rust
use hexing::HexPosition;
let rotation = 120;
let pos = HexPosition::new(1, 2);
let rotated_pos = pos.rotation(rotation/60); // Rotates 120 degrees
println!("Rotated Position: {:?}", rotated_pos);
```
### Reflection of Hexagonal Position
```rust
use hexing::HexPosition;
let pos = HexPosition::new(1, 2);
let reflected_pos = pos.reflect();
println!("Reflected Position: {:?}", reflected_pos);
```
### Line Iterator
```rust
use hexing::HexPosition;
let start = HexPosition::new(0, 0);
let end = HexPosition::new(3, -3);
for pos in start.line(end) {
println!("Line Position: {:?}", pos);
}
```
### Using HexDirection
```rust
use hexing::HexDirection;
let direction = HexDirection::UpRight;
let vector = direction.to_vector();
println!("Vector for Right Direction: {:?}", vector);
let new_position = HexPosition::new(0, 0) + vector * 3;
println!("New Position after moving Right: {:?}", new_position);
```
### Full Documentation
For more detailed documentation and additional explanations about hexagonal grids, please refer to the [Red Blob Games hexagonal grid documentation](https://www.redblobgames.com/grids/hexagons/).
### Installation
Add `hexing` to your `Cargo.toml`:
```toml
[dependencies]
hexing = "0.3.3"
```
[contributors-shield]: https://img.shields.io/github/contributors/cocosol007/hexing.svg?style=for-the-badge
[contributors-url]: https://github.com/cocosol007/hexing/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/cocosol007/hexing.svg?style=for-the-badge
[forks-url]: https://github.com/cocosol007/hexing/network/members
[stars-shield]: https://img.shields.io/github/stars/cocosol007/hexing.svg?style=for-the-badge
[stars-url]: https://github.com/cocosol007/hexing/stargazers
[issues-shield]: https://img.shields.io/github/issues/cocosol007/hexing.svg?style=for-the-badge
[issues-url]: https://github.com/cocosol007/hexing/issues
[license-shield]: https://img.shields.io/github/license/cocosol007/hexing.svg?style=for-the-badge
[license-url]: https://github.com/cocosol007/hexing/blob/main/LICENSE