I got x and y (My position) and also destination.x and destination.y (where I want to get). This is not for homework, just for training.
So what I did already is
float x3 = x - destination.x;
float y3 = y - destination.y;
float angle = (float) Math.atan2(y3, x3);
float distance = (float) Math.hypot(x3, y3);
I got angle and distance but don't know how to make it move directly.
Please help!
Thanks!
Maybe using this will help
float vx = destination.x - x;
float vy = destination.y - y;
for (float t = 0.0; t < 1.0; t+= step) {
float next_point_x = x + vx*t;
float next_point_y = y + vy*t;
System.out.println(next_point_x + ", " + next_point_y);
}
Now you have the coordinates of the points on the line. Choose step to small enough according to your need.
To calculate the velocity from a given angle use this:
velx=(float)Math.cos((angle)*0.0174532925f)*speed;
vely=(float)Math.sin((angle)*0.0174532925f)*speed;
*speed=your speed :) (play with the number to see what is the right)
I recommend calculating the x and y components of your movement independently.
using trigonometric operations slows your program down significantly.
a simple solution for your problem would be:
float dx = targetX - positionX;
float dy = targetY - positionY;
positionX = positionX + dx;
positionY = positionY + dy;
in this code example, you calculate the x and y distance from your position to your target
and you move there in one step.
you can apply a time factor (<1) and do the calculation multiple times, to make it look like your object is moving.
Note that + and - are much faster than cos(), sin() etc.
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.
does anyone have any tips/ideas on how to calculate Round line joins?
The device I'm working on only supports single width lines.
I am trying to implement basic stroking with only round line joins.
Some things I'm messing with are below.
It's not much, but I hope to get some ideas on how to handle the different cases when two lines join, based on any replies.
Thanks in advance for any help.
I have had some progress with the outer join:
a. Get clockwise order vertices (I get these from flattened glyphs)
b. Grab 3 vertices
c. Compute normal of line A (prevX, prevY) -> (currentX, currentY)
d. Compute normal of line B (currentX, currentY) -> (nextX, nextY)
I compute normals using a left turn on the current clockwise vertices
normal = (deltaY, -deltaX) // Thanks Andreas
Vec2[] computeNormals(float prevX, float prevY, float x, float y, float nextX, float nextY) {
float dx1 = x - prevX;
float dy1 = y - prevY;
float dx2 = x - nextX;
float dy2 = y - nextY;
Vec2 normal1 = new Vec2(dy1, -dx1).normalize();
Vec2 normal2 = new Vec2(dy2, -dx2).normalize();
if (normal1.angleDeg() > normal2.angleDeg()) {
normal2.rot((float) Math.PI);
}
return (new Vec2[] { normal1, normal2 });
}
e. Determine outer join arc angle from atan2(deltaY, -deltaX)
void computeArc(VertexBuffer dest, float x, float y, float arcRadius, Vec2 normal1, Vec2 normal2) {
// Angle from Vecto2D is atan2(y, x)
float angleStart = normal1.angle();
float angleEnd = normal2.angle();
float angleInc = (float) Math.PI / 4f; // Temporary, need to find a way to determine numVertices for a Pen of a given width
while (angleStart > angleEnd) {
angleStart -= (float) (2f * Math.PI);
}
for (float a = angleStart; a <= angleEnd; a += angleInc) {
float vx = x + ((float) Math.cos(a) * arcRadius);
float vy = y + ((float) Math.sin(a) * arcRadius);
dest.addVertex(vx, vy);
}
}
If your device can draw filled circles, you could put a filled circle at the 2 end points, and one at every line joint.
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 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.
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.