CellModules
PluginSpheroidManager.hpp
Go to the documentation of this file.
1#ifndef PLUGINSPHEROIDMANAGER_HPP
2#define PLUGINSPHEROIDMANAGER_HPP
3
11#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
12#include <CGAL/point_generators_3.h>
13#include <CGAL/algorithm.h>
14#include <CGAL/Polyhedron_3.h>
15#include <CGAL/convex_hull_3.h>
16#include <CGAL/intersections.h>
17#include <vector>
18#include <mecacell/mecacell.h>
19#include <math.h>
20
21typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
22typedef CGAL::Polyhedron_3<K> Polyhedron_3;
23// define point creator
26
32{
33 Polyhedron_3::Plane_3 operator()(Polyhedron_3::Facet &f)
34 {
35 Polyhedron_3::Halfedge_handle h = f.halfedge();
36 return Polyhedron_3::Plane_3(h->vertex()->point(),
37 h->next()->vertex()->point(),
38 h->opposite()->vertex()->point());
39 }
40};
41
46namespace SpheroidManager {
47
54 template<typename cell_t>
57
58 private:
60 double optimRad = 0.0;
61 double meanRadius;
71 inline static double Kernel(const double x) { return exp(- pow(x, 2) / 2.) / sqrt(2. * M_PI); }
72
79 double r = 0;
80 Data data;
82 double max = - INFINITY;
83 for (auto &c : cells) {
84 r = (c->getBody().getPosition() - centroid).length();
85 c->getBody().setDistanceFromCentroid(r);
86 data.push_back(r);
87 points.push_back(Point_3(c->getBody().getPosition().x(), c->getBody().getPosition().y(), c->getBody().getPosition().z()));
88 if (r > max) {
89 max = r;
90 }
91 }
92 optimRad = getOptimalRadius(data, max);
93
94 // define polyhedron to hold convex hull
95 Polyhedron_3 poly;
96
97 // compute convex hull of non-collinear points
98 CGAL::convex_hull_3(points.begin(), points.end(), poly);
99
100 if (poly.size_of_vertices() > 5) {
101 std::transform(poly.facets_begin(), poly.facets_end(), poly.planes_begin(), PlaneFromFacet());
102 Point_3 pCentroid = Point_3(centroid.x(), centroid.y(), centroid.z());
103 for (auto &c : cells) {
104 Point_3 pCell = Point_3(c->getBody().getPosition().x(), c->getBody().getPosition().y(),
105 c->getBody().getPosition().z());
106 Line_3 lCellCentroid = Line_3(pCell, pCentroid);
107 Polyhedron_3::Plane_iterator pit;
108 double min = INFINITY;
109 for (pit = poly.planes_begin(); pit != poly.planes_end(); ++pit) {
110 auto result = CGAL::intersection((*pit), lCellCentroid);
111 if (result) {
112 const Point_3 *p = boost::get<Point_3>(&*result);
113 double dist = CGAL::squared_distance(pCell,(*p));
114 if (dist < min) {
115 min = dist;
116 }
117 }
118 }
119 c->getBody().setDistanceFromCentroid( c->getBody().getDistanceFromCentroid() * optimRad /
120 (c->getBody().getDistanceFromCentroid() + sqrt(min) ));
121 }
122 }
123 }
124
132 double getOptimalRadius(const Data &data, double max) {
133 double maxDensity = -1.;
134 double xMaxDensity = -1.;
135 double val;
136 double lambda = 10.;
137 double sum;
138 for (double i = 0.; i <= max; i += 0.2) {
139 sum = 0;
140 for (size_t j = 0; j < data.size(); ++j) {
141 sum += Kernel((i - data[j]) / lambda);
142 }
143 val = sum / lambda;
144 if (val > maxDensity) {
145 maxDensity = val;
146 xMaxDensity = i;
147 }
148 }
149 return (max - (max - xMaxDensity) / 2 + meanRadius);
150 }
151
159 centroid = MecaCell::Vec(0, 0, 0);
160 for (auto &c : cells) {
161 centroid += c->getBody().getPosition();
162 }
163 return centroid /= cells.size();
164 }
165
166 public:
170 inline PluginSpheroidManager() = default;
171
176 inline PluginSpheroidManager(double r) : meanRadius(r){}
177
182 inline MecaCell::Vec getCentroid() const{ return centroid; }
183
188 inline double getSpheroidRadius() const{ return (optimRad); }
189
194 inline void setMeanRadius(double r) { meanRadius = r; }
195
196
205 if (cells.size() > 5) {
206 computeCentroid(cells);
208 }
209 }
210
219 template<typename world_t>
220 void initSpheroid(world_t *w) {
221 updateSpheroid(w->newCells);
222 }
223
232 template<typename world_t>
233 void preBehaviorUpdate(world_t *w) {
234 updateSpheroid(w->cells);
235 }
236 };
237}
238#endif
K::Point_3 Point_3
CGAL::Exact_predicates_inexact_constructions_kernel K
K::Line_3 Line_3
CGAL::Polyhedron_3< K > Polyhedron_3
general purpose 3D vector/point class.
Definition: vector3D.h:20
double x() const
Definition: vector3D.h:94
double y() const
Definition: vector3D.h:100
double z() const
Definition: vector3D.h:106
Class for managing spheroid bodies.
void updateDistanceFromCentroid(std::vector< cell_t * > cells)
Updates the distance from centroid for each cell.
MecaCell::Vec computeCentroid(std::vector< cell_t * > cells)
Computes the centroid position.
void preBehaviorUpdate(world_t *w)
Pre-behavior update hook for MecaCell.
MecaCell::Vec getCentroid() const
Gets the centroid.
static double Kernel(const double x)
Gaussian probability density function.
double getOptimalRadius(const Data &data, double max)
Computes the optimal radius.
void setMeanRadius(double r)
Sets the mean radius.
double getSpheroidRadius() const
Gets the spheroid radius.
void updateSpheroid(std::vector< cell_t * > cells)
Computes everything for the spheroid.
void initSpheroid(world_t *w)
Init function to be called on scenario init.
PluginSpheroidManager(double r)
Constructor with mean radius.
PluginSpheroidManager()=default
Default constructor.
void push_back(const T &value)
Adds an element to the end of the vector.
Definition: std.hpp:304
iterator begin()
Returns an iterator to the first element.
Definition: std.hpp:409
iterator end()
Returns an iterator to the last element.
Definition: std.hpp:418
size_t size() const
Returns the number of elements in the vector.
Definition: std.hpp:320
Vector3D Vec
alias for Vector3D
Definition: utils.hpp:22
Namespace for spheroid manager-related classes and functions.
double sqrt(double x)
Computes the square root of a number.
Definition: std.hpp:32
double exp(double x)
Computes the exponential function of a number.
Definition: std.hpp:22
double pow(double base, double exponent)
Computes the power of a number.
Definition: std.hpp:43
Functor computing the plane containing a triangular facet.
Polyhedron_3::Plane_3 operator()(Polyhedron_3::Facet &f)