title: OpenGL + Rotate Spring and Mass around Point
body: <p>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. </p>
  
  <p>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)</p>
  
  <pre><code>void angularSpring::updateGeometry(atlas::utils::Time const&amp; 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();
  }
  </code></pre>
  
  <p>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 <a href="http://www.gamefromscratch.com/post/2012/11/24/GameDev-math-recipes-Rotating-one-point-around-another-point.aspx" rel="nofollow">here</a> 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. (i.e. from the anchorPosition to the bottom of the mass).</p>
  
  <pre><code>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;
  }
  </code></pre>