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
m3mn0ckAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jaime OlivaresSoftware ArchitectCommented:
I see a big error in your code. The for loop (1..12), not only draw the clock face but it repeateadly draw the hour/minutes/seconds hands. You need to terminater your for loop before.

// 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 ) );

      }  // <------------------ Terminate your for loop here

     // NOW DRAW HANDS ONLY ONCE    
          //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)  +          // <----- USE MODULUS OPERATOR HERE
           (double) t.GetMinute() / 60.0  +         // TOO MUCH PARENTHESIS
           (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 * 0.5 * sin(HourValue) ),
                              nCenterY - (int) ( (double)nYRadius * 0.5 * 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 * 0.75 * sin( MinuteValue) ),
                               nCenterY - (int) ( (double) nYRadius * 0.75 * cos( MinuteValue) ) );

//       }  <---- Don't need this ending brace

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
m3mn0ckAuthor Commented:
Thanks a lot Jaime i really appreciate it

:D
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming

From novice to tech pro — start learning today.