Я хотел бы применить ограничение между двумя точками, применяя гравитацию.Следующее изображение, которое я нарисовал, демонстрирует начальную и конечную позиции точки 2, которая не включает промежуточные позиции временного шага, и предполагает, что точка 1 имеет фиксированную позицию:
У меня есть класс точек, определенный следующим образом:
class Point{
glm::vec3 position;
glm::vec3 op; // original position
glm::vec3 velocity;
float mass;
};
Я могу определить две точки и найти исходную длину между двумя точками, используя следующее:
Point p1;
p1.position = glm::vec3(0, 10, 0);
p1.op = p1.position;
p1.velocity = glm::vec3(0, 0, 0);
p1.mass = 1.0f;
Point p2;
p2.position = glm::vec3(10, 10, 0);
p2.op = p2.position;
p2.velocity = glm::vec3(0, 0, 0);
p2.mass = 1.0f;
float original_length_p1_p2 = glm::length(p2.op- p1.op);
У меня есть функция обновления внутри класса точек, которая запускается в течение определенного временного шага, который должен обновлять положение точки, применяя гравитацию:
glm::vec3 gravity(0,-9.8,0);
...
void update(float dt){
velocity += gravity * dt;
position += velocity * dt;
}
Точки хранятся внутри вектора иФункция обновления вызывается, как показано ниже:
std::vector<Point> myPoints;
...
for(int n = 0; n < myPoints.size(); n++){
myPoints[n].update(dt);
}
Теперь я хочу иметь возможность применить некоторые пружинные ограничения между этими двумя точками, которые качались бы как простой пружинный маятник.Я попытался добавить следующее в цикл for:
void applyConstraint(Point &p1, Point &p2, float dt){
float change = (glm::length(p1.position-p2.position) - glm::length(p1.op-p2.op)) / glm::length(p1.position-p2.position);
p1.position -= 0.5 * (p1.position-p2.position) * change * dt;
p2.position += 0.5 * (p1.position-p2.position) * change * dt;
}
Но при попытке этого p2 падает без ограничений.Как я могу гарантировать, что p2 падает аналогично изображению?
Обновлено applyConstraint:
void Scene::applyConstraint(Point &p1, Point &p2, float dt) {
float change = (glm::length(p1.position - p2.position) - glm::length(p1.op - p2.op)) / glm::length(p1.position - p2.position);
glm::vec3 force = 0.5f * (p1.position - p2.position) * change * dt;
glm::vec3 accel1 = (-force / p1.mass) * dt;
glm::vec3 accel2 = (force / p2.mass) * dt;
p1.velocity += accel1 * dt;
p2.velocity += accel2 * dt;
p1.position += p1.velocity * dt;
p2.position += p2.velocity * dt;
}