Reputation: 7414
I have a spaceship, that spaceship moves though space 360 Degrees.
The spaceship needs thrust animation in 2d. The trust animation needs to be at the bottom middle line of the spaceship. I have the following variables.
_Rotation
_Spaceship.width
_Spaceship.height
_Spaceship.Position(x,y)
I've uploaded an image of my problem too in-case people don't understand my bad explanation:
https://i.sstatic.net/wIEx3.jpg
Both animation render like so:
this._itemAnimation.render(this.getPosition(), canvas, this._degrees);
this._thrustAnimation.render(this.thrustPosition(), canvas, this._degrees);
I have tried so far and failed:
_thurstPosition.set(((int)_object_x + Math.cos(_degrees) * _itemAnimation.getWidth() / 2) ,
((int)_object_y + Math.sin(_degrees) * _itemAnimation.getWidth() / 2));
I'm fail, somebody help me.
--- UPDATE ---
I've updated the code so it's better understood:
int SpaceshipCenterX = getPosition().x + (_SpaceshipAnimation.getWidth() / 2) - (_thrustAnimation.getWidth() / 2);
int SpaceshipCenterY = getPosition().y + ((_SpaceshipAnimation.getHeight() / 2) - (_thrustAnimation.getHeight() / 2));
double OffSetCos = Math.cos(_spaceshipDegrees);
double OffSetSin = Math.sin(_spaceshipDegrees);
_thurstPosition.set
(
(int)(SpaceshipCenterX + (SpaceshipAnimation.getWidth() / 2) * OffSetCos)
,
(int)(SpaceshipCenterY + (SpaceshipAnimation.getHeight() / 2) * OffSetSin)
);
I still can't get it too work. It's going around the spaceship but very fast and flashing everywhere.
--- UPDATE 2 ---
This is almost working but it's going too far out:
int xOffset = -1 * (_itemAnimation.getWidth() / 2);
double DegreeToRadien = Math.toRadians(_degrees);
_thurstPosition.set
(
(int)(((xOffset) * Math.cos(DegreeToRadien)) + getPosition().x),
(int)(((xOffset) * Math.sin(DegreeToRadien)) + getPosition().y)
);
Upvotes: 0
Views: 911
Reputation: 22956
Assuming that you are using this coordinate/angle system:
90 (pi/2) - Up
^
|
Left - 180 (pi) <----|----> 0 - Right
|
v
Down - 270 (3pi/2)
And that your spaceship is going to the right at 0 degrees
>[ } 0
Then for any direction you need to translate the thrust relatively from the centre of the spaceship, let's say we translate in the x direction by
offset = -1 * width/2;
Then rotate it by the angle of the spaceship and finally translate it by the position of the spaceship.
To compute this transformation, write out the 3 transformations as matrices in reverse order and multiply them out, transforming a point starting at (0,0)
[1 0 spaceshipX] [cos(dir) -sin(dir) 0] [1 0 -width/2] [0]
[0 1 spaceshipY] [sin(dir) cos(dir) 0] [0 1 0 ] [0]
[0 0 1 ] [ 0 0 1] [0 0 1 ] [1]
So that would give you the position of the thrust as
thrustX = (-width/2)cos(dir) + spaceshipX
thrustY = (-width/2)sin(dir) + spaceshipY
So I suppose you just missed the fact you need to subtract width/2, not add it.
I've edited this with a correct and more readable syntax. Using underscores everywhere really hurts readability. I am assuming you have a spaceship class, and the spaceship has a width, height, x position, y position and rotation. You have a thruster class which also has a width, height, x position, y position and rotation. (They could inherit from a Sprite abstract class). To set the position of a thruster object we call thruster.setPosition(x,y);
int xOffset = -1 * (spaceship.width / 2);
thruster.setPosition(
(int)(((xOffset) * Math.cos(spaceship.rotation)) + spaceship.x),
(int)(((xOffset) * Math.sin(spaceship.rotation)) + spaceship.y)
);
Hopefully this makes it obvious to you which values you need to be setting where. I can't decipher your code without seeing more of it, where these variables are declared and what they actually mean.
Just to conclude, as I think you may have discovered. Math.cos and Math.sin require angles to be in Radians, not degrees. The solution I have given here is correct, and I have shown how you compute the position of any relatively positioned object by performing the matrix calculation. You just have to remember that spaceship.rotation must be in radians or you must translate it to radians from degrees before passing it to Math.cos() or Math.sin().
int xOffset = -1 * (spaceship.width / 2);
double radians = Math.toRadians(spaceship.rotation);
thruster.setPosition(
(int)(((xOffset) * Math.cos(radians)) + spaceship.x),
(int)(((xOffset) * Math.sin(radians)) + spaceship.y)
);
Upvotes: 4
Reputation: 7414
double DegreeToRadien = Math.toRadians(_degrees);
int ObjectXCenter = (int) (_object_x + ((_itemAnimation.getWidth() / 2)) - _thrustAnimation.getWidth() / 2);
int ObjectYCenter = (int) (_object_y + ((_itemAnimation.getHeight() / 2)) - _thrustAnimation.getHeight() / 2);
int xOffset = -1 * (_itemAnimation.getWidth() / 2);
_thurstPosition.set
(
(int)(((xOffset) * Math.cos(DegreeToRadien)) + ObjectXCenter),
(int)(((xOffset) * Math.sin(DegreeToRadien)) + ObjectYCenter)
);
Upvotes: 0
Reputation: 23265
Your code looks close to me. You need to be careful about what _degrees
means. If _degrees
is the direction in which the rocket points (counterclockwise from the +x axis), then you'll need to put some minus signs in there because the thrust is at the back of the rocket, not the front. Also, I would think the thrust is on the height end of the rocket, so use getLength
instead of getWidth
. You may need to add some extra for the height of the thrust animation as well (depending on where its anchor is). So something like
_thurstPosition.set(((int)_object_x - Math.cos(_degrees) * (_itemAnimation.getHeight() / 2 + _thrustAnimation.getHeight() / 2)) ,
((int)_object_y - Math.sin(_degrees) * (_itemAnimation.getHeight() / 2 + _thrustAnimation.getHeight() / 2)));
You'll also need to set thrust orientation if it isn't a circle.
(I'm assuming _degrees
== _Rotation
)
Upvotes: 1