1#ifndef PHYSICSCONSTRAINTS_HPP
2#define PHYSICSCONSTRAINTS_HPP
46 if (
n.
x() * c.
x() +
n.
y() * c.
y() +
n.
z() * c.
z() + (-
n.
x() *
p.
x() -
n.
y() *
p.
y() -
n.
z() *
p.
z()) < 0)
119 void addSymAxis(std::function<
double(
double,
MecaCell::Vec,
MecaCell::Vec)> _radiusFunction,
MecaCell::Vec _axis =
MecaCell::Vec(0., 1., 0.),
MecaCell::Vec _origin =
MecaCell::Vec(0., 0., 0.),
double _length = 100,
double _maxEffectRadius = 100,
bool _fitShape =
true,
double _velocity_attraction = 0.001) {
120 symAxes.push_back(
SymAxis(_axis, _origin, _length, _maxEffectRadius, _fitShape, _velocity_attraction, _radiusFunction));
139 template<
typename cell_t>
143 double distOnAxis = symAxis.axis.normalized().dot((c->getBody().getPosition() - symAxis.origin));
145 if (distOnAxis > 0 && distOnAxis < symAxis.length) {
147 MecaCell::Vec dir = (c->getBody().getPosition() - (symAxis.axis.normalized() * distOnAxis + symAxis.origin));
148 double sqDistToAxis = dir.
sqlength();
151 if (sqDistToAxis < symAxis.maxEffectRadius * symAxis.maxEffectRadius) {
152 double targetRadius = symAxis.radiusFunction(distOnAxis / symAxis.length, symAxis.origin, symAxis.axis.normalized() * symAxis.length);
153 double sqDistToRadius = targetRadius * targetRadius - sqDistToAxis;
154 if ((sqDistToRadius > 0 && symAxis.fitShape) || sqDistToRadius < 0) {
156 ret = dir * (sqDistToRadius > 0 ? 1 : -1) * symAxis.attraction_velocity;
171 template<
typename cell_t>
174 double distToCenter = c->getBody().getPosition().
length();
193 void setCurvedBox(
double radiusBoxPlane,
double curvedDistToMaxSpeed,
double maxSpeed) {
214 template<
typename cell_t>
216 double dist, delta, R, E, Frep, adhesion, Fadh;
217 for (
auto plane :
planes) {
219 dist =
std::abs(plane.distanceToPoint(c->getBody().getPosition()));
221 delta = c->getBody().getBoundingBoxRadius() - dist;
222 R = 1.0 / (1.0 / c->getBody().getBoundingBoxRadius() + 1.0 / c->getBody().getBoundingBoxRadius());
224 ((1.0 - c->getBody().getPoissonNumber() * c->getBody().getPoissonNumber()) / c->getBody().getYoungModulus() +
227 Frep = 4.0 / 3.0 * E *
sqrt(R) *
pow(delta, 3.0 / 2.0);
228 adhesion = (4.0 *
sqrt(
overlapAdhesion * c->getBody().getBoundingBoxRadius()) * E *
sqrt(R)) / (3.0 * M_PI * M_PI * R * R);
229 Fadh = -M_PI * M_PI * R * R * adhesion * delta;
231 c->getBody().receiveForce(plane.n * (Frep + Fadh));
243 template<
typename cell_t>
246 for (
auto plane :
planes) {
247 dist = plane.distanceToPoint(c->getBody().getPosition()) - (c->getBody().getBoundingBoxRadius() - c->getBody().getBoundingBoxRadius() *
overlapAdhesion);
248 if (dist < 0) c->getBody().setPosition(c->getBody().getPosition() - plane.n * dist);
double getBoundingBoxRadius() const
general purpose 3D vector/point class.
static Vector3D getProjectionOnPlane(const Vector3D &o, const Vector3D &n, const Vector3D &p)
project a point on a plane
double length() const
compute the length of the vector
double sqlength() const
compute the square length of the current vector (faster than length)
static Vector3D zero()
constructs a zero vector
void normalize()
normalizes the vector
Vector3D normalized() const
returns a normalized copy of the current vector
Represents a plane constraint.
double distanceToPoint(MecaCell::Vec c)
Computes the distance from a point to the plane.
Plane(MecaCell::Vec _n=MecaCell::Vec(0, 1, 0), MecaCell::Vec _p=MecaCell::Vec(0, 0, 0), bool _sticky=false)
Constructor for Plane.
Represents a symmetrical axis constraint.
double attraction_velocity
std::function< double(double, MecaCell::Vec, MecaCell::Vec)> radiusFunction
SymAxis(MecaCell::Vec a, MecaCell::Vec o, double l, double mef, bool fs, double av, std::function< double(double, MecaCell::Vec, MecaCell::Vec)> rf)
Constructor for SymAxis.
Class for managing physical constraints in a simulation.
PhysicsConstraints()
Default constructor.
std::vector< Plane > planes
void setPoissonAndYoungOfPlane(double poisson, double young)
Sets the Poisson's ratio and Young's modulus for the plane.
std::vector< MecaCell::Vec > velocities
void addPlane(MecaCell::Vec _n=MecaCell::Vec(0, 1, 0), MecaCell::Vec _p=MecaCell::Vec(0, 0, 0), bool _sticky=false)
Adds a plane constraint.
void applyPlaneConstraints(cell_t *c)
Applies plane constraints to a cell.
MecaCell::Vec getSymAxesConstraintsVelocity(cell_t *c)
Computes the symmetrical axis constraints velocity for a cell.
std::vector< SymAxis > symAxes
MecaCell::Vec getConstraintVelocity(cell_t *c)
Computes the constraint velocity for a cell.
void snapCellsToPlane(cell_t *c)
Snaps cells to the plane.
void addSymAxis(std::function< double(double, MecaCell::Vec, MecaCell::Vec)> _radiusFunction, MecaCell::Vec _axis=MecaCell::Vec(0., 1., 0.), MecaCell::Vec _origin=MecaCell::Vec(0., 0., 0.), double _length=100, double _maxEffectRadius=100, bool _fitShape=true, double _velocity_attraction=0.001)
Adds a symmetrical axis constraint.
double ratioPoisson2OnYoung
double velocity_center_attraction
void addVelocity(MecaCell::Vec _v=MecaCell::Vec(0, 1, 0))
Adds a velocity constraint.
void setCurvedBox(double radiusBoxPlane, double curvedDistToMaxSpeed, double maxSpeed)
Sets the curved box parameters.
A simple vector class template.
int abs(int x)
Computes the absolute value of an integer.
double sqrt(double x)
Computes the square root of a number.
double pow(double base, double exponent)
Computes the power of a number.