Exemplo n.º 1
0
void Sphere::DrawRays(Ray ray, sf::RenderWindow *window) {
//	sf::Vertex way[4];
	StraightLine line = ray.Equation();
	Vector2 p = Intersect(line, c2.center, c2.r, '-');
	way[0] = sf::Vertex(sf::Vector2f(ray.getBegin().x, ray.getBegin().y), COLOR);
	way[1] = sf::Vertex(sf::Vector2f(p.x, p.y), COLOR);
	StraightLine normal = Normal(p, 2);
	StraightLine refrline;
//	drawNormal(p, normal, window);
	double sin = sinAngle(normal, line);
	double refr_sin = sin / n;
	if (refr_sin > 1 || refr_sin < -1) { // external reflection
		cout << "I AM HERE" << endl;
		refrline = external_reflection(normal, sin, p, line.a);
		
		double x =  - refrline.b / refrline.a;
		//double y = refrline.a * 500 + refrline.b;
		way[2] = sf::Vertex(sf::Vector2f(x, 0));
		
	}
	else{
		 refrline = refr_line(normal, refr_sin, p, line.a);
		cout << "REFRSIN" << refr_sin<< endl;
		p = Intersect(refrline, c1.center, c1.r, '+');

		way[2] = sf::Vertex(sf::Vector2f(p.x,p.y), COLOR);
		normal = Normal(p, 1);
	}
	sin = sinAngle(normal, refrline);
	refr_sin = n*sin;
//cout << refr_sin << endl;
	if (refr_sin > 1 || refr_sin < -1) { // external reflection
		
		cout << "REFRSIN" << refr_sin << endl;
		refrline = external_reflection(normal, sin, p, refrline.a);
		double x = (250 - refrline.b) / refrline.a;
		//double y = refrline.a * 500 + refrline.b;
		way[3] = sf::Vertex(sf::Vector2f(x,250), COLOR);
		window->draw(way, 4, sf::LinesStrip);
	}
	else {
		refrline = refr_line(normal, refr_sin, p, refrline.a);
		//double x = (250 - refrline.b) / refrline.a;
		//way[3] = sf::Vertex(sf::Vector2f(x, 250));
		double y = refrline.a * 500 + refrline.b;
		way[3] = sf::Vertex(sf::Vector2f(500, y), COLOR);
		window->draw(way, 4, sf::LinesStrip);
	}
}
 inline
 Matrix2d
 Quaternion2d::rotationMatrix() const {
     return Matrix2d(cosAngle(), sinAngle(), -sinAngle(), cosAngle());
 }
 inline
 Quaternion2d
 Quaternion2d::inverse() const {
     return Quaternion2d(cosAngle(), -sinAngle());
 }
 inline
 double
 Quaternion2d::dot(const Quaternion2d& other) const {
     return cosAngle() * other.cosAngle() + sinAngle() * other.sinAngle();
 }
 inline
 double
 Quaternion2d::angle() const {
     return atan2(sinAngle(), cosAngle());
 }
Exemplo n.º 6
0
void Ball::ProcessCollisions(unordered_map<string, Game_Object*> objects)
{
	// Calculate 
	Vector4 thisCenter(this->translationMatrix[0][3], this->translationMatrix[1][3], 0.0f, 0.0f);

	// Check collision with all objects
	for(unordered_map<string, Game_Object*>::iterator itr = objects.begin(); itr != objects.end(); itr++)
	{
		//
		Vector4 otherCenter(itr->second->translationMatrix[0][3], itr->second->translationMatrix[1][3], 0.0f, 0.0f);
		Vector4 combinedRadius = this->sprite->GetRadius() + itr->second->sprite->GetRadius();

		// Check for collidable objects, based on dictionary name
		if(itr->first == "WallLeft" && thisCenter.x - sprite->GetRadius().x < otherCenter.x + itr->second->sprite->GetRadius().x)
		{
			velocity->x += this->velocity->x * -2.0f;
		}
		if(itr->first == "WallRight" && thisCenter.x + sprite->GetRadius().x > otherCenter.x - itr->second->sprite->GetRadius().x)
		{
			velocity->x += this->velocity->x * -2.0f;
		}
		if(itr->first == "WallTop" && thisCenter.y + sprite->GetRadius().x > otherCenter.y - itr->second->sprite->GetRadius().y)
		{
			velocity->y += this->velocity->y * -2.0f;
		}
		if(itr->first == "WallBottom" && thisCenter.y - sprite->GetRadius().x < otherCenter.y + itr->second->sprite->GetRadius().y)
		{
			velocity->y += this->velocity->y * -2.0f;
		}


		// Detect spherical collision
		if( ( itr->first.find("Ball") != string::npos || itr->first == "Bumper" /*|| itr->first == "Flipper1"*/) && 
			itr->second != this && 
			( (thisCenter.x - otherCenter.x) * (thisCenter.x - otherCenter.x) ) +
			( (thisCenter.y - otherCenter.y) * (thisCenter.y - otherCenter.y) ) <
			( combinedRadius.x * combinedRadius.x) )
		{
			// Get the vector in between the two objects
			Vector4 hyp( (thisCenter.x - otherCenter.x), (thisCenter.y - otherCenter.y), 0.0f, 0.0f );
			// Get the normal vector to the colliding object
			Vector4 normal(hyp.normalize(hyp));
			// Calculate a new velocity
			*velocity = normal * (velocity->dot(normal) * -2.0f) + *velocity;
			// Separate collided objects (upon collision 2 objects will slightly overlap so this is necessary)
			Matrix4::UpdatePositionMatrix(translationMatrix, velocity->x, velocity->y, 0);

			// NOTE: Ball-Ball collision sometimes only changes the velocity of one of the balls
		}

		// Angle of reflection (angle of flipper)
		float bounceAngle = 0.0f;
		if(itr->first == "Flipper1" && FlipperCollision(otherCenter, *(itr->second), bounceAngle))
		{

			Vector4 flipperRadius(itr->second->sprite->GetRadius().x, itr->second->sprite->GetRadius().y, 0.0f, 0.0f);
			GLfloat cosAngle(itr->second->rotationMatrix[0][0]);
			GLfloat sinAngle(-itr->second->rotationMatrix[0][1]);
			
			// Calculate angle of impact
			GLfloat hitAngle = atan(velocity->y/velocity->x) + PI;
			if(velocity->x < 0)
				hitAngle += 180 * PI / 180;
			else if(velocity->x >= 0 && velocity->y < 0)
				hitAngle += 360 * PI / 180;
			
			if(hitAngle >= 2*PI - .0000002 && hitAngle <= 2*PI + .0000002)
				hitAngle = 0.0f;

			bounceAngle = PI - hitAngle - 2 * bounceAngle;
				if(bounceAngle < 0)
					bounceAngle += 2 * PI;

			float length = velocity->length();
			
			
			// How to get a vector based on this angle
			Vector4 normal(length * cos(bounceAngle), length * sin(bounceAngle), 0.0f, 0.0f);

			*velocity = normal;

			// Separate collided objects (upon collision 2 objects will slightly overlap so this is necessary)
			Matrix4::UpdatePositionMatrix(translationMatrix, velocity->x, velocity->y, 0);

			// NOTE: Corner wonky, need to implement with rotation
		}
	}
}