I'm writing a game of sorts to practice some programming, and i've come across this problem. In my game, there are circles on the screen. And when the user clicks on the screen, the circles should move away from the click. I've got the x and y position of the point where the mouse button was pressed, and i have the x and y position of each cicle object.
I found the center of the circles with the following code
float cx = circle.getX()+circle.getRadius();
float cy = circle.getY()+circle.getRadius();
And to find the distance from the edge of the circle to the mouse click I did this
float distance = (float) Math.sqrt( ((cx-x)*(cx-x)) + ((cy-y)*(cy-y)) ) - circle.getRadius();
Now after I check if the circle is close enough to the click, how can I split a velocity of 1f, for example, to the circle's variables vx and vy?
EDIT: Well actually I wanted acceleration, but I guess it's all the same.
This sounds like a job for sin and cos in java.lang.Math : http://download.oracle.com/javase/6/docs/api/java/lang/Math.html .
Once you know the total velocity (1f in your example above) and the angle (in radians), the horizontal component of the velocity is v * cos(angle), and the vertical component is v * sin(angle).
You probably need to negate the angle if you want to move it away.
To calculate an angle from horizontal and vertical distances, use atan2.
Btw, if you don't want to take unnecessary square roots, and want to avoid the cost of computing series the way trigenometric functions do, take a look at http://www.youtube.com/user/njwildberger#p/u/368/9wd0i44vK04 .
Find the line from the mouse to the center of the circle and that should be the "force" vector. This vector will give you the direction, now you just need to figure out how distance affects the magnitude.
You could first find angle as Mike suggested and use cos and sin functions.
Or use:
velHoriz = velocity * (cx-x) / distance
velVert = velocity * (cy-y) / distance
Related
I followed an online tutorial, I did not understand how the professor managed to get the distance of a circle from the top left corner of the screen:
//calculate the distance from epicenter (of a circle) to the top left corner of the screen
double theta = atan(epicenter.dy/epicenter.dx);
double distanceToCorner = epicenter.dy / sin(theta);
I would like to know how to get the distance from all the other screen corners (and possibly have an explanation of what has been done).
Thank you
Assuming, that in android you can get screen width and height, you can simply count the distance at horizontal and vertical axis separately.
Getting the distances at those axes, you can use Pythagoras equation, like
dist = sqrt( dx^2 * dy^2 )
To make it more felxible, just make a function, that takes corner position as a parameter and make the dx and dy as a absolute difference of corner and epicenter location.
Going back to your question and atan(...), I don't quite understand the need of using this here, except if that's a project for the math class :)
I know this is not the answer but if i understand what you mean, then this image might be helpful.
I am making a 3D game in which the player can rotate their view point via the mouse to look around the environment. I firstly just did x and y rotation via vertical and horizontal movement of the mouse and z via another control. But after playing the game I realised it did not rotate correctly. NOTE: I have a global variable matrix which represents the player's angle (3x1), at 0,0,0 it seems to work correctly as up or down is a direct x axis rotation and right or left is a direct y axis rotation, but if I move my camera diagonally for example then left doesn't directly correlate to a y axis rotation anymore.
Visually on a unit circle the players viewpoint wouldn't travel the full circumference anymore and would travel in a circle that is smaller that the circumference. This is the current code (x and yRateOfRot is the ratio of how far away from the centre the cursor is in each direction between -1 and 1):
private static void changeRotation(){
angle.set(Matrix.add(angle.matrix,new double[][]{
{ROTATION_SPEED * camera.xRateOfRot()},
{ROTATION_SPEED * camera.yRateOfRot()},
{ROTATION_SPEED * camera.zRateOfRot()}}));
}
I have looked at this source http://paulbourke.net/geometry/rotate/ and understand how to rotate via an arbitrary axis which I could do but I am not sure how to correlate this into getting a ratio to find out what the x,y and z change would be for looking in a specific direction i.e. at 0,0,0 the ratio of looking up would be x:1, y:0, z:0 but then at another angle the ratios would be different as looking up no longer means only an x rotation. Any information would be appreciated, thanks!
I'm trying to make a ball bounce around a window. Depending on how far away the ball hits the wall and at what angle will determine its reflection. You can see in the pic that the black trajectory hits the opposite wall on the inner half... and the gray trajectory represents if it were to reflect and hit the other half... which would decrease the angle of reflection.
I'm not sure if I'm thinking about it correctly... I'm trying to put the coordinates in terms of degrees.
So given the pic... You would take those deltas, then get degrees...
degree = Math.atan2(opposite/adjacent) = (-4/-2)
My code
public class Calculate {
public Calculate() {
System.out.println(getCalc(7,5,4,0));
}
public double getCalc(int x1, int x2, int y1, int y2) {
double deltaX = Math.abs(x2-x1);
double deltaY = Math.abs(y2-y1);
double degrees = Math.toDegrees((java.lang.Math.atan2(deltaX, deltaY)));
return degrees;
}
}
Gives the output: 26.56505117707799
So now I know the ball would reflect off the wall at 26 degrees (since that's the angle of incidence). But I don't want the ball to necessarily reflect uniformly off each wall so it adds variability.
My questions:
Am I calculating the angle of the ball correctly?
How can I add variability to the bounce based on where it hits on the wall?
Once I have the angle in degrees, how can I translate that back to coordinates?
Thank you!
Am I calculating the angle of the ball correctly?
Your drawing is not to scale. The 26 degrees is measured from a line perpendicular to the wall.
How can I add variability to the bounce based on where it hits on the wall?
You already suggested a random angle. You can also adjust the angle of reflection based on the distance from the center of the wall.
Put your angle of reflection calculation into its own method. You can adjust the calculation until your calculations give you the "randomness" you're looking for.
Once I have the angle in degrees, how can I translate that back to coordinates?
Convert the degrees to radians, then calculate the SAS of the triangle. Just leave your angles in radians in the model, and convert to degrees in your display / diagnostic methods.
I think that the distance of the ball from the surface doesn't really have an effect on the angle. The angle of the ball before hitting the surface should be the same (mirror reflected) when it leaves the surface for it to be natural.
You can add some variability by thinking what happens to a rubber ball, since it changes a little on impact depending on the force etc., the reflection is not exactly the same every time. You could simply add or remove a degree or two randomly and see how it goes.
Once you have an angle, its once again down to trigonometry. You have an angle, and you know the hypotenuse (I presume depending on your frame-rate and ball speed the ball would have travelled a certain amount from the surface). So from that you need to get the adjacent and opposite lines of the triangle.
For example:
sin(angle) * hypothenuse = opposite (so Y offset from the surface).
cos(angle) * hypothenuse = adjacent (so X offset from the point of contact).
Just add or remove (depending on the direction) the adjacent and opposite values from the coordinates of the contact point.
If you want to make it seem a little random, you could model spin somewhat--it doesn't have to be too complicated.
If it was not spinning and hit a wall at a 45 degree angle, it would impart a spin to the ball. When it hit the next wall, the spin would added to the angle and the spin would be increased (or decreased) by the angle. I think the spin/angle combination would also effect the speed at which it came off the wall (Just visualizing real-life situations)
That would make it vary without it being truly random--but I don't know how it would actually look--you may have to apply other restrictions (I think that there must be a way to limit the max spin).
I bet there is a simple physics book around that could give enough to model this without going too deep into the math if you didn't just want to make up rules.
if i make an ellipse bounded by a rectangle. how can i rotate it ? as in if i have rx,ry,cx,cy,topleft x,toplefy, bottomrightx,bottomrighty
iused the formula
angle=taninverse(ry/rx)
and i keep adding the angle that is angle=angle + taninverse(ry/rx)
the angle is too small to see the difference.
please provide another formula to calctulate teh angle with the given parmeteres
to have a look at the ellipse with the bounded rectangle frame
http://svg-edit.googlecode.com/svn/branches/2.5.1/editor/svg-editor.html
Have you tried rotating by a larger angle to see what happens? Do the values of rx and ry change?
If not, you probably should compute 'atan(ry/rx)' and store the result in a variable like so:
double delta = Math.atan(ry / rx);
Then when you rotate
angle += delta; // or angle = angle + delta --- these are equivalent
Alternatively, rather than calculating the angle from ry and rx, you may wish to simply keep a value such as
double delta = Math.PI / 6;
This simply gives the angle to rotate through without a calculation. The advantage is that you can simply set this delta variable to any value you wish, large or small. As above, you can increment angle by this delta value.
There are some animation classes in Android. The package android.animation is available since API 11 and provides the ability animate object properties. android.view.animation is available from API 1 and provides animations for resizing, moving, and rotating. Both also offer XML attributes so you can also set you animation in XML. The main classes to check out are android.view.animation.Animation and android.animation.Animator.
Alright, so I got two angles. One is the joystick's angle, and the other is the camera to player angle. The camera's angle. Now I want it so when I press up on the joystick it moves the player away from the camera. How would I do this? And is there a easy way to do it in Java or Ardor3d?
edit: Here is the code of how I get my angles.
float camDegree = (float) Math.toDegrees(Math.atan2(
_canvas.getCanvasRenderer().getCamera().getLocation().getXf() - colladaNode.getTranslation().getXf(),
_canvas.getCanvasRenderer().getCamera().getLocation().getYf()) - colladaNode.getTranslation().getYf());
player.angle = (float) Math.toDegrees(Math.atan2(padX, padY));
Quaternion camQ = new Quaternion().fromAngleAxis(camDegree, Vector3.UNIT_Y);
I have to say that I don't really understand your question, but it seems to be about how to implement camera-relative control using a joystick.
The most important piece of advice I can give you is that it's better not to compute angles, but to work directly with vectors.
Suppose that the camera is looking in the direction v (in some types of game this vector will be pointing directly at the player, but not all types of game, and not always):
Typically you don't care about the vertical component of this vector, so remove it to get the horizontal component, which I'll call y for reasons that will become apparent later:
y = v − (v · up) up
where up is a unit vector pointing vertically upwards.
We can find the horizontal vector that's perpendicular to y using the cross product (and remembering the right hand rule):
x = v × up
Now you can see that y is a vector in the plane pointing forwards (away from the camera), and x a vector in the plane pointing right (sideway with respect to the camera). If you normalise these vectors:
x̂ = x / |x|
ŷ = y / |y|
then you can use x̂ and ŷ as the coordinate basis for camera-relative motion of the player. If your joystick readings are Jx and Jy, then move the player by
s (Jx x̂ + Jy ŷ)
where s is an appropriate scalar value proportional to the player's speed.
(Notice that no angles were computed at any point in this answer!)