Advertisement

Reverse movement.

Started by March 25, 2009 04:46 PM
1 comment, last by Antonym 15 years, 11 months ago
I am trying to make a ship that given a point in space(2d) will turn towards it and if facing close enough will start to move, that part I have so far. Now I want it to check if it would be faster to face that point or turn its back on it and go on reverse. I am having trouble implementing this I think it has something to do with the angles. This is the solution I have right now.

void ShipEnemy::TurnTowardsPoint()
{
	b2Vec2 v1 = GetDirection(1); //Gets the direction vector.
	v1.Normalize();
	v1 = b2Vec2(-v1.y,v1.x);
	b2Vec2 v2 = mTarget - mBody->GetPosition();
	float angle = b2Dot(v1,v2);

	v1 = GetDirection2(1); //Gets the opposite direction.
	v1.Normalize();
	v1 = b2Vec2(-v1.y,v1.x);
	float angle2 = b2Dot(v1,v2);

	float threshold = DegToRad(90);

	if(angle >= -threshold && angle <= threshold){
		if(TurnFront(angle))
			Impulse(MOVE_SPEED);
	}
	else{
		if(TurnBack(angle2))
			Impulse(-MOVE_SPEED);
	}
}
bool ShipEnemy::TurnFront(float angle)
{
	float threshold = DegToRad(10);

	if(angle > 0)
		Rotate(-ROT_SPEED);
	else
		Rotate(ROT_SPEED);

	if(angle >= -threshold && angle <= threshold) 
		return true;

	return false;
}
bool ShipEnemy::TurnBack(float angle)
{
	float threshold = DegToRad(10);

	if(angle > 0)
		Rotate(-ROT_SPEED);
	else
		Rotate(ROT_SPEED);

	if(angle >= -threshold && angle <= threshold) 
		return true;

	return false;
}

Assuming that you're not already moving: if the dot product between the normalized forward vector of the ship and the normalized ship->target vector is a negative number it is faster to turn your back.

[EDIT: reasoning

dot product of 2 normalized vectors = cos ( angle between them );

cos(0) = 1
cos(90) = 0
cos(180) = -1;

so, if the cos(angle) is negative the angle between those 2 vectors is > 90 degrees which means that your closer to having your ass pointed towards your target then you are having your nose pointed towards it.

At that point to determine whether to turn left or right you do a cross product of the same vectors. Based on whether that vector is pointing up or down you know in which direction the shortest turn lies.
]

However, I should point out that for realism, boats almost always go much faster forwards than backwards. No real war ship would ever approach in reverse.

-me
Advertisement
Err I don't see how that could work no matter where the ship is facing, won't cos(0),cos(90,cos.. etc stay the same?

I tried though but it doesn't seem to work. The ship turns towards the point but moves backwards.
void ShipEnemy::TurnTowardsPoint(){	b2Vec2 v1 = GetDirection(1); //Gets the direction vector.	v1.Normalize();	v1 = b2Vec2(-v1.y,v1.x);	b2Vec2 v2 = mTarget - mBody->GetPosition();	float angle = b2Dot(v1,v2);	float angle2 = b2Cross(v1,v2);	if(angle > 0){		if(TurnFront(angle, angle2))			Impulse(MOVE_SPEED);	}	else{		if(TurnBack(angle, angle2))			Impulse(-MOVE_SPEED);	}}inline float32 b2Cross(const b2Vec2& a, const b2Vec2& b){	return a.x * b.y - a.y * b.x;}bool ShipEnemy::TurnFront(float angle, float angle2){	float threshold = DegToRad(10);	if(angle > 0)		Rotate(-ROT_SPEED);	else		Rotate(ROT_SPEED);	if(angle >= -threshold && angle <= threshold) 		return true;	return false;}bool ShipEnemy::TurnBack(float angle, float angle2){	float threshold = DegToRad(10);	if(angle > 0)		Rotate(-ROT_SPEED);	else		Rotate(ROT_SPEED);	if(angle >= -threshold && angle <= threshold) 		return true;	return false;}

This topic is closed to new replies.

Advertisement