2018-02-07 15:07:59 +01:00
|
|
|
/**
|
|
|
|
* Implementation of a spheroid
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include "spheroid.hpp"
|
2018-02-13 01:02:58 +01:00
|
|
|
#include <iostream>
|
2018-02-07 15:07:59 +01:00
|
|
|
|
2018-02-12 18:45:35 +01:00
|
|
|
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();
|
|
|
|
}
|
2018-02-07 15:07:59 +01:00
|
|
|
|
|
|
|
void Spheroid::_compute_volume() {
|
2018-02-13 10:49:12 +01:00
|
|
|
V = (4./3.) * PI * p * q * q;
|
2018-02-07 15:07:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Spheroid::update_radius() {
|
2018-02-13 01:02:58 +01:00
|
|
|
q = sqrt((3./4.) * V / PI / p);
|
2018-02-07 15:07:59 +01:00
|
|
|
}
|
|
|
|
|
2018-02-11 17:29:56 +01:00
|
|
|
void Spheroid::update_height() {
|
2018-02-13 01:02:58 +01:00
|
|
|
q = (3./4.) * V / PI / (p*p);
|
2018-02-11 17:29:56 +01:00
|
|
|
}
|
|
|
|
|
2018-02-07 15:07:59 +01:00
|
|
|
|
|
|
|
void Spheroid::update_center_pos(Point& _center) {
|
|
|
|
center = _center;
|
|
|
|
}
|
2018-02-09 20:23:06 +01:00
|
|
|
|
2018-02-13 01:02:58 +01:00
|
|
|
void Spheroid::check_horizontal_plan_collision(double height) {
|
2018-02-13 10:49:12 +01:00
|
|
|
if (((center.y - p) <= height) || (p < init_p)) {
|
2018-02-12 18:18:28 +01:00
|
|
|
p = fmin(init_p, center.y-height);
|
2018-02-09 20:23:06 +01:00
|
|
|
update_radius();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-11 17:29:56 +01:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-02-12 14:31:08 +01:00
|
|
|
|
|
|
|
Cuboid Spheroid::max_bounding_box() const {
|
2018-02-12 21:53:35 +01:00
|
|
|
double max_radius = sqrt((3./4.) * V / PI / min_p);
|
2018-02-12 14:31:08 +01:00
|
|
|
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);
|
|
|
|
}
|
2018-02-12 18:32:58 +01:00
|
|
|
|
2018-02-12 17:40:50 +01:00
|
|
|
void Spheroid::check_perlin_collision(PerlinNoise perlin) {
|
2018-02-12 18:32:58 +01:00
|
|
|
double height = perlin.noise(center.x, center.z);
|
|
|
|
if ((center.y - p) <= height) {
|
2018-02-12 17:40:50 +01:00
|
|
|
p = fmin(init_p, center.z- height );
|
2018-02-12 18:32:58 +01:00
|
|
|
normal_vector = perlin.normal_vector(center.x, center.z);
|
2018-02-12 17:40:50 +01:00
|
|
|
update_radius();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-12 14:15:30 +01:00
|
|
|
|
|
|
|
double Spheroid::operator() (double _x, double _y, double _z) const {
|
2018-02-12 18:36:59 +01:00
|
|
|
return (pow(_x, 2) / pow(q, 2)
|
2018-02-13 01:02:58 +01:00
|
|
|
+ pow(_y, 2) / pow(p, 2)
|
|
|
|
+ pow(_z, 2) / pow(q, 2) -1);
|
2018-02-12 18:32:58 +01:00
|
|
|
}
|