Clock Angles

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math topics]   [Library]   [Utilities]

 

 

Search

Search WWW

Search DelphiForFun.org

As of October, 2016, Embarcadero is offering a free release of Delphi (Delphi 10.1 Berlin Starter Edition ).     There are a few restrictions, but it is a welcome step toward making more programmers aware of the joys of Delphi.  They do say "Offer may be withdrawn at any time", so don't delay if you want to check it out.  Please use the feedback link to let me know if the link stops working.

 

Support DFF - Shop

 If you shop at Amazon anyway,  consider using this link. 

     

We receive a few cents from each purchase.  Thanks

 


Support DFF - Donate

 If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

Mensa® Daily Puzzlers

For over 15 years Mensa Page-A-Day calendars have provided several puzzles a year for my programming pleasure.  Coding "solvers" is most fun, but many programs also allow user solving, convenient for "fill in the blanks" type.  Below are Amazon  links to the two most recent years.

Mensa® 365 Puzzlers  Calendar 2017

Mensa® 365 Puzzlers Calendar 2018

(Hint: If you can wait, current year calendars are usually on sale in January.)

Contact

Feedback:  Send an e-mail with your comments about this program (or anything else).

Search DelphiForFun.org only

 

 

 

 

Problem Description

Here's a beginner's program that was adapted from an ACM Programming Contest.   Given  integers representing  hour and minute of a time of day, calculate the angle between the hour and minute hands when looking at a normal analog clock.

