how to use atan2 in my android game - java

I am making a side scroller shooting game. I currently have my character shooting horizontally to the right. I would like to get him shoot anywhere on the screen.
I understand that I should use atan2 to figure what angle my bullet will be shot at but I am confuse how to implement it into my game.
My question is how do I call my coordinates of the touch on the screen into atan2? Do I place this in my touch command codes or the class for my projectile. Lastly do I need to do another atan2 for speed?

First you need the vector of your player
P = (a, b)
And the position of your shooting point
T = (x, y)
This then gives us a vector from P to T, (x - a, y - b). By taking
angle = atan2 (y-b, x-a)
From there, it depends how you are implementing your shooting.
To reiterate, all atan2 does is finds the angle, so
do I need to do another atan2 for speed
depends on whether you want to have the projectile moving at a different speed depending on angle. In fact, you only really need the angle if you are rotating your projectile, otherwise you can just move it along the vector (if it is a circle, doesn't matter what way it is facing!)

You don't need any trigonometry and you should not use it, as it is slow, inaccurate and full of sign (+/-) cases to get wrong.
You can probably do everything you need with linear algebra. Use vectors, not angles.

Related

Determining IF & WHERE a line intersects with a 2D plane (in 3D space)

The following problem im working on is for one of my favorite past-times: game development.
Problem:
We're in 3D space. I'm trying to determine if a line between two vectors in said space is passing through a circle; the latter of which consists of: center vector, radius, yaw & pitch.
In order to determine that, my aim is to convert the circle to a plane which can either be infinite or just have the diameter of the circle for all it's sides.
Should the line between the two vectors in fact pass through that plane, i am left with the simple task of determining wether that intersection point is within the radius of the circle, in which case i can return either true or false.
What's already working:
I have my circles set up and the general framework is there. The circles are appearing/rendered in the 3D space exactly as specified, great!
What was already tried:
Copied some github gist codes and tried to make them work for my purposes. I kinda worked, sometimes at least. Unfortunately due to the nature of how the code was written, i had no idea what it was doing and just scrapped all of that.
Researched the topic a lot, too. But due to me not really understanding the language people speak when talking about line/plane intersections, i could have read the answer without recognizing it as such.
Question:
I'm stuck at line intersections. No idea where to go and how it works logically! So, where do i go from here and how can one comprehend all of this?
Note:
I did tag this issue as "java", but i'm not looking for spoon-fed code. It's a logical issue i'm trying to get past. If explained well enough, i will make the code work with trial and error!
Say if your circle is a circle in the XY plane with its centre on (0,0,0) and radius 1. How would you solve that?
You would check the values of X and Y when Z is equal to zero. And X squared plus Y squared would be less than 1 (radius squared) if the line passes through the circle.
In other words, you could transform the 3D coordinates to a simpler reference frame. So I think you need to learn transformation of 3D coordinates, which is really not too hard to do. You need to rotate the 3D space around until the centre vector only has a Z component, and yaw and pitch are zero. And then offset the coordinates so the circle centre is in (0, 0, 0). Then apply the same transformation to the line. You could lastly scale by radius, but to be honest that is not so important since the circle math is easy.

How to determine the distance from an obstacle without knowing its location

I am writing a code where I have a world filled with various obstacles (of rectangular shapes). My robot which is a circle, originates randomly at any place inside the world. I assume that it has a range sensor on its head and want to get the distance between the nearest obstacle/boundary wall which is in its straight line of view.
I am using a random orientation between 0 and 360 degrees to orient the robot and use sin and cos of orientation to move the robot in the same orientation. But how can I get the distance between any obstacle or the boundary wall along this orientation? It should be able to tell me the distance of the first object it encounters in its vision which would be an angle from 0 to 360.
Please provide me a hint of logic how to encounter this issue?
Thanks
Assuming you know the angle, the robot's position and the position of all the obstacles, you could have a function like this:
if the angle if less than 90 or greater than 270 you increment the x coordinate by 1, otherwise you decrement by 1
you make a for loop from the current x coordinate until the edge of the world (I don't know how you have the world implemented), scanning for any obstacles at position (x, x*tan(angle)), incrementing or decrementing in accordance with the step above
the first obstacle you run across, return sqrt(x^2 + (x*tan(angle))^2) - that's just the pythagorean theorem
Here's what i think you could do.
In real game development, they uses a lot of optimization tricks, often giving approximates for better performances.
Also note that there's a lot of libraries out there for game development, that probably could get you what you want a lot simplified.
But anyway, here's what i'ld do.
identify object you'd pass through if you go straight forward.
identify the nearest one, in the list of objects you just made.
1:
A)
make a formula for your position/angle in the form y = mx + b
[y = tan(angle)x + (positionY - (tan(angle)*x))]
B)
for each object, divide the object in multiple lines segments (2 points).
check if the segment crosses the line made by the formula in point A
(if a point is smaller and the other is greater than the same X value in the formula, it's crossing)
do the same thing for your world boundaries
2: This part is more tricky (to do in programmation).
Next, you have to find the position where your robot orientation formula intersect
with all the lines you previously identified.
For each line, you must again turn the line into a y=mx+b
Let say we have:
y=3x+5 and
y=5x+1
3x+5 = 5x+1
3x-5x = 1-5
-2x = -4
x = 2
Then you replace x with 2 in either formula, you'll get the intersection point:
y = 3(2)+5 = 11
y = 5(2)+1 = 11
So these two lines intersect on point (2, 11)
Next you have to see if that point is in the domain of you're robot path formula.
Since your robot is looking at a single direction, and the formula we made in point 1.A is infinite in both directions, you must ensure the line intersection you found is not in the back of your robot (unless he moves backward...)
I guess you can make it simple, look at cos(angle) signs, then look at the position of the intersection point, if it's to the left of your robot, and cos(angle) is negative it's fine.
Finally,
Once you found ALL the intersect point, you can find the nearest one by using the Pythagorean theorem sqrt((x1-x2)^2 + (y1-y2)^2)
Also, note that it won't work for 90 and 270 angles, since tan(90) doesn't exists.
In that case, just look if both points of the segments are at both side of your robot, and the intersect point is in the right direction, it means you pass through it.
Again, there's a lot of place for optimization.

Determine which java 2d Rectangle edge (top/left/etc) an angle points to (from center)

I have two Rectangles (call them A and B) on a game map and I've calculated the angle from the center of B to A. I have code that spawns a third (C) and "shoots" it from B to A. The problem is that in my game, two of these game elements should never overlap (they have collision code normally) so the "shooting" code is stopped - spawning C on top doesn't work logistically.
My solution (tell me if there's a better one) is to spawn the third rectangle next to the edge of the parent - but for the UI to function properly, it needs to always spawn off the edge of the parent that faces rectangle A.
I know the center coordinates for rectangle B, I know the angle (can be in radians or degrees) from B to A, how can I determine which side (left, top, right, bottom) the angle would point at?
Think of the square lying on the unit circle with its center at the origin. Then figure out if Java behaves like JavaScript which is backwards from standard trigenometry. (pi/2 is straight down in JS whereas it is straight up in standard trig). Rectangle objects also have boundary and intersection methods which may help.
The graphic a little down this page may help: http://en.wikipedia.org/wiki/Unit_circle
When I've written games with collision engines like this, and needed projectile launching behavior, there's been a couple different approaches I've taken.
First, I've maintained a reference to the entity that fired the projectile. Then in the collision detection method, I've compared against this reference.
Another option, which may be preferable, is to instead associate the entities to a "Faction". This could be modeled as an enum. Then the collision detection code could check to ensure the two entities are not in the same faction. You could also use a mapping to determine which factions collide with each other. For instance, you could have "Hostile", "Neutral", and "Player" factions and have the player faction entities not collide with Neutral, etc. It would depend on the "business rules" of your game.
If you do this, you can spawn the projectile anywhere you want.
Supposing that angle is the angle from center of B to center of A, given in radians in the interval -pi..pi, then the following should do what you want (remember that like #Jared suggested, positive angles are down rather than up):
double halfPi = Math.PI/2;
double theta = Math.atan2(B.height, B.width);
if (angle >= theta+halfPi || angle <= -theta-halfPi) {
// left side
} else if (angle >= theta) {
// bottom side
} else if (angle >= -theta) {
// right side
} else {
// top side
}

Math For Pong Game

Lets say I have an angle... what would be a reasonable way to go about finding the next point of where the ball would be?
Variables: bSpeed, bAngle, Ball.x, Ball.y
You knwon when you do c^2 = a^2 + b^2... is there a way you could find how long c^2 could be and actually "draw" it out and then use speed to go only part of that... with that find a^2 and b^2 so you can actually have a x and a y to draw the ball...
Thanks ahead of time! (BTW, I don't need code... just reasoning and wisdom)
Your 4 variables are effectively a vector - where the vector is a measure of both direction and magnitude/velocity (i.e. what you've represented as bSpeed and bAngle). Using this representation means that Ball.x and Ball.y simply become the horizontal and vertical components of the vector.
Given a vector called v1 we can calculate the movement in the x and y axis as follows...
xVelocityOfBall = v1.magnitude * cos(v1.angle);
yVelocityOfBall = v1.magnitude * sin(v1.angle);
GPWiki (Games Programming Wiki) is a great resource for anything maths/physics for games development. Here's a handy link to their vector page
delta_x = speed*cos(angle)
delta_y = speed*sin(angle)
new_x = x+delta_x
new_y = y+delta_y
and then you need just change speed and angle of ball in the case of wall strike)
Open up your textbooks on Sin, Cos and Tan since you're using bAngle. Specifically you'll probably be looking Sin for the vertical motion and Cos for the horizontal motion. Depending on where you've defined degree 0 to face.
Also, you could consider caching the horizontal and vertical speeds since Sin and Cos are expensive
You probably will need to consider the physics of the movement that the pong player is moving also. For example, if a player's paddle is speeding to the left as it contacts the ball, the ball will need to speed up wrt to the left direction. This represents transfer of momentum in physics. The general system of equations in the x and y directions will always be:
mass*velocity (in x) = the sum of the mass*velocity of all objects in x
mass*velocity (in y) = the sum of the mass*velocity of all objects in y
generally speaking sine you always have the speed of the ball in x and y all you need to do is determine the masses of both the ball and the paddles (i suppose that's up to you but I suggest making them the same for ease of calculation).
In terms of solving for the angle, it's very simple, you would just make sure the reflection is equal. If the ball is approaching a paddle (or wall) from a 60 degree incident, then the bounce should also be at a 60 degree incident.
First, convert the angle to a vector using the sin and cos functions. This tells you the relative x-speed and y-speed of the ball. Then, to find out how far the ball actually went, multiply these numbers by the ball's speed and time-of-flight. Finally, add to the ball's starting position. This gives you the ball's ending position.
In a pong game, the ball may hit an object, in which case you need to correct for the change in velocity.

Java: moving ball with angle?

I have started to learn game physics and I am trying to move a ball with an angle. But it does not change its angle. Java coordinate system is a little different and I think my problem is there. Here is my code.
This is for calculating x and y speed:
scale_X= Math.sin(angle);
scale_Y=Math.cos(angle);
velosity_X=(speed*scale_X);
velosity_Y=(speed*scale_Y);
This is for moving ball in run() function:
ball.posX =ball.posX+(int)velosity_X;
ball.posY=ball.posY+(int)velosity_Y;
I used (int)velosity_X and (int)velosity_Y because in ball class I draw object
g.drawOval(posX, posX, width, height);
and here g.drawOval requires int. I dont know if it is a problem or not. Also if I use angle 30 it goes +X and +Y but if I use angle 35 it goes -X and -Y. I did not figure out how to work coordinate system in Java.
Math.sin() and Math.cos() expect the angle in radians. You should transform your angles to radians (angle*Math.PI/180).
Use Math#toRadians()
scale_X = Math.sin(Math.toRadians(angle));
scale_Y = Math.cos(Math.toRadians(angle));
Check your types. You probably want everything to be floats because your scale variables are going to be less than one, greater than zero. If they are multiplied by ints, there is a good chance you will end up converting to a 1 or 0 all the time. I'm not completely sure of this, I'd code up a few simple equations to make sure (rather than memorize all the rules) if I were you.
One way to do it is to downcast your floats (or doubles) to int at the last possible moment (when you need to pass the values to a method call). This is a little bit of an overkill but doesn't hurt anything but CPU that you aren't using anyway--and may prevent bugs.

Categories