pub fn cross_sign(ax: i64, ay: i64, bx: i64, by: i64, cx: i64, cy: i64) -> i128 {
let dx1 = (bx as i128) - (ax as i128);
let dy1 = (by as i128) - (ay as i128);
let dx2 = (cx as i128) - (ax as i128);
let dy2 = (cy as i128) - (ay as i128);
dx1 * dy2 - dy1 * dx2
}
pub fn sub_u64(a: u64, b: u64) -> i128 {
(a as i128) - (b as i128)
}
pub fn sign(v: i128) -> i32 {
v.cmp(&0) as i32
}
pub fn is_left_turn(cross: i128) -> bool {
cross > 0
}
pub fn is_right_turn(cross: i128) -> bool {
cross < 0
}
pub fn is_collinear(cross: i128) -> bool {
cross == 0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cross_sign_left_turn_is_positive() {
let result = cross_sign(0, 0, 2_000_000, 0, 2_000_000, 2_000_000);
assert!(result > 0, "left turn should be positive, got {result}");
}
#[test]
fn cross_sign_right_turn_is_negative() {
let result = cross_sign(0, 0, 2_000_000, 2_000_000, 4_000_000, 0);
assert!(result < 0, "right turn should be negative, got {result}");
}
#[test]
fn cross_sign_collinear_is_zero() {
let result = cross_sign(0, 0, 1_000_000, 0, 2_000_000, 0);
assert_eq!(result, 0, "collinear should be zero");
}
#[test]
fn cross_sign_matches_move_test_vectors() {
let zero = cross_sign(0, 2, 1, 1, 2, 0);
assert_eq!(zero, 0);
let left = cross_sign(0, 0, 2, 0, 2, 2);
assert_eq!(left, 4);
let right = cross_sign(0, 0, 2, 2, 4, 0);
assert!(right < 0);
}
#[test]
fn cross_sign_no_overflow_with_max_world_coordinates() {
const MAX_WORLD: i64 = 40_075_017_000_000;
let result = cross_sign(0, 0, MAX_WORLD, 0, 0, MAX_WORLD);
let expected = (MAX_WORLD as i128) * (MAX_WORLD as i128);
assert_eq!(result, expected);
}
#[test]
fn cross_sign_large_negative_no_overflow() {
const MAX_WORLD: i64 = 40_075_017_000_000;
let result = cross_sign(0, MAX_WORLD, MAX_WORLD, 0, 0, 0);
assert!(result < 0);
}
#[test]
fn sub_u64_positive_and_negative() {
assert_eq!(sub_u64(10, 5), 5_i128);
assert_eq!(sub_u64(5, 10), -5_i128);
assert_eq!(sub_u64(7, 7), 0_i128);
}
#[test]
fn sign_returns_correct_values() {
assert_eq!(sign(42), 1);
assert_eq!(sign(-42), -1);
assert_eq!(sign(0), 0);
}
}