(If you're not interested in the why or how, you can skip to the bottom of the page to download source and/or executable for this program)

Background & Techniques

ACM Programming Contests provide an almost unlimited source of problems.  Each contest contains a couple of programs that can be coded by a talented college Freshman in an hour.  This is one.   

I decided to time myself - the non-visual version took 30 minutes.  With the extra time I added a visual clock display - which took an extra 28 minutes.  You won't find many comments in the code so I'll try to provide a thorough explanation here.     

First the "computing the angles" part.   The angle of the minute hand  should be "# of degrees for each minute" X "# of minutes".    Since 60 minutes represents 360 degrees, each minute represents 360/60 or  6 degrees.      (So 30 minutes becomes  6*30 = 180 degrees, etc.).   The hour hand is similar with one exception - the hour hand includes hours and and fractions of an hour (reflected by minutes) in its angle.   So the hourtime  is  "hours +  minutes/60".  (  Hourtime for 6:30, for example, is 6+30/60 or 6.5).  Since the hour hand revolves 1/12 of a revolution or 30 degrees for each hour, the hour hand angle is 30 X  hour time.   If the time is 6:30, the hour hand angle is 30 X 6.5 = 195 degrees.   Finally, the angle difference between the hands is 195-180=15 degrees.

As you browse the program you'll note that, under the pressure of time, the code is not quite this neat.    I tended to write the code step by step as I worked out the solution.  (How we solve problems is an big interest of mine but it's very difficult to solve a problem and think about how it's being solved at the same time.)

On to the second half of the problem - displaying the clock image.  I "wasted" perhaps 5 minutes deciding which component to use.   First a  TShape circle was dropped on the form as a clock face, but then realized that it has no Canvas property on which to draw hands etc.   I considered drawing the clock face  using the form's canvas, but rejected that idea.  A TImage was finally chosen using  a TBitmap's canvas to draw on.   

The drawing was implemented as a procedure ( DrawTime) with the two hand angles as parameters.  I decided to make the  minute hand length equal to 3/4 of the face radius and the hour hand equal to half the radius.   Looking at real clocks now I see that they should be much longer, another sacrifice to time pressure.   To draw the hands, we need a couple of lines at  particular angles.   Time for a trigonometry review.  Pretty simple thanks to my old Indian chief friend - chief SOH CAH TOA.   (In case you haven't met him, Sine=Opposite side/Hypotenuse, Cosine=Adjacent side/Hypotenuse and Tangent=Opposite/Adjacent; --- picture an Indian chief soaking his toe).      In our case sin(a)=Y/HandLength and cos(a)=X//HandLength.  Or, multiplying everything by HandLength, Y=sin(a)*HandLength, X=cos(a)*HandLength.   Note that these angles are calculated the traditional way, relative to horizontal.  For our clock face we need to subtract 90 degrees to make them relative to vertical.   On hindsight, I see that the same 90 degree shift could be accomplished by interchanging the sin and cos functions.  

Everything else is detail.  Sin and Cos functions require angles in radians so input angles are multiplied by Pi/180.  There is a DegToRad function which does this, but again, I didn't have time to look it up.   The 12 dots around the clock face were added as a bonus in the last 5 minutes of my one hour time limit.

All-in-all, I didn't find "speed programming" nearly as enjoyable as taking more time and doing it well.   The  program has about 100 lines of code but nearly half are generated for the many labels, edits, etc. on the form.   The angle calculation part took about 20 lines of code and the  DrawTime procedure about 40 lines.   

Addendum October 20, 2004:   A viewer recently  wrote asking for the solution to a puzzle that was bugging him - "How many times are a clock's  hour and minute hands at right angles to each other in a 24 hour day?"    Here's a link to my  email answer.  I also animated the clock angle program today to visually  answer the question.   This addition moves the program from "Beginners" to "Intermediate" category, but still not too complex if you take time to study the code.   As always, feel free to use the feedback link below  if you have questions or comments.

Addendum June 23, 2006:   The email mentioned above derives the equations for calculating when the hands are 90°  apart: m = (60h+180) / 11 (for minute hand leading hour hand by 90°) and  m = (60h-180) / 11 (for minute hand trailing hour hand by 90°).   Another viewer wrote recently, confused by the results.  For example, when she tried hour 9, she got 65.45 for the minutes time rather than the 0 she expected. Two factors contribute to This anomalous result:

bulletThe way that hours of the day are labeled; we call the first hour of the day "12", the 2nd hour "1", ... and the 12th hour "11".  So the 9th hour is when the hour hand is between 8 and 9. 
bulletIf we evaluate the equation for h=8, we get m= (60*8+180)/11= 660/11=60.  So the time when the minute hand leads the hour in the 8-9 range is hour 8 plus 60 minutes (i.e.:9:00).  Similarly for the 10th and 11 hours, the minutes value reflects that the hour hand is into the next hour.      

 To clarify things, here is the complete table for each hour with minutes for both trailing and leading.  I have subtracted 60 minutes when the equation results  were greater than 60:  

Minute hand passing hour hand cycle
Minutes hand  position when 90°ahead of hour hand Approximate
 HH:MM time
Minutes hand  position when 90° behind hour hand Approximate HH:MM time
1 16.36 12:16 49.09 12:49
2 21.82 1:22 54.55 1:55
3 27.27 2:27 60.00 3:00
4 32.73 3:33 0.00 3:00
 5 38.18 4:38 5.45 4:05
 6 43.64 5:44 10.91 5:11
 7 49.09 6:49 16.36 6:16
 8 54.55 7:55 21.82 7:22
 9 60.00 9:00 27.27 8:27
10 0.00 9:00 32.73 9:33
 11 5.45 10:05 38.18 10:38
 12 10.91 11:11 43.64 11:44

Notice that, for the hour hand horizontal (3 or 9 o'clock), the time duplicates the preceding entry in the table.  So there are only 11 (or 22 counting before and after) unique values in 12 hours!

September 18, 2011:  We're revisiting the program today with Version 2 which allows the option of pausing the clock each time the minute hand is at right angles to the hour hand.   Thanks to Middle-school teacher Judy in Australia for requesting the feature to help her math students think about the problem  The exercise forced me to re-think the algorithm because, while it was easy to count hands crossing the 90 degree boundaries, stopping there and displaying the exact crossing time was not so easy.  In the process I developed this step by step explanation which seems easier to understand and implement than the equations previously developed:

  1. The Hour hand of a regular clock rotates 360 degrees in 12 hours. The rate at which the hand moves
    is therefore 360/12 or 30 degrees per hour. That is 0.5 degrees per minute.
  2. The Minute hand makes a complete revolution in 60 minutes or 360/60= 6 degrees per minute.
  3. This means that for each passing minute, the minute hand picks up 5.5 degrees over the Hour hand (6.0 - 0.5).   Written as an equation, X degrees lead = 5.5 x M minutes.  How long will it take the Minute hand to get 90 degrees ahead? We can turn the equation around and compute M = X / 5.5. Assuming both hands start at 0 degrees (12:00:00), the Minute hand will be 90 degrees ahead in 90/5.5 or in about 16.36 minutes at (HH:MM:SS) 12:16:22. It will again be separated by 90 degrees, counterclockwise this time, after the Minute hand has moved 270 degrees more than the Hour hand. That is, at -90 degrees, the time is  270/5.5, about 49.09 minutes or at about 12:49:05.
  4. We can continue calculating this way for each 180 degree increase of the difference in hand positions computing total times since start which are 450/5.5, 630/5.5, 810/5.5, 990/5.5, etc.,
    until times start repeating after 12 hours.
     

Running/Exploring the Program 

bulletDownload source
bulletDownload executable

Suggestions for Further Explorations

It wouldn't take much code to add a second hand, and a timer to pop each second to produce a real time analog clock.  Easy to do -- so now you can see why tons of versions already exist - let's just move on to the next challenge. 

 

Original Date: April 29, 2001

Modified: May 11, 2018

  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright © 2000-2018, Gary Darby    All rights reserved.