Link to home
Start Free TrialLog in
Avatar of m3mn0ck
m3mn0ck

asked on

Problems with C++ ANALOG CLock drawing

Hi i am doing a C++ Active X analog clock

when i draw the hour hand i have no problem and the formula i use to calculate its position works perfect
but when i try to draw the minute hand it always seems off and then whenever a minute passes it jumps about 25 muinutes and draws in an incorrect position

here is the code witht he calculation for the position of the hands.

void CProject5Ctrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
      
   if(m_nDisplayStyle == 7)
   {
        //Creat the Time String
        CString m_sTime;
        CTime curTime = CTime::GetCurrentTime();
        //Format the Time String
        m_sTime.Format("%02d:%02d:%02d",
                              curTime.GetHour(),
                              curTime.GetMinute(),
                              curTime.GetSecond());
      
        // Fill the Rectangle with white            
        pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
        // Calculate the Average Width and Height for the Font      
        int nChars = strlen ( m_sTime );
        int nAvWidth = ( rcBounds.Width() / nChars) - 3;
        int nAvHeight = rcBounds.Height();

        // Create the Font
        CFont m_fFont;
        m_fFont.CreateFont(nAvHeight,nAvWidth,
                                    0,0,FW_DONTCARE,FALSE,
                                    FALSE,0,DEFAULT_CHARSET,
                                    OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,
                                    DEFAULT_QUALITY,DEFAULT_PITCH | FF_DONTCARE,"Arial");

        // Assign the font and set a Pointer to the old Font
        CFont *pOldFont = pdc->SelectObject( &m_fFont );
      
        // Display the current time
        int nCenterX = rcBounds.TopLeft().x;
        int nCenterY = rcBounds.TopLeft().y;
        pdc->TextOut(nCenterX,nCenterY,m_sTime);
   }      
   
   else
   {
        // Fill the Rectangle with white            
        pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
        
        // Create a small font to draw the clock digits with.
      CFont Font;
        Font.CreateFont( 15, 15,
        0, 0, FW_DONTCARE, FALSE, FALSE, 0,
        DEFAULT_CHARSET, OUT_CHARACTER_PRECIS,
        CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY,
        DEFAULT_PITCH | FF_DONTCARE,
      "Arial" );
        // Set the device context to the new font, and
        // make a pointer to the old font.
        CFont *pOldFont = pdc->SelectObject( &Font );
        // Calculate the X and Y radii, and the center point of
        // the analog clock face.
      int nXRadius = rcBounds.Width() / 2;
        int nYRadius = rcBounds.Height() / 2;
        int nCenterX = rcBounds.TopLeft().x + nXRadius;
        int nCenterY = rcBounds.TopLeft().y + nYRadius;      

      // Remove the largest possible clock face so your clock
        // stays within the circle.
        CSize size = pdc->GetTextExtent( "12", 2 );
      nXRadius -= ( size.cx / 2 );
        nYRadius -= ( size.cy / 2 );

        // Draw the clock face.
        for( int i=1; i<=12; i++ )
        {
          // Create the number string for the display.
          char szDisplayNum[25];
          wsprintf( szDisplayNum, "%d", i );
          // Get the size of this clock digit string.
          size = pdc->GetTextExtent( szDisplayNum,strlen( szDisplayNum ) );
            // Calculate how far from the center of the clockface the
             // numbers will be (both X and Y axis).
          int nXLength = (int)( (double) nXRadius * sin( (2 * 3.14) * ( (double) i / 12 ) ) );
          int nYLength = (int)( (double) nYRadius * cos( (2 * 3.14) * ( (double) i / 12 ) ) );
          // Draw the display.
           pdc->TextOut( nCenterX + nXLength - ( size.cx / 2 ),nCenterY - (int) nYLength - ( size.cy / 2 ),szDisplayNum, strlen( szDisplayNum ) );
            
            //Pointer for old Pen
            CPen Hour;
            CPen Minute;
            CPen Second;
            CPen *pOldPen;
            Hour.CreatePen(PS_SOLID,1,RGB(0,0,0));
            Minute.CreatePen(PS_SOLID,1,RGB(0,255,0));
            Second.CreatePen(PS_SOLID,1,RGB(255,0,0));
            
            // Select the hour hand pen.
            pOldPen = pdc->SelectObject( &Hour );
            // Calculate the hour display value. Remember to convert from the
            // 24-hour to the 12-hour format here.
            CTime t = CTime::GetCurrentTime();
            double HourValue =
            ( (double) ( t.GetHour() <= 12 ?
            t.GetHour() : t.GetHour() - 12 ) +
            ( (double) t.GetMinute() / 60.0 ) +
            ( (double) t.GetSecond() / 3600.0 ) ) *
            ( (2 * 3.14) / 12.0);
            // Now, draw the hour hand line.
            pdc->MoveTo( nCenterX, nCenterY );
            pdc->LineTo( nCenterX +
            (int) ( ( double) ( ( nXRadius * 50) / 100) *
            sin( HourValue ) ),
            nCenterY - (int) ( (double) ( ( nYRadius * 50) / 100) *
            cos( HourValue ) ) );

            // Select the Minute hand pen.
            pOldPen = pdc->SelectObject( &Minute );
            // Calculate the minute display value.
            double MinuteValue =
            ( (double) t.GetMinute() ) +
            ( (double) t.GetSecond() / 60.0 )  *
            ( (2 * 3.14) / 60.0);
            // Now, draw the Minute hand line.
            pdc->MoveTo( nCenterX, nCenterY );
            pdc->LineTo( nCenterX +
            (int) ( ( double) ( ( nXRadius * 75) / 100) *
            sin( MinuteValue ) ),
            nCenterY - (int) ( (double) ( ( nYRadius * 75) / 100) *
            cos( MinuteValue ) ) );

        }

        // Reset the font back to the original.
        pdc->SelectObject( pOldFont );
        
      }
      
}



thanks in advance
ASKER CERTIFIED SOLUTION
Avatar of Jaime Olivares
Jaime Olivares
Flag of Peru image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of m3mn0ck
m3mn0ck

ASKER

Thanks a lot Jaime i really appreciate it

:D