Jump to content
  • Advertisement
Guy Leonard Thomas

C++ Simple trig problem driving me crazy

Recommended Posts

Hello folks,

I am fighting with a really simple problem that has been driving me nuts. I'm usually fairly confident with trigonometry and I'm pretty sure the issue here is not the math but in some behavior behind the scenes.

A bit of background - basically I'm developing my own little 2D game engine using C++, in my free-time for fun. I work with game technology and simulation products IRL so for the most part this has been plain sailing. I am using Box2D for physics, and SFML for rendering.

My game at current has a few space ships flying around via keyboard and AI input. These space ships need exhausts! So I'm currently in the process of getting a 'component' system in place, however my problem is that the animated exhaust sprites are not going where I want them to.

When the base GameObject class runs it's update method, it does the following:

  1. Queries the physics object for a position
  2. Converts the physics position to a pixel position (x10 scale factor)
  3. Moves the sprite to the new position
  4. Passes new position to all 'component' objects into their 'UpdateComponent' method
  5. Components move their sprite to the correct position

However the exhaust sprites seem to wander around all over the place, in no way representing where I actually want them to be! This should have been a simple case of:

  • newPosition = (sin(rotationRadians) * offsetX, cos(rotationRadians) * offsetY) + oldPosition

Here is the current code:

void Exhaust::UpdateComponent(const Vec2f & position, float rotationDegrees, float deltaTime)
{
	float angleRad = DEGREES_TO_RADIANS(rotationDegrees);
	float offsetX = sin(angleRad) * mOffset.x;
	float offsetY = cos(angleRad) * mOffset.y;

	sf::Vector2f newPos(position.x + offsetX, position.y + offsetY);

	mSprite->SetRotation(rotationDegrees);
	mSprite->SetPosition(newPos);
	mSprite->Update(deltaTime);

#ifdef _DEBUG
	sf::Vector2f p(position.x, position.y);
	stringstream ss;
	ss << rotationDegrees;
	DebugUtils::DrawCross(p, 8, sf::Color::Green, ss.str());
	DebugUtils::DrawCross(newPos, 8, sf::Color::Green);
	DebugUtils::DrawLine(p, newPos, sf::Color::Green);
	cout << rotationDegrees << endl;

	DebugUtils::DrawSpriteOutline(*mSprite->GetGraphic(), sf::Color::Green);
#endif // _DEBUG
}

 

And here is a gif of it all going wrong! (link below)

Gif of game engine problem

Any help would be much appreciated, even if it is just a thought of where the problem might be originating from!

Thanks!

Share this post


Link to post
Share on other sites
Advertisement
1 minute ago, Guy Leonard Thomas said:

newPosition = (sin(rotationRadians) * offsetX, cos(rotationRadians) * offsetY) + oldPosition

Shouldn't sin and cos be reversed there? Ie.

newPosition = (cos(rotationRadians) * offsetX, sin(rotationRadians) * offsetY) + oldPosition

 

Share this post


Link to post
Share on other sites

I haven't dug into this problem but I think you should look into using Transforms.  This is what Transforms do, transform a local coordinate space into another space like the global, camera or viewport space.  You're going to be doing trig everywhere if you don't use transforms and it just seems like there's a super-simple solution already done for you in the library you're already using and you're not using it.

Share this post


Link to post
Share on other sites
5 minutes ago, gaxio said:

I haven't dug into this problem but I think you should look into using Transforms.  This is what Transforms do, transform a local coordinate space into another space like the global, camera or viewport space.  You're going to be doing trig everywhere if you don't use transforms and it just seems like there's a super-simple solution already done for you in the library you're already using and you're not using it.

This sounds entirely like a good idea, I'll look into transforms, thanks!

Share this post


Link to post
Share on other sites

The captures don't load for me, but I am wondering why the rotation would be impacting the position. 

I assume mOffset are members, but you aren't setting them with this method that is already taking an offset in.

This math would make since if you passing a rotation and a speed:

Velocity.y=sin(angle)*speed

Velocity.x=cos(angle)*speed

Newpos=oldpos+velocity.

Perhaps we need more context to understand what you are trying to do, but I don't see why you are doing this particular math.

Share this post


Link to post
Share on other sites
3 minutes ago, Michael LaserBlade Scoggin said:

The captures don't load for me, but I am wondering why the rotation would be impacting the position. 

I assume mOffset are members, but you aren't setting them with this method that is already taking an offset in.

This math would make since if you passing a rotation and a speed:

Velocity.y=sin(angle)*speed

Velocity.x=cos(angle)*speed

Newpos=oldpos+velocity.

Perhaps we need more context to understand what you are trying to do, but I don't see why you are doing this particular math.

Hey mate,

No probs, I should've explained. So basically the offset parameters are supplied via a config file, and describe the offset in pixels, from the centre of the sprite, that the component sprite(s) should be rendered. So for example, the exhaust jet for this particular sprite is at offset (-50,-14) from the center of the sprite.

When the sprite rotates, the sub-sprite should too

Share this post


Link to post
Share on other sites

Ahh, that is definitely what transform matrices are for. You multiply the hierarchy together to get your final transformation. But without them you want

The math you want is a vector rotation:

 x' = x cos θ − y sin θ
 y' = x sin θ + y cos θ

Where theta is the rotation of the parent.

x' and y' will be rotated versions of x and y. 

You also have to translate by adding your parents position to yours.

There can be a scaling as well.

All of these can be represented as a matrix individualy and multiplied to get to make a 'transform'. 

Order matters. 

It might worth noting that exhaust is the type of thing your ship would 'drop' and only it's spawn would be relative to the ship and it's position would become fixed or at least detached from the ship imeddiately. You could add some drift to it though for a cool effect.

Share this post


Link to post
Share on other sites
Posted (edited)

Yeah I feel like I really should've been using transforms from the beginning - didn't know SFML had them! (Didn't look for them to be fair). Oh well silly me :D

Thanks for the input folks, will post a working image once I've fixed it

Edited by Guy Leonard Thomas

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!