Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!

# anyone good at math?

Randall Twede
Ranch Hand
Posts: 4363
2
i finally thought of a new project. it is an old style analog clock. it has to draw the hands every second. to do this it uses two points, the origin and a point on the circumference. i use 3 array[60] to hold the end points. my problem is with initializing the arrays. lets just consider the second hand for now, the others will be similar. this is what i came up with but it is so convoluted i think there has to be a better way.

O = the origin point
L = the length of the hand(radius)
I = the index into the array and the value returned by Calendar

i have four special cases
I = 0
{
x = O.x
y = O.y - L
}
I = 15
{
x = O.x + L
y = O.y
}
I = 30 {
x = O.x
y = O.y + L
}
I = 45
{
x = O.x - L
y = O.y
}
then i need four seperate for statements
for(1 to 14)
x = O.x + (L/15) * I
y = O.y - (L - (I/15) * L
for(16 to 29)
x = O.x + (L - ((I -15 )/15) * L)
y = O.y + (L/15) * (I - 15)
that should be enough to give you the idea. please tell me there is a better way.

Jeff Verdegan
Bartender
Posts: 6109
6
Um, to find the x and y coordinates of a point on a circle, you need the cos and sin of the angle. So read up on math.cos() and math.sin(), and then figure out how to work that into your coordinate system.

Randall Twede
Ranch Hand
Posts: 4363
2
ok, that might be a better way.

Campbell Ritchie
Sheriff
Posts: 48454
56
Cast your mind back six years, to when I was a little greenhorn and I posted this.

After I had explained it face-to-face to Joseph, I helped him implement a clock, and mischievously suggested trying -sin instead of +sin. So he had this clock resolutely ticking away backwards and Elizabeth, the lecturer, came to see how we were getting on. I had to confess that I might have misled Jo slightly, and she laughed out loud when she saw the clock working.

Randall Twede
Ranch Hand
Posts: 4363
2
i almost have it working the way i did it, but i do thank you for the link. now i have something to do when i finish(rewrite it the other way)

Randall Twede
Ranch Hand
Posts: 4363
2
thanks again Campbell. it turns out the way i was doing it didn't work correctly anyway. the hand moved correctly, but it's length didn't stay the same. it would have worked fine if the clock was square(diamond shaped).

Randall Twede
Ranch Hand
Posts: 4363
2
ok, i really need help with this. in the 8 years i spent in college, the only course i ever failed was trigonometry. i took it the very next term and still only got a C. by comparison calculus and probability&statistics were easy. i saved Campbells first post in that old thread and worked on it offline. all i ended up with was this://g.drawLine(origin.x,origin.y,origin.x + Math.cos(angle) * secondHandLength,origin.y - Math.sin(angle) * secondHandLength);
it's good code once i have a variable called angle.
i will post the entire code since it isn't that long.

i have two observations. first i might not need the arrays. and second the hour and minute hands might move linearly instead of "ticking" like they would have in my original design. i will copy his second post in that old thread and see if i can figure it out, but any help will be appreciated.

Campbell Ritchie
Sheriff
Posts: 48454
56
Create a copy of the Graphics object, and cast it to Graphics 2-d. I am not absolutely certain whether this step is necessary, but affine transforms can interfere with each other. Shear is the worst offender, and you are only using scale and translate, so you might not have any problems.
You will have to look in the API, because I am doing this from memory, and you will have to assume some values for the constants. They should be obvious.
You have a clock face, and you move the graphics object with its translate method, so the origin is in the middle of the componentNow you need to work out from the time what the angle is. Let us assume you have a minutes int local variable, such that 0 = 12o’clock and 719 = 11.59. Now, the origin of sin and cos work on the assumption that 0° = 3o’clock and they run anti-clockwise.This is from memory, so I cannot guarantee it is correct; please tell me if you find an error. Note you have to double up the angles because a circle is not π radians but 2π radians round.

Randall Twede
Ranch Hand
Posts: 4363
2
thanks Campbell, i was just frustrated i couldn't figure it out. but after a good night sleep, i see i am very close. i don't need any arrays. i just have to figure out the 3 angles in actionPerformed(), then use them in paintComponent(). so i guess it is easy.

thanks also for the advice about shear i noticed that and thought my other program that drew lines didn't have that problem.

i posted the rest of this message before actually reading your reply. are you trying to confuse me?
i'll figure it out thanks to you though. and i will post the final source code and a link to the image file so you can all have a clock on me.

Campbell Ritchie
Sheriff
Posts: 48454
56
I set Eclipse to work this morning and got this:. . . complete with serial version UID And I forgot I didn’t need a Layout.
The hands weren’t behaving as I thought, presumably because subtracting 3o’clock is only necessary when you don’t transform the Graphics object.

Randall Twede
Ranch Hand
Posts: 4363
2
i finished it this morning.
i didn't use a layout either
it does have a little shear, but not too bad though

thanks for the help. i'm glad i didn't have to relearn trig so i could figure it out myself.

Campbell Ritchie
Sheriff
Posts: 48454
56
Well done

There is no need for the % operations. If you calculate the angle correctly for 1o’clock, you can use 13 25 or 37o’clock, and get the same sin and cos.

Randall Twede
Ranch Hand
Posts: 4363
2
Campbell, i tried what you first mentioned, using -sin for x.
it's funny, seeing a digital clock counting down looks normal, but seeing an analog clock running backwards looks wrong. a lifetime of conditioning i suppose.
if i can find an image of a clock face with the numbers going counter-clockwise i will use it. hehe
i am sure you are right about not needing the mod operators. especially since Calendar takes care of that.

Campbell Ritchie
Sheriff
Posts: 48454
56
There is an analogue clock running anti-clockwise about 10 feet beyond my left shoulder as I write. When I moved in here, I thought we are all computer scientists, we ought to be able to think laterally, so we can cope with an anti-clockwise clock. There is one in the club where I pay £2.55 for a pint (0.57l) of beer. I see them occasionally in bars, where they ought to be placed opposite a mirror. So few people realise you can read an anti-clockwise clock easily by looking in the mirror! I am tempted to buy my wife such a clock as a present, but I think that might cause ructions
The reason you don’t need the % operator is that sin, cos, etc., take any value for their argument; sin(x) is equal to sin(x % (2π)) for all values of x, with a few reasonable assumptions about sign when x < 0.

Paul Clapham
Sheriff
Posts: 20776
30
Randall Twede wrote:thanks for the help. i'm glad i didn't have to relearn trig so i could figure it out myself.

You had to take a whole course in trigonometry? I didn't think there was enough content for a whole course (I was a graduate teaching assistant for courses where we spent a week or two covering trigonometry).

The only thing you needed to take away from your trig course was the acronym SOH-CAH-TOA. (Draw a right triangle and pick one of the two non-right-angle corners; then Sine = Opposite/Hypotenuse, Cosine = Adjacent/Hypotenuse, and Tangent = Opposite/Adjacent.) This is pretty much all you'll ever need to know for programming.

Randall Twede
Ranch Hand
Posts: 4363
2
it was not only a 3 month course at community college when i took it in the 70's, but it is the only course i failed and had to take again. this is the first time i have had to use it in over 30 years.

Darryl Burke
Bartender
Posts: 5125
11
Randall Twede wrote:it does have a little shear, but not too bad though

Graphics2D#setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)

Every Graphics object in a modern JDK (>1.2) is a Graphics2D subclass.

Campbell Ritchie
Sheriff
Posts: 48454
56
That isn’t shear. Shear means turning a square into a rhomb. What you have, as DB implies, is aliasing. It causes the oblique lines to look like staircases.

Randall Twede
Ranch Hand
Posts: 4363
2
ah yes. aliasing. well it isn't very bad, but since i have nothing to do, i might pursue the hint D.B. gave me.

Campbell Ritchie
Sheriff
Posts: 48454
56
Quite right. It’s always good to take the opportunity to learn something new.

Randall Twede
Ranch Hand
Posts: 4363
2
ah well, all the backward clocks i could find on google had hands so i would have to edit one in Paint to erase the hands. too much bother for now.

Randall Twede
Ranch Hand
Posts: 4363
2
here is something interesting. i cast the Graphics g to Grapics2D and called it g2.
Graphics2D g2 = (Graphics2D)g;
i set the antialiasing to on and ran it and it was much smoother. then i went back to the code to change the stroke to make the hour and minute hand wider and i noticed i was still using g to draw the lines. but the antialiasing worked anyway.

one question though. the current code is this

should i move the third line to before the other two and use g2 in those lines? does it matter?