ManevilleF / hexx

Hexagonal tools lib in rust
Apache License 2.0
288 stars 23 forks source link

Add Direction::from_angle #84

Closed alice-i-cecile closed 1 year ago

alice-i-cecile commented 1 year ago

Is your feature request related to a problem? Please describe.

I want to convert from an angle in radians to the nearest Direction.

Describe the solution you'd like

Direction::from_angle(radians: f32, orientation: HexOrientation) -> Direction

alice-i-cecile commented 1 year ago

Terrible workaround code for those who need it.

pub(crate) fn direction_from_angle(radians: f32, orientation: HexOrientation) -> Direction {
    let direction_angle_pairs = Direction::ALL_DIRECTIONS.map(|direction| {
        let angle = direction.angle(&orientation);
        (direction, angle)
    });

    let mut current_best_direction = Direction::Top;
    let mut current_best_delta = f32::MAX;

    let mut lowest_direction = Direction::Top;
    let mut lowest_angle = f32::MAX;

    let mut highest_direction = Direction::Top;
    let mut highest_angle = 0.;

    for (direction, angle) in direction_angle_pairs {
        if angle > highest_angle {
            highest_direction = direction;
            highest_angle = angle;
        }

        if angle < lowest_angle {
            lowest_direction = direction;
            lowest_angle = angle;
        }

        let delta = (angle - radians).abs();
        if delta < current_best_delta {
            current_best_direction = direction;
            current_best_delta = delta;
        }
    }

    // Handle the case where the angle is between the highest and lowest angles
    if radians > highest_angle {
        // If we are closer to the lowest angle, use that
        // TAU / 12 is half the angle between each pair of directions
        if radians - highest_angle > TAU / 12. {
            lowest_direction
        } else {
            highest_direction
        }
    } else {
        current_best_direction
    }
}