void Scene::step() { // This is the heart of the simulation. checkCollisions(); // EULER //applyG(); getImpulse(); integrateVelocities(); updatePositions(); clearStep(); // Increment time for next step, used in RK4. t += dt; }
void Convex::applyChanges(int index, sf::Vector2f* collisionNormal) { float radius = getRadius(index); sf::Vector2f collisionPoint(getPoint(index).x - _massCenter.x, getPoint(index).y - _massCenter.y); _momentOfInertia = _mass * pow(radius, 2); float impulse = getImpulse(&collisionPoint, collisionNormal); _velocity.x += impulse / _mass * collisionNormal->x; _velocity.y += impulse / _mass * collisionNormal->y; _angularVelocity = _angularVelocity + impulse / _momentOfInertia * (collisionPoint.x * collisionNormal->y - collisionPoint.y * collisionNormal->x); }
/* Calculates the coordinates of the collision point */ void Convex::convexCollision(Convex* other, sf::RenderWindow* window) { sf::Vector2f collisionNormal; float collisionX, collisionY; float x1, x2, x3, x4, y1, y2, y3, y4; if (hasCollided(other)) { for (int i = 0; i < getPointCount(); i++) { //Retrieves the coordinates of the point i x1 = this->getPoint(i).x; y1 = this->getPoint(i).y; //If the index 'i' equals the amount of points //the other end of the line should be the starting point if (i == getPointCount() - 1) { x2 = this->getPoint(0).x; y2 = this->getPoint(0).y; } else { x2 = this->getPoint(i + 1).x; y2 = this->getPoint(i + 1).y; } for (int j = 0; j < other->getPointCount(); j++) { x3 = other->getPoint(j).x; y3 = other->getPoint(j).y; //If the index 'j' equals the amount of points //the other end of the line should be the starting point if (i == getPointCount() - 1) { x4 = other->getPoint(0).x; y4 = other->getPoint(0).y; } else { x4 = other->getPoint(i + 1).x; y4 = other->getPoint(i + 1).y; } collisionX = vectorProduct(vectorProduct(x1, y1, x2, y2), vectorProduct(x1, 1, x2, 1), vectorProduct(x3, y3, x4, y4), vectorProduct(x3, 1, x4, 1)) / vectorProduct(vectorProduct(x1, 1, x2, 1), vectorProduct(y1, 1, y2, 1), vectorProduct(x3, 1, x4, 1), vectorProduct(y3, 1, y4, 1)); collisionY = vectorProduct(vectorProduct(x1, y1, x2, y2), vectorProduct(y1, 1, y2, 1), vectorProduct(x3, y3, x4, y4), vectorProduct(y3, 1, y4, 1)) / vectorProduct(vectorProduct(x1, 1, x2, 1), vectorProduct(y1, 1, y2, 1), vectorProduct(x3, 1, x4, 1), vectorProduct(y3, 1, y4, 1)); //Checking that the collision point is actually between the corners //of the convexes if (isBetween(collisionX, x1, x2) && isBetween(collisionX, x3, x4) && isBetween(collisionY, y1, y2) && isBetween(collisionY, y3, y4)) { //If the collision point is between these points use them to calculate the //collisionNormal's components if (isBetween(collisionX, x1, x2) && isBetween(collisionY, y1, y2)) { float x = x2 - x1; float y = y2 - y1; float length = sqrt(pow(x, 2) + pow(y, 2)); float unitX = x / length; float unitY = y / length; collisionNormal.x = -unitY; collisionNormal.y = unitX; float impulse = getImpulse(&sf::Vector2f(collisionX, collisionY), &collisionNormal, other, this); applyChanges(&collisionNormal, impulse, &sf::Vector2f(collisionX, collisionY), other, this); } else { float x = x4 - x3; float y = y4 - y3; float length = sqrt(pow(x, 2) + pow(y, 2)); float unitX = x / length; float unitY = y / length; collisionNormal.x = -unitY; collisionNormal.y = unitX; float impulse = getImpulse(&sf::Vector2f(collisionX, collisionY), &collisionNormal, this, other); applyChanges(&collisionNormal, impulse, &sf::Vector2f(collisionX, collisionY), this, other); } sf::CircleShape circle(5); circle.setFillColor(sf::Color::Red); circle.setPosition(collisionX, collisionY); window->draw(circle); } } } } }