#![warn(missing_docs)]
use nannou::color::Alpha;
use nannou::prelude::*;
#[derive(Clone, Debug)]
pub struct Line {
pub start: Vec2,
pub end: Vec2,
pub weight: f32,
pub color: Alpha<Hsl, f32>,
}
impl Line {
pub fn new(start: Vec2, end: Vec2, weight: f32, color: Alpha<Hsl, f32>) -> Self {
Self { start, end, weight, color }
}
pub fn draw(&self, draw: &Draw) {
draw.line()
.start(self.start)
.end(self.end)
.weight(self.weight)
.color(self.color);
}
pub fn collides_with_line(&self, other: &Line) -> bool {
if collision_line_line(self.start.x, self.start.y, self.end.x, self.end.y, other.start.x, other.start.y, other.end.x, other.end.y) {
return true;
}
let radius = self.weight + 2.0;
let length = other.start.distance(other.end);
let dot_product = (((self.end.x - other.start.x) * (other.end.x - other.start.x)) + ((self.end.y - other.start.y) * (other.end.y - other.start.y))) / (length * length);
let closest_point = vec2(other.start.x + (dot_product * (other.end.x - other.start.x)), other.start.y + (dot_product * (other.end.y - other.start.y)));
if !collision_line_point(other, closest_point) {
return false;
}
let distance_to_closest_point = self.end.distance(closest_point);
if distance_to_closest_point <= radius {
return true;
}
false
}
}
fn collision_line_line(x1: f32, y1: f32, x2: f32, y2: f32, x3: f32, y3: f32, x4: f32, y4: f32) -> bool {
let a = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
let b = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
a >= 0. && a <= 1. && b >= 0. && b <= 1.
}
fn collision_line_point(line: &Line, p: Vec2) -> bool {
let d1 = p.distance(line.start);
let d2 = p.distance(line.end);
let line_length = line.start.distance(line.end);
let buffer = 0.1;
if d1 + d2 >= line_length - buffer && d1 + d2 <= line_length + buffer {
return true;
}
false
}