Move bitmap in certain direction Android - java

Ok so I am working on a game in Android and right now I have a bitmap that I have drawn at the center of the screen. I can rotate the bitmap left and right by certain degrees using the Matrix class. The bitmap is a picture of a ship so when the user wants to move forward, I want the ship to move at the current angle that the ship is rotated at. Any ideas about how I should go about doing this?

Ok well with a bunch of trial and error and some reading up on trig I have managed to solve my own question. The vector that holds the current location of the ship has an X and a Y. What I then need to do, was based on the current rotation of the ship calculate a speed vector and then add that speed vector to the position vector.
speedX = (float) Math.sin(rotation*(Math.PI/180)) * speed;
speedY = (float) -Math.cos(rotation*(Math.PI/180)) * speed;
x += speedX;
y += speedY;
The rotation is in degrees so they needed to be converted to radians. Also speed is the actual speed of the ship and is applied to each speed vector. Hope that will help someone having the same problem.

Related

Rotating and drawing an image at a point in Java

I tried to post a different topic for this but people didn't really seem to understand what I was trying to do, so, now I've closed that one and opened this one to give more detail and rephrase the question as a whole.
Ok.
So basically, I have an application which draws an Ellipse. Now, I have a certain number of points (that can be random) in which I have to rotate an image and draw at.
Using Maths I know that to get a point on an Ellipse based by using an angle I use the following equation;
final int radiusW = (width / 2);
final int radiusH = (height / 2);
final int angle = 120;
int pointX = (int) (radiusW + (radiusW * Math.cos(Math.toRadians(angle))));
int pointY = (int) (radiusH + (radiusH * Math.sin(Math.toRadians(angle))));
And that works fine, I can locate an absolute point around the perimeter of the Ellipse.
However, now I'm trying to draw an image on this point so that the image is rotated facing the center of ellipse and is centered on the point.
So, to get the image rotated to the center of the point I do the following;
final AffineTransform at = new AffineTransform();
at.rotate(Math.toRadians(angle - 90), image.getWidth() / 2, image.getHeight() / 2);
final AffineTransformOp ato = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
And then I get my new rotated BufferedImage using;
BufferedImage rotated = ato.filter(image, null);
However, I can't seem to be able to get the central point of the image anymore.
If the angle was 0 so that the Image was the original direction then I would simply do;
graphics.drawImage(rotated, pointX - rotated.getWidth() / 2, pointY - rotated.getHeight() / 2, this);
However I'm not sure how to find the central point and draw it based upon that on a rotated image.
I know it involves using cos and sin to multiply the original pointX and pointY by the rotation matrix but everytime I try and work out a solution it always draws completely wrong.
Any help would be very much appreciated as I've spent the best part of a day trying to resolve this.
Thank you.
The thing is that if you just use sin and cos to rotate the corner of the image you will end up with the new rotated position of that corner - when actually what you want to find is the new width and height.
The center is width/2, height/2
Use this to calculate your new width and height:
Calculate Bounding box coordinates from a rotated rectangle
I have done this with OpenCV, and there the image have been rotated but the resulted image was having the same width and height as the initial on. The image was cropped if it was getting out of the initial dimentions and there were black pixels if no information (the rotated image has no pixels in that place).
If you think that rotated has more pixels than the initial image you can verify with size() or length(). Or you can play with the diagonals of the initial rectangle (image size): compute the projection of the diagonals and thake the greatest or what you think. But I am sure that it is similar to the OpenCV case.
I don't know if this can help you, but I hope so.
Your question is not entirely clear but it seems to me that you have a misunderstanding of the nature of the angle used to parametrise your ellipse. The angle as you have it is merely used to parametrise the form of an ellipse equation. It is not the same as the polar angle (except at particular angles). That is to say if you evaluate a point on your ellipse using an angle of (pi/4) radians (45 degrees), then measured the angle that the line from the ellipse centre to your point makes with the axis, it will not measure 45 degrees (except for the case where the ellipse is actually a circle).
That is to say that
int pointX = (int) (radiusW + (radiusW * Math.cos(Math.toRadians(angle))));
int pointY = (int) (radiusH + (radiusH * Math.sin(Math.toRadians(angle))));
is just a parametrisation of an ellipse and that angle is not a polar angle and treating this angle as a rotation angle will not give accurate results (except at integer multiples of (pi/2) radians)
It seems to me that you require the polar form of an ellipse relative to its centre in order for your code to make sense in the context of using this angle for rotation.
It is also possible that I have misunderstood your question though, in which case this answer will be downvoted on a grand scale and I will delete it.

Direction of a moving sprite

I'm doing a simple breakout game and I have some problem to understand how I should handle speed and direction of the ball to move it in different diagonal paths. I'm using this code in an update method:
xPos += xSpeed * direction;
yPos += ySpeed * direction;
If I use different vaules of xSpeed = 2 and YSpeed = 1 I can change to different diagonal paths, but I still want the same speed. If I increase value of xSpeed = 4 to get another diagonal path, then the speed is also increased, and I want the ball to move in the same speed. For the value of direction I use 1 or -1. But I guess it would be better to change the value of direction to get diagonal paths in degrees? In a breakout game the ball has to bounce back in the oppesite direction. I'm not good in math, so I would preciate some help to solve this. Any ideas how I can improve my code?
You could use sine and cosine functions to get the relative movement in x and y axis.
Like:
xPos += speed * Math.sin(movementAngle);
yPos += speed * Math.cos(movementAngle);
Using the above (polar coordinates) in various animations has the advantage of ease in modyfing direction or velocity of movement (which are speed and movementAngle variables respectively). When using cartesian coordinates (x and y position), change in either velocity or direction of movement would require non-obvious changes to both x and y.
Formulas in the solution above are nothing more than conversion from polar to cartesian coordinates.
Edit: to get the more "natural" behaviour, when movementAngle of 0 means moving right, PI/2 - up, PI - left and 3*PI/2 - right, use the following:
xPos += speed * Math.cos(-1*movementAngle);
yPos += speed * Math.sin(-1*movementAngle);

How to rotate a single image around a remote point

I'm developing a tube shooter-esque game in java that simulates 3D without actually using any 3D libraries. Right now I have a player-controlled ship that rotates around the center point of the screen, using (in this case, for moving right).
angle += 0.1;
x = Math.cos(angle) * radius + cX;
y = Math.sin(angle) * radius + cY;
Where angle is the placement in relation to the center point (ex. 270 is directly under the center), x and y are the current ship position, radius is the distance from the center, and cX and cY are the center point's location.
Right now revolving around the point works smoothly, but I'm not sure how to handle rotating the actual ship to always point towards the center. I've looked around a lot online but can't figure out how an individual Image (or if that doesn't work, an array of drawLines) can be rotated without affecting other objects on the screen.
Long story short, how would one go about rotating an individual Image to constantly point towards a remote x,y location?
What you need is the AffineTransform class which is basically a matrix class in java. Graphics2D has a draw image variant which accepts an AffineTransform instance:
boolean java.awt.Graphics2D.drawImage(Image img, AffineTransform xform, ImageObserver obs)
To create a transform, you can use 2D matrix operations:
AffineTransform trans = new AffineTransform();
trans.translate(x, y);
trans.rotate(theta);
trans.scale(scalex, scaley);
etc...
Mind that the order is important, probably you will want to scale first, rotate and then traslate the image to the corresponding location. It should do fine.
Java has uses some 3D power to draw as fast as it can, it is faster than a software renderer, but quite far from native opengl.

Rotating quaternions based on mouse movement (OpenGL and Java)

I'm writing a game in Java using OpenGL (the LWJGL binding, to be specific). Each entity, including the camera, has a quaternion that represents it's rotation. I've figured out how to apply the quaternion to the current OpenGL matrix and everything rotates just fine. The issue I'm having is getting the camera to rotate with the mouse.
Right now, every frame, the game grabs the amount that the mouse has moved on one axis, then it applies that amount onto the quaternion for the camera's rotation. Here is the code that rotates the quaternion, I'll post it since I think it's where the problem lies (although I'm always wrong about this sort of stuff):
public void rotateX(float amount){
Quaternion rot = new Quaternion(1.0f, 0.0f, 0.0f, (float)Math.toRadians(amount));
Quaternion.mul(rot, rotation, rotation);
rotation.normalise();
}
This method is supposed to rotate the quaternion around the X axis. 'rotation' is the quaternion representing the entity's rotation. 'amount' is the amount that I want to rotate the quaternion (aka the amount that the mouse was moved). 'rot' is a normalized vector along the X axis with a w value of the amount converted to radians (I guess the goal here is to give it an angle- say, 10 degrees- and have it rotate the quaternion along the given axis by that angle). Using Quaternion.mul takes the new quaternion, multiplies it by the rotation quaternion, and then stores the result as the rotation quaternion. I don't know if the normalization is necessary, since 'rot' is normal and 'rotation' should already by normalized.
The rotateY and rotateZ methods do the same thing, except for changing the vector for 'rot' (0.0, 1.0, 0.0 for y and 0.0, 0.0, 1.0 for z).
The code appears to work fine when the game starts and the camera is looking down the negative Z axis. You can spin all the way around on the Y axis OR all the way around the X axis. But as soon as you try to rotate the camera while not looking down the Z axis, everything gets really screwy (I can't even describe it, it rotates very oddly).
My end goal here is to have something to use for controlling a ship in a space with no up vector. So when you move the mouse on the Y axis, no matter what angle the ship is at, it changes the pitch of the ship (rotation along the X axis). Similarly, when you move the mouse on the X axis, it changes the yaw (rotation along the Y axis). I might be going about this the wrong way and I probably just need a push (or shove) in the right direction.
If you need more details on anything (how my rendering is done, any other maths that I'm trying to do) just ask and I'll put it up. I understood everything when I was using euler angles (which apparently are a big no-no for 3D application development... wish somebody would have told me that before I sunk a lot of time into getting them to work) but as soon as I switched over to quaternions, I got in over my head really fast. I've spent the past few months just playing with this code and reading about quaternions trying to get it to work, but I haven't really gotten anywhere at all :'(
Very, very frustrating... starting to regret trying to make something in 3D >_<
Quaternion rot = new Quaternion(1.0f, 0.0f, 0.0f, (float)Math.toRadians(amount));
OK, this is flat-out wrong.
The constructor that takes four floats assumes that they represent an actual quaternion. What you give that constructor is not a quaternion; it's a vec3 axis and an angle that you expect to rotate around.
You can't shove those into a quaternion class and expect to get a legitimate quaternion out of it.
Your quaternion class should have a constructor or some other means of creating a quaternion from an angle and an axis of rotation. But according to the documentation you linked to, it does not. So you have to do it yourself.
A quaternion is not a vec3 axis with a fourth value that is an angle. A unit quaternion representation a change in orientation is a vec3 that is the axis of rotation * the sine of half of the angle of rotation, and a scalar component that is the cosine of half the angle of rotation. This assumes that the angle of rotation is clamped on the range [-pi/2, pi/2].
Therefore, what you want is this:
float radHalfAngle = ... / 2.0; //See below
float sinVal = Math.Sin(radHalfAngle);
float cosVal = Math.Cos(radHalfAngle);
float xVal = 1.0f * sinVal;
float yVal = 0.0f * sinVal; //Here for completeness.
float zVal = 0.0f * sinVal; //Here for completeness.
Quaternion rot = new Quaternion(xVal, yVal, zVal, cosVal);
Also, converting amount to radians directly doesn't make sense, particularly so if amount is just a pixel-coordinate delta that the mouse moved. You need some kind of conversion scale between the distance the mouse moves and how much you want to rotate. And toRadians is not the kind of scale you want.
One more thing. Left-multiplying rot, as you do here, will perform a rotation about the camera space X axis. If you want a rotation about the world-space X axis, you need to right-multiply it.

Moving Objects Help

I want to know how is it possible,I could have an Object drawn at a certain point and move to the point that is touched on the screen. I am trying to use it for my game where when the user touches on the screen, the gun fires from the position of the player, but the player is stationary.
Thanks in advance.
P.S.
Is there a visual graphic of some sort that shows where every plot is on android.
I don't know what kind of library you're using to draw all of your things, but that basically doesn't matter since you only need to know two things in order to do this:
Without going into specifics on vector geometry:
1. You need to calculate the direction (x and y component) that the projectile moves in depending on your mouses position. You get this direction by simply subtracting the position of the mouse from the position of the player:
//x component of direction
float direction_x = mousePosition.x - playerPosition.x;
//y component of direction
float direction_y = mousePosition.y - playerPosition.y;
In order to just get a direction instead of adding a velocity component to this vector, you need to normalize it (so it has a length of 1):
float length =(float) Math.sqrt(direction_x*direction_x + direction_y*direction_y);
direction_x /= length;
direction_y /= length;
You then need to update the projectiles position by adding the direction_x and direction_y components to it, multiplied by the speed that you want the projectile to have (This process is called linear interpolation, by the way):
projectile_x += direction_x*speed;
projectile_y += direction_y*speed;
If you have some way of measuring the time between two frames, the speed variable should depend on the elapsed time between those frames, in order to create smooth movements on different platforms.

Categories

Resources