1
votes

I know this isn't a hard trig issue, but sadly I am math retarded.

I need to draw a line of 50 pixels from a known starting point along a known angle to an unknown ending point. The angle is derived from a starting point (400,400) and a mouse click; the line needs to be drawn towards the mouse click, but only 50 pixels towards the click.

I've google'd extensively and found a number of solutions, but it's just not coming together for me.

Here is how I'm getting the angle.:

float angle = (float) Math.toDegrees(Math.atan2(400 - event.getY(), 400 - event.getX()));
float angleInDegrees = (angle + 270) % 360;

"event" is a mouse click.

float endX = 250 + 50 * (float)Math.cos(angleInDegrees);
float endY 250 + 50 * (float)Math.sin(angleInDegrees);

line.setStartX(400);
line.setStartY(400);
line.setEndX(endX);
line.setEndY(endY);

Everything I've found revolved around Math.cos and Math.sin but I'm still not getting it. I think the issue is related to mapping radians to scene coordinates, but I'm not sure. So people, in what way am I stupid? I'd appreciate any help.

3

3 Answers

5
votes

I wouldn't bother with angles. You can do this just using ratios:

int startX = 400;
int startY = 400;
int dx = event.getX() - startX;
int dy = event.getY() - startY;
float distToTarget = Math.sqrt(dx * dx + dy * dy);
float ratio = 50 / distToTarget;
int endX = startX + Math.round(ratio * dx);
int endY = startY + Math.round(ratio * dy);

Then draw from (startX, startY) to (endX, endY).

Here's what's going on:

  1. compute the vector that goes from (400, 400) to the mouse click (this is (dx, dy))
  2. scale the vector so it is 50 pixels long
  3. round the scaled vector so it has integer length in x and y
  4. add the scaled, rounded vector to (400, 400) to compute the end point
3
votes

You don't even have to deal with radians/degrees. Go back to the geometrical definition of sine and cosine: sine is opposite/hypotenuse, cosine is adjacent/hypotenuse. ("Opposite" and "adjacent" mean the legs of the right triangle respectively opposite and adjacent to the angle you're taking the sine or cosine of).

So:

float opposite = event.getY() - 400;
float adjacent = event.getX() - 400;
float hypotenuse = Math.sqrt(opposite*opposite + adjacent*adjacent);

float cosine = adjacent/hypotenuse;
float sine = opposite/hypotenuse;

float endX = 400 + 50 * cosine;
float endY = 400 + 50 * sine;
1
votes

Error in your code is that you using degrees, while Math.cos and Math.sin requires argument in radians.
Use Math.toRadians instead of Math.toDegrees and your code will start to work.