use crate::Point;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Line {
pub slope: f64,
pub intercept: f64,
}
impl Line {
#[inline]
#[must_use]
pub fn from_slope_intercept(slope: f64, intercept: f64) -> Self {
Self { slope, intercept }
}
#[inline]
#[must_use]
pub fn from_slope_point(slope: f64, point: Point) -> Self {
Self {
slope,
intercept: point.y - slope * point.x,
}
}
#[inline]
#[must_use]
pub fn from_points(point1: Point, point2: Point) -> Self {
let slope = (point2.y - point1.y) / (point2.x - point1.x);
Self {
slope,
intercept: point1.y - slope * point1.x,
}
}
}
impl Line {
#[inline]
#[must_use]
pub fn eval(&self, x: f64) -> f64 {
self.slope * x + self.intercept
}
}
#[cfg(test)]
mod test_line {
use super::*;
use approx::assert_relative_eq;
const EPS: f64 = 1e-30;
#[test]
fn from_slope_intercept() {
let line = Line::from_slope_intercept(2.0, 1.0);
assert_eq!(line.slope, 2.0);
assert_eq!(line.intercept, 1.0);
assert_relative_eq!(line.eval(0.5), 2.0, epsilon = EPS);
}
#[test]
fn from_slope_point() {
let point = Point { x: 1.0, y: 3.0 };
let line = Line::from_slope_point(2.0, point);
assert_eq!(line.slope, 2.0);
assert_eq!(line.intercept, 1.0);
assert_relative_eq!(line.eval(0.5), 2.0, epsilon = EPS);
}
#[test]
fn from_points() {
let point1 = Point { x: 0.0, y: 1.0 };
let point2 = Point { x: 1.0, y: 3.0 };
let line = Line::from_points(point1, point2);
assert_eq!(line.slope, 2.0);
assert_eq!(line.intercept, 1.0);
assert_relative_eq!(line.eval(0.5), 2.0, epsilon = EPS);
}
}