lather 0.0.0

A Rust crate and Python extension for modeling starspot effects on radial velocity and photometric observations, inspired by complaints about the SOAP project of similar goals.
extern crate std;

#[derive(PartialEq)]
#[derive(Debug)]
pub struct Point {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

#[allow(dead_code)]
impl Point {
    pub fn rotated_x(&self, angle: f64) -> Point {
        Point {
            x: self.x,
            y: self.y * angle.sin() - self.z * angle.sin(),
            z: self.y * angle.sin() + self.z * angle.cos(),
        }
    }

    pub fn rotated_y(&self, angle: f64) -> Point {
        Point {
            x: self.z * angle.sin() + self.x * angle.cos(),
            y: self.y,
            z: self.z * angle.cos() - self.x * angle.sin(),
        }
    }

    pub fn rotated_z(&self, angle: f64) -> Point {
        Point {
            x: self.x * angle.cos() - self.y * angle.sin(),
            y: self.x * angle.sin() + self.y * angle.cos(),
            z: self.z,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::f64::consts;

    fn is_close(actual: f64, expected: f64) -> bool {
        let precision = 15;
        let pow = 10.0f64.powi(precision + 1);
        let delta = (expected - actual).abs();
        let max_delta = 10.0f64.powi(-precision) / 2.0;
        return (delta * pow).round() / pow <= max_delta;
    }

    #[test]
    fn x_rotation() {
        let point = Point {
            x: 1.0,
            y: 1.0,
            z: 1.0,
        }.rotated_x(consts::FRAC_PI_4);
        assert_eq!(point.x, 1.0);
        assert!(is_close(point.y, 0.0));
        assert!(is_close(point.z, consts::SQRT_2));
    }

    #[test]
    fn y_rotation() {
        let point = Point {
            x: 1.0,
            y: 1.0,
            z: 1.0,
        }.rotated_y(consts::FRAC_PI_4);
        assert!(is_close(point.x, consts::SQRT_2));
        assert_eq!(point.y, 1.0);
        assert!(is_close(point.z, 0.0));

    }

    #[test]
    fn z_rotation() {
        let point = Point {
            x: 1.0,
            y: 1.0,
            z: 1.0,
        }.rotated_z(consts::FRAC_PI_4);
        assert!(is_close(point.x, 0.0));
        assert!(is_close(point.y, consts::SQRT_2));
        assert_eq!(point.z, 1.0);
    }
}