rust/landgen/src/outline.rs
author alfadur
Sun, 14 Oct 2018 21:25:59 +0300
changeset 13914 a44e4c057f57
parent 13913 9a1f1e8170f2
child 13926 939641cdb94f
permissions -rw-r--r--
use correct compiler flags

pub struct Point {
    x: i32,
    y: i32,
}

pub struct Outline {
    points: Vec<Point>,
}

fn check_intersect(v1: &Point, v2: &Point, v3: &Point, v4: &Point) -> bool {
    let dm: i32 = (v4.y - v3.y) * (v2.x - v1.x) - (v4.x - v3.x) * (v2.y - v1.y);

    if dm == 0 {
        return false;
    }

    let c1: i32 = (v4.x - v3.x) * (v1.y - v3.y) - (v4.y - v3.y) * (v1.x - v3.x);

    if dm > 0 {
        if (c1 < 0) || (c1 > dm) {
            return false;
        }
    } else {
        if (c1 > 0) || (c1 < dm) {
            return false;
        }
    }

    let c2: i32 = (v2.x - v3.x) * (v1.y - v3.y) - (v2.y - v3.y) * (v1.x - v3.x);

    if dm > 0 {
        if (c2 < 0) || (c2 > dm) {
            return false;
        }
    } else {
        if (c2 > 0) || (c2 < dm) {
            return false;
        }
    }

    true
}

impl Outline {
    fn check_intersects_self_at_index(&self, index: usize) -> bool {
        if index <= 0 || index > self.points.len() {
            return false;
        }

        for i in 1..=self.points.len() - 3 {
            if i <= index - 1 || i >= index + 2 {
                if i != index - 1 && check_intersect(
                    &self.points[index],
                    &self.points[index - 1],
                    &self.points[i],
                    &self.points[i - 1],
                ) {
                    return true;
                }
                if i != index + 2 && check_intersect(
                    &self.points[index],
                    &self.points[index + 1],
                    &self.points[i],
                    &self.points[i - 1],
                ) {
                    return true;
                }
            }
        }

        false
    }
}

#[cfg(test)]
#[test]
fn intersection() {
    let p1 = Point{x: 0, y: 0};
    let p2 = Point{x: 0, y: 10};
    let p3 = Point{x: -5, y: 5};
    let p4 = Point{x: 5, y: 5};
    let p5 = Point{x: 5, y: 16};

    assert!(check_intersect(&p1, &p2, &p3, &p4));
    assert!(!check_intersect(&p1, &p2, &p3, &p5));
}