use std::fmt;
use prelude::*;
use distances_3d::dist_3d;
use functions::center_3d;
#[derive (Debug, PartialEq, PartialOrd, Eq, Clone, Hash)]
pub struct LineSegment3D {
pub start: Point3D,
pub end: Point3D
}
impl LineSegment3D {
pub fn new(start: Point3D, end: Point3D) -> Self {
LineSegment3D{start, end}
}
}
impl IsMovable3D for LineSegment3D {
fn move_by(&mut self, x: f64, y: f64, z: f64) {
self.start.move_by(x, y, z);
self.end.move_by(x, y, z);
}
}
impl HasLength for LineSegment3D {
fn length(&self) -> f64 {
dist_3d(&self.start, &self.end)
}
}
impl HasBoundingBox3D for LineSegment3D {
fn bounding_box(&self) -> Result<BoundingBox3D> {
let mut pts = Vec::new();
pts.push(Box::new(self.start.clone()));
pts.push(Box::new(self.end.clone()));
BoundingBox3D::from_iterator(pts.iter())
}
}
impl HasCenterOfGravity3D for LineSegment3D {
fn center_of_gravity(&self) -> Result<Point3D> {
Ok(center_3d(&self.start, &self.end))
}
}
impl IsScalable for LineSegment3D {
fn scale(&mut self, factor: Positive) {
let c = self.center_of_gravity().unwrap();
self.start.increase_distance_to_by(&c, factor);
self.end.increase_distance_to_by(&c, factor);
}
}
impl fmt::Display for LineSegment3D {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {}, {} -> {}, {}, {})", self.start.x(), self.start.y(), self.start.z(), self.end.x(), self.end.y(), self.end.z())
}
}