31

Let's say I have an (x,y) that is always the same for the start point of a line and an (x,y) that changes for the end point of that same line. The line is also always 40px long. At the start of the program the line originates in a vertical orientation (lets call it 0 degrees). Based on a user input I need the line to be redrawn a specific number of degrees from its origin by changing only the end (x,y).

SOME MORE FOOD FOR THOUGHT IF YOU NEED IT:

I'm in a rut trying to calculate this and make it work in Java. I can make the math work to calculate the point based on the arc length of a circle segment, but I don't know how to make Java do it.

I think it would work easier based off a triangle angles since I will always know the length of two sides of a triangle (one side formed by the 40px long line and the other side formed by the start point of that line and the border of the JPanel) and the angle those two lines form. Still, my brain is mush from trying to figure it out. Any help would be much appreciated.

UPDATE:

@casablanca got me on the right track. I brushed up on my trig functions and here is how I made it work.

First off, I didn't realize that 90 degrees was straight up, but once I did realize that I made my solution reflect that fact. I was drawing my line starting at the bottom center of the frame going out. Since the opposite side of the triangle is on the right side of the screen when the angle given by my user is less than 90 degrees and is on the left side of the screen when the angle given by my user is greater than 90 degrees I had to adjust the formula to account for that fact, thus I have four methods, one for the x coordinate on the left side of the screen (when the user given angle is greater than 90 degrees), one for the y coordinate on the left side of the screen (when the user given angle is greater than 90 degrees) and the same thing for the right side of the screen when the user given angle is less than 90 degrees. The int length in all methods is the length of the hypotenuse. Thanks again for your help @casablanca!

public double leftSideX(double angle, int length){
    double x = frameWidth/2 - (length * Math.cos(Math.toRadians(90-(Math.toDegrees(angle)-90))));
    return x;
}

public double leftSideY(double angle, int length){
    double y = frameHeight - (length * Math.sin(Math.toRadians(90-(Math.toDegrees(angle)-90))));
    return y;
}

public double rightSideX(double angle, int length){
    double x = frameWidth/2 + (length * Math.cos(angle));
    return x;
}

public double rightSideY(double angle, int length){
    double y = frameHeight - (length * Math.sin(angle));
    return y;
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
ubiquibacon
  • 10,451
  • 28
  • 109
  • 179
  • Also consider altering the graphics context's transform, shown here: http://stackoverflow.com/questions/3420651 – trashgod Aug 21 '10 at 15:18
  • You might want to consider encapsulating this functionlity in a class; e.g. Vector2D. That way you could construct a Vector2D with either x and y coordinates or a length and angle, and provide methods such as getMagnitude(), getAngle(), getX(), getY(), rotateClockwise(double), etc. – Adamski Aug 22 '10 at 21:22
  • I would love to, but I think that is a bit beyond my ability right now. It took me nearly a full day to figure this out :) – ubiquibacon Aug 22 '10 at 21:28

1 Answers1

72

Is this what you're looking for?

startX = x;
startY = y;
endX   = x + 40 * Math.sin(angle);
endY   = y + 40 * Math.cos(angle);

And draw a line from (startX, startY) to (endX, endY) in whatever API you're using.

Also note that angle is in radians. If you had it in degrees, you need to convert it first:

angle = angle * Math.PI / 180;
casablanca
  • 69,683
  • 7
  • 133
  • 150
  • 1
    I hope to God it isn't that simple, but if it is you are going to get at fruit cake this Christmas! I'm too tired to try it now though, but first thing in the morning... thanks for the quick reply! – ubiquibacon Aug 21 '10 at 05:28
  • 1
    @Jim Lewis: Actually the trig conventions are the other way round. I switched it because OP wanted 0 degrees to be vertical: `sin 0 = 0` so `endX = x` and `cos 0 = 1` so `endY = y + 40`. – casablanca Aug 21 '10 at 14:46
  • @casablanca: D'oh! Of course you're right...maybe I should quit commenting on math posts on Friday nights. – Jim Lewis Aug 21 '10 at 16:49
  • 1
    This wasn't quite right, but it got me on the right track. I think I would have used `Math.sin` for `x` and `Math.cos` for `y` if I was drawing my line from the top down, but I was going from the bottom up so I had to switch the functions. – ubiquibacon Aug 22 '10 at 21:08
  • 2
    @typoknig: You just need to change the `+ 40` into a `- 40` if you need to change direction. Switching the functions will switch the `angle` orientation between vertical and horizontal. – casablanca Aug 22 '10 at 22:14
  • @Carlos: Good one, didn't know such a method existed. – casablanca Aug 23 '10 at 16:07
  • Just converting polar to rectangular – Arlind Hajredinaj Jan 13 '16 at 19:24