OpenGL +围绕点旋转弹簧和质量
Posted
技术标签:
【中文标题】OpenGL +围绕点旋转弹簧和质量【英文标题】:OpenGL + Rotate Spring and Mass around Point 【发布时间】:2016-01-30 22:48:53 【问题描述】:我试图通过一个弹簧围绕一个末端有一个质量的点旋转来做物理。我想做我有 angularVelocity 改变我的对象被重绘的角度,但它没有做一个干净的旋转,我的意思是我的弹簧质量确实围绕该点旋转,但它目前也在围绕轴向下旋转春天。我相当确定我计算围绕该点的旋转的公式是错误的。
这是我的更新函数,每个时间步都会调用它。这是计算重新绘制弹簧质量的角度的地方。然后对象生成器使用重新计算的顶点重建弹簧质量模型,以便它们围绕锚点位置(此时只是原点)旋转
void angularSpring::updateGeometry(atlas::utils::Time const& t)
angleDegrees = GLfloat((int(angleDegrees + angularVelocity)) % 360);
mSpringMass = ObjectGenerator::makeAngularSpringMass(anchorPosition, springWidth2, stretched, massWidth, massHeight, angleDegrees);
glBufferSubData(GL_ARRAY_BUFFER, 0, mSpringMass.vertexBufferSize(), mSpringMass.vertices);
mSpringMass.cleanup();
下面是我的 ObjectGenerator,它执行顶点数据的重新计算。这有点笨拙,但它可以工作......除了旋转计算。底部的函数实际上是重新计算每个新顶点的位置。我猜是在这些函数中存在错误。我从here 得到了公式。重申一下,我希望我的 springMass 系统简单地围绕 anchorPosition 点旋转,但是现在它围绕点和沿弹簧的轴旋转。 (即从 anchorPosition 到质量的底部)。
ShapeData ObjectGenerator::makeAngularSpringMass(glm::vec3 anchorPosition, GLfloat springWidth, GLfloat stretch, GLfloat width, GLfloat height, GLfloat angle)
ShapeData ret;
angle = glm::radians(angle);
glm::vec3 springColor 1.0f, 0.0f, 0.0f , massColor 0.0f, 1.0f, 0.0f , connectionPoint anchorPosition.x, anchorPosition.y - (17 * stretch), 0.0f ;
//The original model
Vertex springMass[] =
glm::vec3(anchorPosition.x, anchorPosition.y, 0.0f), // 0
springColor,
glm::vec3(anchorPosition.x, anchorPosition.y - (0.1 *stretch),0.0f), // 1
springColor,
glm::vec3(anchorPosition.x + springWidth, anchorPosition.y - (1 * stretch), 0.0f), // 2
springColor,
glm::vec3(anchorPosition.x - springWidth, anchorPosition.y - (3 * stretch), 0.0f), // 3
springColor,
glm::vec3(anchorPosition.x + springWidth, anchorPosition.y - (5 * stretch), 0.0f), // 4
springColor,
glm::vec3(anchorPosition.x - springWidth, anchorPosition.y - (7 * stretch), 0.0f), // 5
springColor,
glm::vec3(anchorPosition.x + springWidth, anchorPosition.y - (9 * stretch), 0.0f), // 6
springColor,
glm::vec3(anchorPosition.x - springWidth, anchorPosition.y - (11 * stretch), 0.0f), // 7
springColor,
glm::vec3(anchorPosition.x + springWidth, anchorPosition.y - (13 * stretch), 0.0f), // 8
springColor,
glm::vec3(anchorPosition.x - springWidth, anchorPosition.y - (15 * stretch), 0.0f), // 9
springColor,
glm::vec3(anchorPosition.x, anchorPosition.y - (16 * stretch), 0.0f), // 10
springColor,
connectionPoint, // 11
springColor,
//=================Mass==============//
glm::vec3(connectionPoint.x - width, connectionPoint.y, 0.0f), //top Left 12
massColor,
glm::vec3(connectionPoint.x + width, connectionPoint.y, 0.0f), //top Right 13
massColor,
glm::vec3(connectionPoint.x + width, connectionPoint.y - height, 0.0f), // bottom right 14
massColor,
glm::vec3(connectionPoint.x - width, connectionPoint.y - height, 0.0f), // bottom left 15
massColor,
;
//New vertices recomputed around anchorPosition
Vertex vertices[] =
glm::vec3(anchorPosition.x, anchorPosition.y, 0.0f), // 0
springColor,
glm::vec3(getRotatedX(angle, springMass[1], anchorPosition), getRotatedY(angle, springMass[1], anchorPosition), 0.0f), // 1
springColor,
glm::vec3(getRotatedX(angle, springMass[2], anchorPosition), getRotatedY(angle, springMass[2], anchorPosition), 0.0f), // 2
springColor,
glm::vec3(getRotatedX(angle, springMass[3], anchorPosition), getRotatedY(angle, springMass[3], anchorPosition), 0.0f), // 3
springColor,
glm::vec3(getRotatedX(angle, springMass[4], anchorPosition), getRotatedY(angle, springMass[4], anchorPosition), 0.0f), // 4
springColor,
glm::vec3(getRotatedX(angle, springMass[5], anchorPosition), getRotatedY(angle, springMass[5], anchorPosition), 0.0f), // 5
springColor,
glm::vec3(getRotatedX(angle, springMass[6], anchorPosition), getRotatedY(angle, springMass[6], anchorPosition), 0.0f), // 6
springColor,
glm::vec3(getRotatedX(angle, springMass[7], anchorPosition), getRotatedY(angle, springMass[7], anchorPosition), 0.0f), // 7
springColor,
glm::vec3(getRotatedX(angle, springMass[8], anchorPosition), getRotatedY(angle, springMass[8], anchorPosition), 0.0f), // 8
springColor,
glm::vec3(getRotatedX(angle, springMass[9], anchorPosition), getRotatedY(angle, springMass[9], anchorPosition), 0.0f), // 9
springColor,
glm::vec3(getRotatedX(angle, springMass[10], anchorPosition), getRotatedY(angle, springMass[10], anchorPosition), 0.0f), // 10
springColor,
glm::vec3(getRotatedX(angle, springMass[11], anchorPosition), getRotatedY(angle, springMass[11], anchorPosition), 0.0f), // 11
springColor,
//=================Mass==============//
glm::vec3(getRotatedX(angle, springMass[12], anchorPosition), getRotatedY(angle, springMass[12], anchorPosition), 0.0f), // 12
massColor,
glm::vec3(getRotatedX(angle, springMass[13], anchorPosition), getRotatedY(angle, springMass[13], anchorPosition), 0.0f), // 13
massColor,
glm::vec3(getRotatedX(angle, springMass[14], anchorPosition), getRotatedY(angle, springMass[14], anchorPosition), 0.0f), // 14
massColor,
glm::vec3(getRotatedX(angle, springMass[15], anchorPosition), getRotatedY(angle, springMass[15], anchorPosition), 0.0f), // 15
massColor,
;
ret.numVertices = NUM_ARRAY_ELEMENTS(vertices);
ret.vertices = new Vertex[ret.numVertices];
memcpy(ret.vertices, vertices, sizeof(vertices)); //memcpy(dest, source, size);
GLushort indices[] = 0,1 ,1,2, 2,3, 3,4, 4,5, 5,6, 6,7, 7,8, 8,9, 9,10, 10,11, 11,12, 12,13, 13,14, 14,15, 15,12 ;
ret.numIndices = NUM_ARRAY_ELEMENTS(indices);
ret.indices = new GLushort[ret.numIndices];
ret.connectionPoint = connectionPoint;
memcpy(ret.indices, indices, sizeof(indices));
return ret;
GLfloat ObjectGenerator::getRotatedX(GLfloat angle, Vertex old, glm::vec3 anchorPosition)
GLfloat newX = (glm::cos(angle) * (old.position.x - anchorPosition.x)) - (glm::sin(angle) * (old.position.y - anchorPosition.y)) + anchorPosition.x;
return newX;
GLfloat ObjectGenerator::getRotatedY(GLfloat angle, Vertex old, glm::vec3 anchorPosition)
GLfloat newY = (glm::sin(angle) * (old.position.x - anchorPosition.x)) - (glm::cos(angle) * (old.position.y - anchorPosition.y)) + anchorPosition.y;
return newY;
【问题讨论】:
【参考方案1】:我想通了。我的旋转方程中有一些符号是错误的。正确的函数如下所示:
GLfloat ObjectGenerator::getRotatedX(GLfloat angle, Vertex old, glm::vec3 anchorPosition)
GLfloat newX = (glm::cos(angle) * (old.position.x - anchorPosition.x)) + (glm::sin(angle) * (old.position.y - anchorPosition.y)) + anchorPosition.x;
return newX;
GLfloat ObjectGenerator::getRotatedY(GLfloat angle, Vertex old, glm::vec3 anchorPosition)
GLfloat newY = -(glm::sin(angle) * (old.position.x - anchorPosition.x)) + (glm::cos(angle) * (old.position.y - anchorPosition.y)) + anchorPosition.y;
return newY;
【讨论】:
以上是关于OpenGL +围绕点旋转弹簧和质量的主要内容,如果未能解决你的问题,请参考以下文章