简体   繁体   中英

OpenGL + Rotate Spring and Mass around Point

I am trying to do the physics by hand of a spring rotating around a point with a mass on the end. I want to do I have the angularVelocity changing the angle at which my object is redrawn but it isn't doing a clean rotation by which I mean the my spring mass does rotate around the point however it is currently also rotating around the axis down the spring. I fairly sure that my formula to calculate the rotation around the point is wrong.

This is my update function which is called every time step. It is where the angle the spring-mass is redrawn at is calculated. The object generator then rebuilds the spring-mass model with the vertices recomputed such that they are rotated around the anchorPosition (which at the moment is just the origin)

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();
}

Below is my ObjectGenerator which performs the recomputation of the vertices data. It's a little clumsy but it works... with the exception of the rotation calculation. The functions at the bottom are what actually recalculate each new vertices position. I'm guessing that it is in these functions that there is an error. I got the formulas from here though. To reiterate I want my springMass system to simply rotate around the anchorPosition point however right now it is rotating around both the point and the axis along the spring. (ie from the anchorPosition to the bottom of the mass).

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;
}

I figured it out. I had some of the signs wrong in my rotation equations. The proper functions look like this:

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM