I need to be able to move my player x and y pixels in the same direction as a point to a point. It's hard to explain, but this is what I am trying to do:
Angles 1 and 2 have to be the same. Point 1 stays the same at (100, 100), however point 2 constantly changes and so must the angles. I have tried this:
moveRectangle.setX(touchEvent.getX());
moveRectangle.setY(touchEvent.getY());
float theta = (float) Math.toDegrees(Math.atan2(touchEvent.getY() - 100,touchEvent.getY() - 100));
float velX = (float) (getSpeed() * Math.cos(theta));
float velY = (float) (getSpeed() * Math.sin(theta));
player.move(velX, velY);
The above code is constantly run when the user puts his finger on moveRectangle (Point 2) and moves it. But the above code does not work. The player just moves in one of two directions. player.move just adds velX and velY velocity. So how can I get the two angles and move the player in the right direction? Thanks.
Would it be easier to approach this problem using a cartesian approach (vectors) versus polar approach (angle and magnitude)? So, if the player is at point p0 and the "finger" is at point p1, then the direction the player should be moving v is given by the vector p1-p0. You can then scale the resulting vector v by the player's speed, and add the player's speed to his position. You can do this easily on a frame-by-frame basis.
Do you need just to know velocity on X and Y axis? You can do it without using trigonometry (just use Pythagorean theorem).
final float deltaX = touchEvent.getX() - player.x; // player.x is point1.x
final float deltaY = touchEvent.getY() - player.y; // player.y is point1.y
final float length = Maths.sqrt((deltaX)^2 + (deltaY)^2);
final float itterations = length / getSpeed();
final float velX = deltaX / itterations;
final float velY = deltaY / itterations;
player.move(velX, velY);
Or you need a code of player moving in cycle?
Remove Math.toDegrees().
From the Math.sin() / cos() Javadoc:
Parameters:
a - an angle, in radians.
Returns:
the sine of the argument.
Related
Okay. My problem is kinda mind-blowing. Let's say that I have a constructor which looks like this:
public Ball(Random r, float halfphonewidth, float halfphoneheight, float cx, float cy){
//te wartosci odpowiadaja za losowe polozenie i losowe wektory
x = (halfphonewidth-48)*0.1f;
y = (halfphoneheight-48)*0.1f;
vx = -0.2f + r.nextFloat();
vy = -0.2f + r.nextFloat();
Log.i("", "\n\n" + this.vx + " " +this.vy+"\n\n");
health = 3;
}
Now let's say that I have a step() method declared somewhere - it works. Step:
public void step(){
x += vx;
y += vy;
if(x<2f || x > 98f)
vx =- vx;
if(y<2f || y > 98f)
vy =- vy;
}
I have an onTouch event that listens and checks the 'click coords'. I catch them and pass to the constructor (float cx, float cy).
The first position of the ball is static - I set it permanently in the constructor and move by 48 pixels (cause of image size). It starts from the bottom-center and floats to the random direction + when it collides with a wall it reverses it's vx & vy.
So! I need to point the ball in a direction I click! :D
I tried by scaling screen w/h with coordinate system, tried with implementing Vector2D class (cause it's missing in the newest java I think) but im not that good with linear algebra, tried with trygonometry(even cyclometry) (but I may be blind).
Is there anyone that can point me a solution? Which is the best way and which should I try to implement?
You need to calculate the difference between the coordinates of the current position and the click position:
double xDiff = clickPoint.x - ball.x;
double yDiff = clickPoint.y - ball.y;
then you move the ball with a velocity proportional to that difference, in your case you have to set the vx and vy like:
vx = xDiff * n;
vy = yDiff * n;
where the bigger n is, the faster the ball will reach the target. You need to update the xDiff and yDiff variables as the ball move, so when the difference is 0 the movement will stop.
I'm trying to find the angle of a circle(2d) where I intersect with another (2d)object
I have a spaceship and a planet, I know what the X and Y coordinates are of both.
Now i need to know what the angle/degree is of the planet WHERE the spaceship intersected with the planet.
Thanks in advance.
,Cheers
Ozcan
If the origin is at (0, 0), the angle (in radians) would be calculated like this:
int deltaX = planet.centerX - spaceship.centerX;
int deltaY = planet.centerY - spaceship.centerY;
double radians = Math.atan2(deltaY, deltaX);
I'm working on some AI stuff in Java. When an entity moves towards a point, the movement does not look natural. If its starting point and target are not equal X and Y distances away from each other, the movement looks like this:
What I want it to look move like is this:
Currently, movement is done like so:
int tX = target.x;
int tY = target.y;
if(tX> oX){
getOwner().addX(getOwner().getMoveSpeed());
}
if(tX < oX){
getOwner().addX(-getOwner().getMoveSpeed());
}
if(tY> oY){
getOwner().addY(getOwner().getMoveSpeed());
}
if(tY< oY){
getOwner().addY(-getOwner().getMoveSpeed());
}
I'm guessing that there is a much better method for handling movement than this.
So what I want to know is probably how to work out the angle I need to move along, and then the x and y velocitys needed to do so.
You just need to scale the x and y speeds according to the total distance to be traveled in each direction.
It will help to do the calculations in floating point and round to an int only when you need to assign a position.
int tX = target.x;
int tY = target.y;
float speed = getOwner.getMoveSpeed();
float dX = tX - oX;
float dY = tY - oY;
float dist = Math.sqrt(dX * dX + dY * dY);
float sX = speed * dX / dist;
float sY = speed * dY / dist;
getOwner().addX((int) (sX + 0.5));
getOwner().addY((int) (sY + 0.5));
You're describing the process of drawing a line between two points.
There are relatively simple integer-only algorithms, such as Bresenham that may help.
I have this in the initialization of a bullet object:
x = startX;
y = startY;
double distance = Math.sqrt(((endX - x) ^ 2) + ((endY - y) ^ 2));
speedX = (6 * (endX - x)) / distance;
speedY = (6 * (endY - y)) / distance;
It goes to where I touch on the screen, but the further away I touch, the faster it goes. This works fine on paper, I've tried it with different lengths and it should work, but bullets need to move 6 pixels on the line from the player to the point touched every step. And its update method moves of course. But why do bullets move at different speeds?
If I remember my Java operators...
Replace
double distance = Math.sqrt(((endX - x) ^ 2) + ((endY - y) ^ 2));
with
double distance = Math.sqrt(Math.pow(endX - x, 2) + Math.pow(endY - y, 2));
Assuming that all measurements are in pixels and you want the speed to be 6 pixels per step, then you can calculate the velocity by using a little bit of trig:
double theta = Math.atan2(endY - startY, endX - startX);
velX = 6 * Math.cos(theta);
velY = 6 * Math.sin(theta);
Note that I am using the terms "speed" and "velocity" as a physicist would; speed is a scalar value and velocity is a vector with magnitude and direction.
Alright, so this is how I am doing it:
float xrot = 0;
float yrot = 0;
float zrot = 0;
Quaternion q = new Quaternion().fromRotationMatrix(player.model.getRotation());
if (q.getW() > 1) {
q.normalizeLocal();
}
float angle = (float) (2 * Math.acos(q.getW()));
double s = Math.sqrt(1-q.getW()*q.getW());
// test to avoid divide by zero, s is always positive due to sqrt
// if s close to zero then direction of axis not important
if (s < 0.001) {
// if it is important that axis is normalised then replace with x=1; y=z=0;
xrot = q.getXf();
yrot = q.getYf();
zrot = q.getZf();
// z = q.getZ();
} else {
xrot = (float) (q.getXf() / s); // normalise axis
yrot = (float) (q.getYf() / s);
zrot = (float) (q.getZf() / s);
}
But it doesn't seem to work when I try to put it into use:
player.model.addTranslation(xrot * player.speed, 0, zrot * player.speed);
AddTranslation takes 3 numbers to move my model by than many spaces (x, y, z), but hen I give it the numbers above it doesn't move the model in the direction it has been rotated (on the XZ plane)
Why isn't this working?
Edit: new code, though it's about 45 degrees off now.
Vector3 move = new Vector3();
move = player.model.getRotation().applyPost(new Vector3(1,0,0), move);
move.multiplyLocal(-player.speed);
player.model.addTranslation(move);
xrot, yrot, and zrot define the axis of the rotation specified by the quaternion. I don't think you want to be using them in your addTranslation() call...in general, that won't have anything to do with the direction of motion.
What I mean by that is: your 3-D object -- let's say for the sake of argument that it's an airplane -- will have a certain preferred direction of motion in its original coordinate
system. So if the original orientation has the center of mass at the origin, and the
propeller somewhere along the +X axis, the plane wants to fly in the +X direction.
Now you introduce some coordinate transformation that rotates the airplane into some other orientation. That rotation is described by a rotation matrix, or equivalently, by a
quaternion. Which way does the plane want to move after the rotation?
You could find
that by taking a unit vector in the +X direction: (1.0, 0.0, 0.0), then applying the
rotation matrix or quaternion to that vector to transform it into the new coordinate
system. (Then scale it by the speed, as you're doing above.) The X, Y, and Z components
of the transformed, scaled vector give the desired incremental motion along each axis. That transformed vector is generally not going to be the rotation axis of the quaternion, and I think that's probably your problem.