예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
/*
	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);
				}
			}
		}
	}
}