Ever wanted the most simple but elegant analog clock:

#include <math.h>
#define CLL  .95
#define CLL2 .90
#define CLS  .90
#define CLM  .80
#define CLH  .60

void line(x1,y1,x2,y2,width);

void render_indicators(x,y,r)
{
  for(i = 0;i < 60;i++)
  {
    line(x + cos(ang * 2 * pi) * r, y - sin(ang * 2 * pi) * r, x + cos(ang * 2 * pi) * (i%5==0?CLL2:CLL) * r, y - sin(ang * 2 * pi) * (i%5==0?CLL2:CLL) * r, 1);
  }
}

void render_arms(x,y,r,hour,minute,second,millisecond=0)
{
  /* We define our angle, a custom 0.0 to 1.0 ranged value: */
  float ang = 0.0;
  
  /* First we take milliseconds (for smoothness) */
  ang += millisecond/1000.0;
  /* Then we add the seconds */
  ang = (ang + second)/60.0;
  
  line(x,y,x + cos(ang * 2 * pi) * CLS * r,y - sin(ang * 2 * pi) * CLS * r,1);
  line(x,y,x - cos(ang * 2 * pi) * CLS*.1 * r,y + sin(ang * 2 * pi) * CLS*.1 * r,1);

  /* Then we add the minutes */
  ang = (ang + minute) / 60.0;

  line(x,y,x + cos(ang * 2 * pi) * CLM * r,y - sin(ang * 2 * pi) * CLM * r,2);

  /* And finally we add the hours */
  ang = (ang + hour) / 12.0;

  line(x,y,x + cos(ang * 2 * pi) * CLH * r,y - sin(ang * 2 * pi) * CLH * r,4);
}

To get various effects or efficiency, you can do the following:

  • To efficiently update:

    void update_clock()
    {
      set_color(background_color);
      render_arms(clock_x,clock_y,100,hour,minute,second,millisecond);
      get_time(&hour,&minute,&second,&millisecond);
      set_color(clock_color);
      render_arms(clock_x,clock_y,100,hour,minute,second,millisecond);
    }
    

    You should declare the hour, minute, second and millisecond somewhere outside the render function where it can store the time of the previous render:

  • Shadow effect:
    set_color(shadow_color);
    render_arms(clock_x,clock_y,100,hour,minute,second,millisecond);
    set_color(clock_color);
    render_arms(clock_x-2,clock_y-2,100,hour,minute,second,millisecond);
    
  • Using OpenGL1:

    void line(x1,y1,x2,y2,width)
    {
      glLineWidth(width);
      glBegin(LINES);
        glVertex2f(x1,y1);
        glVertex2f(x2,y2);
      glEnd();
    }
    
  • Make the second arm red
  • Make the clock transparent
  1. This code uses the deprecated glBegin/glVertex functions. They should be changed to vertex buffers