Designing an Analog Clock in C programming - Clearly explained

Analog-clock-designed-in-c-language
Hi friends,
This is the first Weekly special post at Tech Google. I have designed this clock inspired by Neon clock programmed by Naren Aryan, a very good Python programmer. Though this clock is not as good as a Neon clock, I think this is also a good one to learn. Hope you all would like it.

Before going into the post, here are few prerequisites you need to have.
  1. A PC with Turbo C++ installed and correctly configured for running graphic programs.
  2. Even if you have Dev C++ , configure it to work with graphics library.
  3. Basic knowledge on Coordinate geometry.( I'm not gonna explain the basics in this post)
  4. At least you should have known the general equation of a circle.
  5. How the hands move in an analog clock.
Let us jump into the content.

Design of Analog Clock in C

Firstly we will start from the clock dial. So, a clock dial would be looking something like a circle with a border and hours and minutes perfectly marked on it.

Layout

For designing the clock dial, I've defined a function named clockLayout(). In this function initially we will be drawing a circle, which would be our clock border using the function circle() in graphics library.

maxx=getmaxx();
maxy=getmaxy();
setcolor(BLACK);
circle(maxx/2,maxy/2,120);               /* 120 is the radius of the circle */
pieslice(maxx/2,maxy/2,0,360,5);      /* small circle  on the centre of dial */

Marking on clock dial

Next Challenge is how to place the hours and minutes marks on dial?For this i'll be discussing a little geometry. If you already know it skip this description.
So we know that the clock must have 12 hrs markings each placed at regular intervals. So the spacing between each hour is an angle of 30 degrees(360/12). These markings will be placed on a circle of radius 100 so that there will be a gap between the outer border and markings on the dial.
If (x,y) is centre of circle of radius r, then a point on the circle making an angle 'j' with the horizontal is given by (x+rcos(j),y+rsin(j)).

x=maxx/2+100;y=maxy/2;                      /* initially j was 0 so, i've initialized the directly */
r=100;                                                      /* radius of circle on which markings are done */
setcolor(BLACK);
for(float j=PI/6;j<=(2*PI);j+=(PI/6)){    /* iterating at every 30 degrees (PI=180 degrees) */
  pieslice(x,y,0,360,4);                             /* marking of hour */
  x=(maxx/2)+r*cos(j);
  y=(maxy/2)+r*sin(j);
}

cordinates-of-a-line-when-inclined-by-j-degrees

similarly for minutes marking we will iterate at an angle of 6 degrees

x=maxx/2+100;y=maxy/2;                        /* initially j was 0 so, i've initialized the directly */
r=100;                                                        /* radius of circle on which markings are done */
setcolor(BLACK);
for(float j=PI/30;j<=(2*PI);j+=(PI/30)){  /* iterating at every 6 degrees (PI=180 degrees) */
  pieslice(x,y,0,360,2);                              /* marking of minute */
  x=(maxx/2)+r*cos(j);
  y=(maxy/2)+r*sin(j);
}

clock-layout-sample

Moving seconds hand

The function secHand() gets the status of the present second from the system clock and moves the end of the seconds hand line according to it.
For example if the seconds from system clock is 21 then the angle it must make with respect to vertical axis is 21*6=126 degrees

void secHand(){
  maxx=getmaxx();maxy=getmaxy();
  struct tm t;                                               /* predefined structure to get system clock */<
  _getsystime(&t);                                     /* getting the system clock */
  int r=80,sec=t.tm_sec;
  int x=maxx/2,y=maxy/2;
  float O=sec*(PI/30)-(PI/2);            /* O stores the inclination of the seconds hand with respect to vertical */
  setcolor(BLACK);
  line(maxx/2,maxy/2,x+r*cos(O),y+r*sin(O)); /* printing the seconds hand */
}

Rotating the minutes hand

Similar to seconds hand we will be rotating minutes hand. 

void minHand(){   maxx=getmaxx();maxy=getmaxy();   struct tm t;   _getsystime(&t);   int r=60,min=t.tm_min;   int x=maxx/2,y=maxy/2;   float O=(min*(PI/30)-(PI/2));   setcolor(BLACK);   line(maxx/2,maxy/2,x+r*cos(O),y+r*sin(O)); }

Displaying the hours hand

The hours hand is little complex. For every 12 min, the hours hand must me moving with an angle of 6 degrees. so if the time is 3.12 then the inclination of hours hand becomes 96 degrees with the vertical.

void hrHand(){
maxx=getmaxx();
maxy=getmaxy(); 
  struct tm t; 
  _getsystime(&t); 
  int r=50,hr=t.tm_hour,min=t.tm_min; 
  int x=maxx/2,y=maxy/2;   float O;
  /* we will get 24 hrs clock from system so change it */   
if(hr<=12)O=(hr*(PI/6)-(PI/2))+((min/12)*(PI/30));
   
if(hr>12) O=((hr-12)*(PI/6)-(PI/2))+((min/12)*(PI/30)); 
  setcolor(BLACK);
   
line(maxx/2,maxy/2,x+r*cos(O),y+r*sin(O)); 
}

Repeating all these functions for every second

We need to update the picture of the clock for every second so we can palce it in an infinite loop as shown below

while(1){
  clockLayout();
  secHand();
  minHand();
  hrHand();
  delay(100);              //delaying the execution for 100 milli seconds
  cleardevice();  }
Aggregating all these functions will give you a complete analog clock.
analog-clock-screenshot

Video showing demo of Analog clock Designed in C language

I have changed colors in this clock. Don't worry its the same code but the colors are little changed.
Check out the links to the github project in the video description.

Also send your opinions through Contact page about the Weekly Special Posts. I will write about what you want me to feature in the next week article.

 Thank you for reading this post. Do you have any problem with the code? Drop a comment below and let me help you.

1 comment:

  1. Hi,
    Thanks for posting the source code.
    Could you please let me know if you can develop an analog clock with date, month, year hands along with the normal hr, min, sec hands. If you could let me know your hourly rate I would appreciate it and I can send the detail specs.
    Thanks.
    Regards.
    sk7403776@gmail.com

    ReplyDelete

Please DO NOT SPAM. You're not allowed to use links in comments unless it's necessary.

I Appreciate your valuable Feedback.

Regards,

www.TricksStar.com