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 +围绕点旋转弹簧和质量的主要内容,如果未能解决你的问题,请参考以下文章

在OpenGL中围绕特定点旋转对象

OpenGL绕点旋转

OpenGL 平移和旋转同时进行

opengl 围绕固定轴旋转对象

在OpenGL中围绕坐标旋转四边形

OpenGL - 围绕 Y 轴旋转“曲线”