bestagon 0.9.0

An engine for discrete stuff in hexagonal grids
Documentation
use crate::{Edge, EdgeAx, HexAx, NodeAx};

pub trait Edges<TEdge>
where
  TEdge: Edge,
{
  fn edges(&self) -> impl Iterator<Item = TEdge>;
}

impl Edges<EdgeAx> for HexAx {
  fn edges(&self) -> impl Iterator<Item = EdgeAx> {
    [
      EdgeAx::new(self.q * 2, self.r * 2 - 1),
      EdgeAx::new(self.q * 2 + 1, self.r * 2 - 1),
      EdgeAx::new(self.q * 2 + 1, self.r * 2),
      EdgeAx::new(self.q * 2, self.r * 2 + 1),
      EdgeAx::new(self.q * 2 - 1, self.r * 2 + 1),
      EdgeAx::new(self.q * 2 - 1, self.r * 2),
    ]
    .into_iter()
  }
}

impl Edges<EdgeAx> for EdgeAx {
  fn edges(&self) -> impl Iterator<Item = EdgeAx> {
    if self.q % 2 == 0 {
      [
        EdgeAx::new(self.q - 1, self.r),
        EdgeAx::new(self.q - 1, self.r + 1),
        EdgeAx::new(self.q + 1, self.r - 1),
        EdgeAx::new(self.q + 1, self.r),
      ]
    } else {
      if self.r % 2 == 0 {
        [
          EdgeAx::new(self.q - 1, self.r + 1),
          EdgeAx::new(self.q, self.r + 1),
          EdgeAx::new(self.q, self.r - 1),
          EdgeAx::new(self.q + 1, self.r - 1),
        ]
      } else {
        [
          EdgeAx::new(self.q - 1, self.r),
          EdgeAx::new(self.q, self.r - 1),
          EdgeAx::new(self.q, self.r + 1),
          EdgeAx::new(self.q + 1, self.r),
        ]
      }
    }
    .into_iter()
  }
}

impl Edges<EdgeAx> for NodeAx {
  fn edges(&self) -> impl Iterator<Item = EdgeAx> {
    match self.q.rem_euclid(3) {
      1 => {
        // Right side of edge (flat orientation)
        assert_eq!(self.r.rem_euclid(3), 1);
        [
          // left
          EdgeAx::new((self.q * 2 - 2) / 3, (self.r * 2 + 1) / 3),
          // top-right
          EdgeAx::new((self.q * 2 + 1) / 3, (self.r * 2 + 1) / 3),
          // bottom-right
          EdgeAx::new((self.q * 2 + 1) / 3, (self.r * 2 - 2) / 3),
        ]
      }
      2 => {
        // Left side of edge (flat orientation)
        assert_eq!(self.r.rem_euclid(3), 2);
        [
          // top-left
          EdgeAx::new((self.q * 2 - 1) / 3, (self.r * 2 + 2) / 3),
          // bottom-left
          EdgeAx::new((self.q * 2 - 1) / 3, (self.r * 2 - 1) / 3),
          // right
          EdgeAx::new((self.q * 2 + 2) / 3, (self.r * 2 - 1) / 3),
        ]
      }
      _ => panic!(
        "Tried to evaluate hexes of an invalid node coordinate: {:?}",
        self
      ),
    }
    .into_iter()
  }
}

// fn edges<T>(&self) -> impl Iterator<Item = T>
// where
//   T: Edge,
// {
//   let self: NodeAx = (*self).into();
//   let mut result = Vec::new();
//   match self.q.rem_euclid(3) {
//     1 => {
//       // Right side of edge (flat orientation)
//       assert_eq!(self_ax.r.rem_euclid(3), 1);
//       // left
//       result.push(EdgeAx::new((self_ax.q * 2 - 2) / 3, (self_ax.r * 2 + 1) / 3).into());
//       // top-right
//       result.push(EdgeAx::new((self_ax.q * 2 + 1) / 3, (self_ax.r * 2 + 1) / 3).into());
//       // bottom-right
//       result.push(EdgeAx::new((self_ax.q * 2 + 1) / 3, (self_ax.r * 2 - 2) / 3).into());
//     }
//     2 => {
//       // Left side of edge (flat orientation)
//       assert_eq!(self_ax.r.rem_euclid(3), 2);
//       // top-left
//       result.push(EdgeAx::new((self_ax.q * 2 - 1) / 3, (self_ax.r * 2 + 2) / 3).into());
//       // bottom-left
//       result.push(EdgeAx::new((self_ax.q * 2 - 1) / 3, (self_ax.r * 2 - 1) / 3).into());
//       // right
//       result.push(EdgeAx::new((self_ax.q * 2 + 2) / 3, (self_ax.r * 2 - 1) / 3).into());
//     }
//     _ => panic!(
//       "Tried to evaluate hexes of an invalid node coordinate: {:?}",
//       self_ax
//     ),
//   }
//   result.into_iter()
// }