9 #ifndef EMP_PHYSICS_2D_H 10 #define EMP_PHYSICS_2D_H 12 #include <unordered_set> 34 Physics2D(
double width,
double height,
double max_org_diameter=20,
bool detach=
true)
35 : surface(width, height)
36 , background(width, height)
37 , detach_on_birth(detach)
46 detach_on_birth = _in;
49 for (
auto cur_body : body_set) { cur_body->SetDetachOnDivide(_in); }
60 if (body_set.size() == 0)
return *
this;
64 for (
size_t i = 1; i < body_set.size(); i++) {
65 if (body_set[i]->GetBirthTime() < body_set[oldest_id]->GetBirthTime()) {
71 body_set[oldest_id].Delete();
72 body_set[oldest_id] = body_set.back();
73 body_set.resize(body_set.size() - 1);
79 if (body1.IsLinked(body2))
return false;
81 const Point dist = body1.GetCenter() - body2.GetCenter();
83 const double radius_sum = body1.GetRadius() + body2.GetRadius();
84 const double sq_min_dist = radius_sum * radius_sum;
87 if (sq_pair_dist >= sq_min_dist) {
return false; }
89 if (sq_pair_dist == 0.0) {
91 body2.Translate(
Point(0.01, 0.01));
97 const double true_dist = sqrt(sq_pair_dist);
98 const double overlap_dist = ((double) radius_sum) - true_dist;
99 const double overlap_frac = overlap_dist / true_dist;
100 const Point cur_shift = dist * (overlap_frac / 2.0);
101 body1.AddShift(cur_shift);
102 body2.AddShift(-cur_shift);
108 double x1, y1, x2, y2;
110 if (dist.
GetX() == 0) {
111 x1 = body1.GetVelocity().GetX(); y1 = body2.GetVelocity().GetY();
112 x2 = body2.GetVelocity().GetX(); y2 = body1.GetVelocity().GetY();
114 body1.SetVelocity(
Point(x1, y1));
115 body2.SetVelocity(
Point(x2, y2));
117 else if (dist.
GetY() == 0) {
118 x1 = body2.GetVelocity().GetX(); y1 = body1.GetVelocity().GetY();
119 x2 = body1.GetVelocity().GetX(); y2 = body2.GetVelocity().GetY();
121 body1.SetVelocity(
Point(x1, y1));
122 body2.SetVelocity(
Point(x2, y2));
125 const Point rel_velocity(body2.GetVelocity() - body1.GetVelocity());
126 double normal_a = dist.
GetY() / dist.
GetX();
127 x1 = ( rel_velocity.GetX() + normal_a * rel_velocity.GetY() )
128 / ( normal_a * normal_a + 1 );
130 x2 = rel_velocity.GetX() - x1;
131 y2 = - (1 / normal_a) * x2;
133 body2.SetVelocity(body1.GetVelocity() +
Point(x2, y2));
134 body1.SetVelocity(body1.GetVelocity() +
Point(x1, y1));
146 for (
auto cur_body : body_set) {
147 cur_body->BodyUpdate(0.25);
148 cur_body->ProcessStep(0.0125);
153 [
this](BODY_TYPE & b1, BODY_TYPE & b2){
return this->TestPairCollision(b1,b2); };
158 while (cur_id < body_set.size()) {
160 const double cur_pressure = body_set[cur_id]->GetPressure();
163 if (cur_pressure > 3.0) {
164 body_set[cur_id].Delete();
165 if (cur_id < body_set.size() - 1) {
166 body_set[cur_id] = body_set.back();
emp::vector< Ptr< BODY_TYPE > > & GetBodySet()
Definition: Surface2D.h:52
Physics2D & Clear()
Definition: Physics2D.h:56
constexpr TYPE GetX() const
Definition: Point2D.h:39
Definition: Physics2D.h:24
const emp::vector< Ptr< BODY_TYPE > > & GetConstBackgroundSet() const
Definition: Physics2D.h:186
constexpr double SquareMagnitude() const
Definition: Point2D.h:45
bool GetDetach() const
Definition: Physics2D.h:43
Surface2D & Clear()
Definition: Surface2D.h:62
const emp::vector< Ptr< BODY_TYPE > > & GetConstBodySet() const
Definition: Surface2D.h:53
Definition: Surface2D.h:38
Surface2D & AddBody(Ptr< BODY_TYPE > new_body)
Definition: Surface2D.h:56
Point2D<> Point
Definition: Point2D.h:99
const emp::vector< Ptr< BODY_TYPE > > & GetConstBodySet() const
Definition: Physics2D.h:183
void TestCollisions(std::function< bool(BODY_TYPE &, BODY_TYPE &)> collide_fun)
Definition: Surface2D.h:71
Physics2D & AddBody(Ptr< BODY_TYPE > in_body)
Definition: Physics2D.h:53
Physics2D & KillOldest()
Definition: Physics2D.h:58
Physics2D & SetDetach(bool _in)
Definition: Physics2D.h:45
A wrapper for pointers that does careful memory tracking (but only in debug mode).
emp::vector< Ptr< BODY_TYPE > > & GetBodySet()
Definition: Physics2D.h:175
~Physics2D()
Definition: Physics2D.h:39
bool TestPairCollision(BODY_TYPE &body1, BODY_TYPE &body2)
Definition: Physics2D.h:78
Physics2D & AddBackground(Ptr< BODY_TYPE > in_body)
Definition: Physics2D.h:54
const Surface_t & GetSurface() const
Definition: Physics2D.h:41
const Surface_t & GetBackground() const
Definition: Physics2D.h:42
emp::vector< Ptr< BODY_TYPE > > & GetBackgroundSet()
Definition: Physics2D.h:178
A drop-in wrapper for std::vector; adds on bounds checking in debug mode.
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Build a debug wrapper emp::vector around std::vector.
Definition: vector.h:42
void Update()
Definition: Physics2D.h:141
#define emp_assert(...)
Definition: assert.h:199
Physics2D(double width, double height, double max_org_diameter=20, bool detach=true)
Definition: Physics2D.h:34
constexpr TYPE GetY() const
Definition: Point2D.h:40