views:

225

answers:

1

I feel stupid for asking this question (my trig is rusty), but I'm having a tough time.

Lets 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;
}
+5  A: 

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
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!
typoknig
@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
@casablanca: D'oh! Of course you're right...maybe I should quit commenting on math posts on Friday nights.
Jim Lewis
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.
typoknig
@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
+1: but I would use `Math.toRadians(angle)` instead of `* Math.PI / 180`...
Carlos Heuberger
@Carlos: Good one, didn't know such a method existed.
casablanca