I am trying to move a Sprite along a straight line path. I want to move it 5 pixels on the slope, or the hypotenuse each time I go through the method until I reach the end point.
I have the slope and y-intercept of the line, I also have the current X and Y values of the sprite through getX() and getY(). The final X and Y points to stop at are variables finalX and finalY.
I have tried so many equations but I can't seem to get any of them to work. What am I missing!!?
My latest equation was trying to use y=mx+b.
float X = (getY() + 5 - interceptY)/slope;
float Y = slope*(getX() + 5) + interceptY;
setPosition(X, Y);
Can help you with a few equations from my recent game, the code moves an object given its rotation:
float xDirection = FloatMath.sin((float) Math.toRadians(getRotation()))
* currentSpeed;
float yDirection = FloatMath.cos((float) Math.toRadians(getRotation()))
* -currentSpeed;
float newX = getX() + xDirection;
float newY = getY() + yDirection;
You just need to derive the angle in which you need your sprite to move and this will do for you. Hope this helps.
Related
The following is a Processing sketch.
Dead centre coordinates are 0,0.
This means the far-left x coord is -250 and the far right x coord is 250. Similar dimension for y.
I want to move the mouse around the centre of the screen and have the relative coordinate appear on the radius, (i.e. mouse at coordinates 45,0 should mark point at 90,0).
The below code works but only for the right side of the screen, in short, angles up to 180. What is missing for this to work for the right hand side?
void draw(){
background(0);
fill(255);
stroke(255);
strokeWeight(5);
translate(width/2,height/2);
// mark center
point(0,0);
strokeWeight(12);
// mark mouse position (follow with point)
float x = mouseX - width/2;
float y = mouseY - height/2;
point(x,y);
// trace point on radius of circle same radius as width
float radius = width/2;
float sinAng = y/radius;
float cosAng = x/radius;
float m = sinAng/cosAng;
float angle = atan(m);
float boundaryX = cos(angle)*width/2;
float boundaryY = sin(angle)*height/2;
stroke(255,0,0);
point(boundaryX,boundaryY);
}
You're loosing the quadrant when calculating m...
-x/-y = x/y
Just correct the angle to the right quadrant by using the sign of x and y.
You can do this in fewer steps by using the atan2() function.
The atan2() function takes two parameters: the y distance between two points, and the x distance between two points, and it returns the angle between those points:
angle = atan2(y1-y0, x1-x0);
You can get rid of a few lines in your program by just doing this:
float x = mouseX - width/2;
float y = mouseY - height/2;
float angle = atan2(y, x);
float boundaryX = cos(angle)*width/2;
float boundaryY = sin(angle)*height/2;
No need to calculate the sinAng, cosAng, or m variables.
I have a Camera class that basically follows the player around the map and keeps him centered on the screen. The math im applying works great until the scale(Zooming in and OUt) of the camera is altered. Here it is:
x = -cell.x - cell.mass/2 + Game.width/2 / sX;
// Where x is the Camera's X, Cell is the Player and sX is the scale factor
I've been playing around with different equations but they all fail once the scale is altered. I can't seem to wrap my head around this and I could really use some insight on how to factor it in.
Here are some bits of the Camera Class:
public void set(Graphics bbg){
Graphics2D g2 = (Graphics2D)bbg;
g2.translate(x, y);
g2.scale(sX, sY);
}
public void unset(Graphics bbg){
Graphics2D g2 = (Graphics2D)bbg;
g2.translate(-x, -y);
}
public void scale(double sx, double sy){
sX = sx;
sY = sy;
}
public void Update(Cell cell){
scale(0.9,0.9);
x = -cell.x - cell.mass/2 + Game.width/2 / sX;
y = -cell.y - cell.mass/2 + Game.height/2 / sY;
}
public double toWorldX(int x){
return x - this.x / sX;
}
public double toWorldY(int y){
return y - this.y / sY;
}
The first image displays the result when the scale factor is 1(Normal Zoom). The second image displays the result when the scale factor is 0.9(Zoomed Out).
I'm having a little difficulty in determining what some of your variables mean (such as cell.mass, I'm assuming it is the size) and I assume that Game.width is the actual width of the window. It would help to know what EXACTLY happen when the zoom is changed (like is the "center" of the zoom at a particular corner of the screen).
Now for an answer, without know what happens to the actual zoom... have you tried the addition of parenthesis like this...
x = ((cell.x + cell.mass/2) - Game.width/2) / sX;
or (because you use '-' a lot, I'm not sure how your coordinates work)
x = ((-cell.x - cell.mass/2) + Game.width/2) / sX;
Just an idea.
The working equation for making the camera follow a player while factoring a scale factor is:
x =((cell.x + cell.mass * 0.5) - Game.width/sX * 0.5);
Is this implementation of the following formula correct? I'm having a hard time implementing certain formula into java:
Formula (Original)
Y(x,y,t)=A*cos(w *(x,y)+ wt*t + FI;
Formula (Java)
float yPos = (float) (A* Math.cos((w * (y) + w * (x)) + wt* t+ FI));
yPos is the y (up) position of a vector on a grid. And since the original formula appears to return a vector i simply applied it to y.
I have created a 3 dimensional grid that contains vertices. Each vertices position is changed in an update loop using a nested for loop:
for (int y = 0; y < sizeY; y++) {
for (int x = 0; x < sizeX; x++) {
float xPos = x;
float yPos = 0;
float zPos = y;
yPos += sineY(x, y, time); // Cant be consistant Waves
waterVertexPos.set(xPos, yPos, zPos); //y is where z is
vertBufArray[index++] = waterVertexPos.getX();
vertBufArray[index++] = waterVertexPos.getY();
vertBufArray[index++] = waterVertexPos.getZ();
}
}
The for loop changes the yposition of each vertex using the above formula:
float yPos = (float) (A* Math.cos((w * (y) + w * (x)) + wt* t+ FI));
The information for the Formula:
Amplitude of these waves (A): half of the length between wave crest to trough;
Wavelength (L): distance between two wave crests;
Spatial angular frequency (w): direction of spatial anglular frequency is the same
with the wave diffuse direction, and the quantity is
relative with the wavelength L: |w|=2*PI/L;
Speed of waves (s): distance of the waves moved in one second;
Temporal angular frequency (wt): wt=S*2*PI/L;
Direction of waves (D): the direction of the wave crests.
Initiatory phase (FI): the initiatory phase of waves;
EDIT:
using this formula gives me the following result:
Source:
http://lnu.diva-portal.org/smash/get/diva2:205412/FULLTEXT01
w is a vector, so you need two numbers wx and wy:
float yPos = A*Math.cos(wx*x + wy*y + wt*t+ FI);
Otherwise, all should be fine, just be sure to expand all vector / matrix expressions into arithmetic operations when you encounter those.
I need a way(in java) to calculate which direction my camera will move forward on the x and z axes based on the direction my camera is facing(yaw), and for y(the vertical axis), the pitch. I'm making my own game engine and my own camera.
With all values defaulting at zero, moving the camera correctly directs all movement along the positive z axis. However, when I pan the camera to the left or right(thereby changing the yaw), the camera still only moves along the z axis... So how do I calculate the change in direction to the x, y, and z axes?
The value range on the yaw is 0(south), 45(southwest), 90(west), 135(northwest), 180(north), 225(northeast), 270(east), 315(southeast), and back to 360(south, same as 0).
What I'm looking for with the compass directions(where a '+' or '-' indicates a change in value along that axis):
South = x, y, z+
SouthWest = x+, y, z+
West = x+, y, z
NorthWest = x+, y, z-
North = x, y, z-
NorthEast = x-, y, z-
East = x-, y, z
SouthEast = x-, y, z+
The value range on the pitch is 0.0(middle), 100.0(up all the way), and -100.0(down all the way).
If I need to post some code, I can, but it might get complicated. I hope I'm making some kind of sense so that someone can help me!
Suppose you want to move the camera in direction y with distance k.
For the sake of simplicity, i will convert your directions to angles, where 0.0 represents right, Pi/2 represents up, Pi represents left, 3*Pi/2 represents down and so.
EDIT: As you say y of camera will be affected only by the pitch. X and z, instead will be affected by both the yaw and the pitch.
You can calculate the new x, y and z by the following:
float y = // Yaw angle
float p = // Pitch angle
float k = // Move distance
float xzLength = cos(p) * k;
float dx = xzLength * cos(y);
float dz = xzLength * sin(y);
float dy = k * sin(p);
// Update your camera:
camera.x += dx;
camera.y += dy;
camera.z += dz;
Obviously, yaw and pitch do not change, so you don't need to update them.
I'm sorry if this question was asked before, I did search, and I did not find an answer.
My problem is, that I'd like to make movement on all 3 axes with the X and Y rotation of the camera being relevant.
This is what I did:
private static void fly(int addX, int addY){ //parameters are the direction change relative to the current rotation
float angleX = rotation.x + addX; //angle is basically the direction, into which we will be moving(when moving forward this is always the same as our actual rotation, therefore addX and addY would be 0, 0)
float angleY = rotation.y + addY;
float speed = (moveSpeed * 0.0002f) * delta;
float hypotenuse = speed; //the length that is SUPPOSED TO BE moved overall on all 3 axes
/* Y-Z side*/
//Hypotenuse, Adjacent and Opposite side lengths of a triangle on the Y-Z side
//The point where the Hypotenuse and the Adjacent meet is where the player currently is.
//OppYZ is the opposite of this triangle, which is the ammount that should be moved on the Y axis.
//the Adjacent is not used, don't get confused by it. I just put it there, so it looks nicer.
float HypYZ = speed;
float AdjYZ = (float) (HypYZ * Math.cos(Math.toRadians(angleX))); //adjacent is on the Z axis
float OppYZ = (float) (HypYZ * Math.sin(Math.toRadians(angleX))); //opposite is on the Y axis
/* X-Z side*/
//Side lengths of a triangle on the Y-Z side
//The point where the Hypotenuse and the Adjacent meet is where the player currently is.
float HypXZ = speed;
float AdjXZ = (float) (HypXZ * Math.cos(Math.toRadians(angleY))); //on X
float OppXZ = (float) (HypXZ * Math.sin(Math.toRadians(angleY))); //on Z
position.x += AdjXZ;
position.y += OppYZ;
position.z += OppXZ;
}
I only implement this method when moving forwards(parameters: 0, 90) or backwards(params: 180, 270), since movement can't happen on the Y axis while going sideways, since you don't rotate on the Z axis. ( the method for going sideways(strafing) works just fine, so I won't add that.)
the problem is that when I look 90 degrees up or -90 down and then move forward I should be moving only on the Y axis(vertically) but for some reason I also move forwards(which means on the Z axis, as the X axis is the strafing).
I do realize that movement speed this way is not constant. If you have a solution for that, I'd gladly accept it as well.
I think your error lies in the fact that you don't fully project your distance (your quantity of movement hypothenuse) on your horizontal plane and vertical one.
In other words, whatever the chosen direction, what you are doing right now is moving your point of hypothenuse in the horizontal plane X-Z, even though you already move it of a portion of hypothenuse in the vertical direction Y.
What you probably want to do is moving your point of a hypothenuse quantity as a total.
So you have to evaluate how much of the movement takes place in the horizontal plane and how much in the vertical axis. Your direction gives you the answer.
Now, it is not clear to me right now what your 2 angles represent. I highly recommend you to use Tait–Bryan angles in this situation (using only yawn and pitch, since you don't seem to need the rolling - what you call the Z-rotation), to simplify the calculations.
In this configuration, the yawn angle would be apparently similar to your definition of your angleY, while the pitch angle would be the angle between the horizontal plane and your hypothenuse vector (and not the angle of the projection in the plane Y-Z).
A schema to clarify:
With :
s your quantity of movement from your initial position P_0 to P_1 (hypothenuse)
a_y the yawn angle and a_p the pitch one
D_x, D_y, D_z the displacements for each axis (to be added to position, ie AdjXZ, OppYZ and OppXZ)
So if you look at this representation, you can see that your triangle in X-Z doesn't have s as hypotenuse but its projection s_xz. The evaluation of this distance is quite straightforward: if you place yourself in the triangle P_0 P_1 P_1xz, you can see that s_xz = s * cos(a_p). Which gives you:
float HypXZ = speed * Math.cos(Math.toRadians(angleP))); // s_xz
float AdjXZ = (float) (HypXZ * Math.cos(Math.toRadians(angleY))); // D_x
float OppXZ = (float) (HypXZ * Math.sin(Math.toRadians(angleY))); // D_z
As for D_y ie OppYZ, place yourself in the triangle P_0 P_1 P_1xz again, and you'll obtain:
float OppYZ = (float) (speed * Math.sin(Math.toRadians(angleP))); // D_y
Now, if by angleX you actually meant the angle of elevation as I suppose you did, then angleP = angleX and HypXZ = AdjYZ in your code.
With this correction, if angleX = 90 or angleX = -90, then
HypXZ = speed * cos(angleX) = speed * cos(90deg) = speed * 0;
... and thus AdjXZ = 0 and OppXZ = 0. No movement in the horizontal plane.
Note:
To check if your calculations are correct, you can verify if you actually move your point of the wanted quantity of movement (hypothenuse ie speed ie s). Using Pythagorean theorem:
s² = s_xz² + D_z² // Applied in the triangle P_0 P_1 P_1xz
= D_x² + D_y² + D_z² // Applied in the triangle P_0 P_1x P_1xz
With the definitions of the displacements given above:
D_x² + D_y² + D_z²
= (s * cos(a_p) * cos(a_y))² + (s * cos(a_p) * sin(a_y))² + (s * sin(a_p))²
= s² * (cos(a_p)² * cos(a_y)² + cos(a_p)² * sin(a_y)² + sin(a_p)²)
= s² * (cos(a_p)² * (cos(a_y)² + sin(a_y)²) + sin(a_p)²)
= s² * (cos(a_p)² * 1 + sin(a_p)²)
= s² * (cos(a_p)² + sin(a_p)²)
= s² * 1 // Correct
Hope it helped... Bye!