/** * Implementation of a spheroid **/ #include "spheroid.hpp" Spheroid::Spheroid(const Point& _center, double _min_p, double _p, double _q) : ImplicitSurface(_center), normal_vector(Point(0,0,1)), min_p(_min_p), init_p(_p), p(_p), q(_q), stiffness(0) { _compute_volume(); } void Spheroid::_compute_volume() { V = (4/3) * PI * p * q * q; } void Spheroid::update_radius() { q = sqrt((3/4) * V / PI / p); } void Spheroid::update_height() { q = (3/4) * V / PI / (p*p); } void Spheroid::update_center_pos(Point& _center) { center = _center; } void Spheroid::check_horizontal_plan_collision(double& height) { if ((center.y - p) <= height) { p = fmin(init_p, center.y-height); update_radius(); } } void Spheroid::check_vertical_plan_collision(double& abscissa) { if (center.x <= abscissa) { if ((center.x + q) >= abscissa) { q = abscissa - center.x; update_height(); } } else { if ((center.x - q) <= abscissa) { q = center.x - abscissa; update_height(); } } } Cuboid Spheroid::max_bounding_box() const { double max_radius = sqrt((3./4.) * V / PI / min_p); double max_height = init_p; Point _bd1(max_radius, max_radius, max_height); Point _bd2(-max_radius, -max_radius, -max_height); return Cuboid(_bd1, _bd2); } void Spheroid::check_perlin_collision(PerlinNoise perlin) { double height = perlin.noise(center.x, center.z); if ((center.y - p) <= height) { p = fmin(init_p, center.z- height ); normal_vector = perlin.normal_vector(center.x, center.z); update_radius(); } } double Spheroid::operator() (double _x, double _y, double _z) const { return (pow(_x, 2) / pow(q, 2) + pow(_y, 2) / pow(q, 2) + pow(_z, 2) / pow(p, 2) -1); }