( Index )
Month

Brief Information about the Jan '04 CSIG Meeting

A Deco Analog Clock

B. Arnold

Deco Clock

Welcome to the CSIG, a Special Interest Group of the ACGNJ. The subject for this month is short journey into C++ Graphical Windows programming. In addition, mathematical and trigonometric functions will be discussed.

Let's build a clock using Windows Graphics. We could ask the system for the time and print the values to the screen in a large font but that's not very challenging. How about an analog clock: one with hands. How do the hands move? There are 43,200 seconds in a 12 hour rotation of a clock. This means that the hour hand moves 360 degrees in that many seconds. In order to design a program to move the hour hand every second, it would have to move 0.00833333333 degrees each time. Can this be done in C++ ? Sure. How about the minute hand. There are 3600 seconds in a 1 hour rotation.. This means that the minute hand moves 360 degrees in that many seconds. For each second it would have to move 0.1000 degrees. As you can see, there's a little bit of math involved. There's also trigonometry which we'll discuss at the meeting.

Sample Code

void TimePiece::show_time(void)         /* display the clock */
    {
    static struct DEGREES last_deg, deg;
    static int firstime = 1;
    
    current.hr  = current.hr % 12;
    deg.hr  = (double)current.hr*30.0 + (double)current.min/2.0 +
                                        (double)(current.sec & 0xFF)/120.0;
    deg.min = (double)current.min*6.0 + (double)(current.sec & 0xFF)/10.0;  // was FE
    deg.sec = (double)current.sec*6.0;
    
    hand(0.50, deg.hr);                    /* hour   hand  */
    hand(0.75, deg.min);                   /* minite hand  */
    pivot(0.05);
    }


void TimePiece::pivot(double radius)                     /* draw pivot */
    {
    int x1, y1, x2, y2;
    x1 = (int)((-radius)*1000); y1 = (int)((-radius)*1000); 
    x2 = (int)((+radius)*1000); y2 = (int)((+radius)*1000);
    pdc->Ellipse(x1, y1, x2, y2);
    }


void TimePiece::hand(double size, double angle) /* draw hand */
    {
    struct FPOINT p3, center;
    oldPen     = (HPEN)pdc->SelectObject(mPen);
    oldBrush   = (HBRUSH)pdc->SelectObject(mBrush);
                                               /*         P3         */
    center.wx = center.wy = 0.0;               /*         |          */
    p3.wx = size * sin( angle*2.0*PI/360.0);   /*         |          */
    p3.wy = size * cos( angle*2.0*PI/360.0);   /*         |          */
                                               /*       CENTER       */
    line(center, p3);
    pdc->SelectObject(oldPen);
    pdc->SelectObject(oldBrush);
    }


void TimePiece::line(struct FPOINT p1, struct FPOINT p2)  /* draw line */
    {
    int x, y;
    x = (int)(p1.wx * 1000); y = (int)(p1.wy * 1000);    pdc->MoveTo(x, y);
    x = (int)(p2.wx * 1000); y = (int)(p2.wy * 1000);    pdc->LineTo(x, y);
    }


void TimePiece::face(void)              /* add circles for hour marks */
    {
    struct FPOINT p1;
    int x1, y1, x2, y2, i;
    double deg, dot_radius, ul_x, ul_y, lr_x, lr_y;
    for (dot_radius=0.09,i=0; i<1; i += 1)          // for 12 hours change to "i<12"
        {
        deg   = (double)i*30.0;
        p1.wx = 0.85*sin( deg*2.0*PI/360.0);        //   = 0.000    at 12:00 o'clock
        p1.wy = 0.85*cos( deg*2.0*PI/360.0);        //   = 0.850
        ul_x  = p1.wx-dot_radius;
        ul_y  = p1.wy+dot_radius;
        lr_x  = p1.wx+dot_radius;
        lr_y  = p1.wy-dot_radius;
        x1 = (int)(ul_x*1000); y1 = (int)(ul_y*1000); 
        x2 = (int)(lr_x*1000); y2 = (int)(lr_y*1000);
        pdc->Ellipse(x1, y1, x2, y2);
        }
    }

"Random Access" questions start at 7:30 Tuesday night.

SOURCE CODE

Source Code Files

For help, email me at b a r n o l d @ i e e e . o r g
Back to C++ Main Page