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\$
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\$
  • \$\begingroup\$ Thanks so much for helping to fill in the blanks! You really saved the day! Really appreciate it! \$\endgroup\$ – user1104028 May 6 '17 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\$
  • \$\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\$ – user1104028 May 3 '17 at 16:40
  • \$\begingroup\$ Viera Costa - I tried using the difference vector: double radians= Math.atan2(xloc - gunBaseXcoord, yloc - gunBaseYcoord); \$\endgroup\$ – user1104028 May 3 '17 at 19:30
  • \$\begingroup\$ Viera Costa- But the difference vector seems at times to return the wrong angle. \$\endgroup\$ – user1104028 May 3 '17 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\$ – user1104028 May 3 '17 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\$ – Bruno Vieira Costa May 4 '17 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.