【发布时间】:2019-04-16 18:18:06
【问题描述】:
我想在两点之间应用约束,同时应用重力。我绘制的下图展示了点 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;
}
【问题讨论】:
-
在
applyConstraint方法中,p1和p2是通过拷贝传递的,所以点没有正确更新。 -
@Gilles-PhilippePaillé 我已更正以在我的代码中通过引用传递,但仍然得到相同的错误。还有其他想法吗?
-
您正在计算弹簧力,但您将其用作速度。您应该修改速度,而不是修改位置。告诉我它是否有效。
-
@Gilles-PhilippePaillé 我尝试将力用作力,将其更改为加速度,然后更改为速度。我已经添加了更新的代码,但点仍然下降。
标签: c++ simulation game-physics glm-math