0
\$\begingroup\$

I am developing a Java 2D video game. I am trying to write code to generate points for a line (actually a projectile path), at a specified angle, from a given start point. There seems to be something wrong with my Math. The points are to be used for moving a projectile from the top of the screen, towards the target (a submarine) which sits at the bottom.

I am suspicuous issue has to do with fact the origin of Java 2D coordinate system is 0,0 at top of the screen, not at bottom left for cartesian coordinate system. Note: I am not a Math person. So please excuse me if I am getting the terms wrong.

Here is what I am doing:

xloc, yloc - the initial location of the projectile I want to move towards the sub location

// Get slope of the line
float m= ((float)((int) yloc - subYcoord))/((int) xloc - subXcoord);

double radians= Math.atan(m);

double ycoord= yloc;
double xcoord= xloc;

int speed= 1;

// This is how I am attempting to generate the points for the path for the projectile to take

while (true) {

    xcoord += speed * Math.cos (radians);
    ycoord -= speed * Math.sin (radians);

    if (((int) ycoord)>= gunBaseYcoord) {

        break;
    }

    // WayPoints is my list of points to move the Projectile towards the sub at    bottom of the screen

    Point aPoint= new Point((int) xcoord, (int) ycoord);
    wayPoints.add(aPoint);
}

This does not seem to work for angles of 245 degrees.

As an example, if x,y are: 660, 35 (this would be my start point for the projectile), and subXcoord, subYcoord are: 169, 500

I get a slope of: -.947 (should be like: 245 degrees)

The radian is: -.758

I get degrees of: -43 (now this doesn't look right)

Appreciate any help with this! Thanks!

\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

Here's the vector based method Bruno Vieira Costa mentioned in the edit, in a bit more detail:

Given projectileX & projectileY, targetX & targetY, we can think of each of these as a vector (arrow) pointing from the origin of our space (0, 0) to the respective objects.

By subtracting the projectile position from the target position, we get a vector (arrow) pointing from the projectile to the target:

differenceX = targetX - projectileX
differenceY = targetY - projectileY

We can "normalize" this vector to a length of one (a so-called "unit vector") to express just the direction of travel (using Pythagorean Theorem):

distance = sqrt(differenceX * differenceX + differenceY * differenceY)
directionX = differenceX/distance
directionY = differenceY/distance

Then we can move at a given speed along this direction like so:

currentX += speed * directionX
currentY += speed * directionY

We can use the dot product to figure out whether two vectors are pointing in similar directions (>0), opposing directions (<0), or perpendicular (0), and use this to detect when we've passed our target

differenceX = targetX - currentX
differenceY = targetY - currentY

dot = differenceX * directionX + differenceY * directionY

if(dot <= 0)
   // The target is now behind us, we passed it! Stop drawing our line.

You can see there's a lot of redundancy in the lines above, repeating the same code for both X and Y. Generally a vector math library will let you perform addition/subtraction and various multiplication operations on vectors as a whole, so don't have a lot of separate x & y (and in 3D, z or even w) variables to manage yourself.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks so much for helping to fill in the blanks! You really saved the day! Really appreciate it! \$\endgroup\$ Commented May 6, 2017 at 17:46
0
\$\begingroup\$

The problem is that tan function is not injective in [-pi .. pi] interval. enter image description here

You should use atan2 instead. This function need 2 parameters: deltay and deltax enter image description here

edit:

Instead of using atan, you can only get the difference vector: (deltaX,deltaY) and normalize it and multiply by the speed you need.

\$\endgroup\$
5
  • \$\begingroup\$ Viera Costa - could you explain what I would need to do to normalize it? I read that the atan2() function calculates with respect to the x-axis (I assume 0,0?). I need it to calculate with respect to location of the submarine. How do I adjust the return value of atan2() to account for this? Thanks! \$\endgroup\$ Commented May 3, 2017 at 16:40
  • \$\begingroup\$ Viera Costa - I tried using the difference vector: double radians= Math.atan2(xloc - gunBaseXcoord, yloc - gunBaseYcoord); \$\endgroup\$ Commented May 3, 2017 at 19:30
  • \$\begingroup\$ Viera Costa- But the difference vector seems at times to return the wrong angle. \$\endgroup\$ Commented May 3, 2017 at 19:31
  • \$\begingroup\$ Ok, so don't use tan, and instead use vectors? Can you note a good resource to understand Vectors Math for Java? Have a learning curve here! Thanks! \$\endgroup\$ Commented May 3, 2017 at 22:20
  • \$\begingroup\$ It depends of your learning style, I'm visual, so I like videos like khan academy's linear algebra course. The good part is that you don't need any Java specific material for this subject, any math book can help you \$\endgroup\$ Commented May 4, 2017 at 12:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .