Jump to content

How to create an analog clock

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
12 replies to this topic

#1
Dren

Dren

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 448 posts
This method is completely based in the SetPixel() function. First the circle is drawn then the clock hands.

How is the circle drawn?
Simple trigonometry! Every angle(in our case every pixel) of a circle has the sine and cosine value. The cosine value of the angle multiplied with the radius of the circle gives you the x for the SetPixel() function and the sine value of the angle multiplied with the radius of the circle gives you the y for the SetPixel(). You can add a number to the x and y value on the function to make the circle not to be in the beginning of the form. Now to draw the circle you need to loop into angles. WHY? If we use degrees as angle measuring units, we know that a circle has 360 degrees. Now we write a loop to find the sine and cosine for the angles from 1 to 360 and use the SetPixel() function to draw the values. The code would be something like this:

	for(in=1;in<361;in++)

	{

		AngleInRad = in * pi / 180;

		x = int(100 * cos(AngleInRad));

		y = int(100 * sin(AngleInRad));


		CClientDC dc(this);

		dc.SetPixel(120 + x,120 + y, RGB(0, 0, 0));

	}

What have we done here? The loop says we give the in variable values until in is 360. For each value, the AngleInRad equals to the value of in in Radians(because the sin() and cos() functions use radians) then the x variable is filled with the integer of the circles radius(in tis case is 100) multiplied by the cosine value of the angle in radians. The same is done for the y value except the the function. For the x value we used the cos() function now we use the sin(). And at the end we draw the pixel for that angle. We see that 120 is added to x and to y. That means the circle is moved 20 pixels from the top and 20 pixels from the left. Why 120 then? Because we included the circles radius :$

Now how is the time shown?
Imagine a circle and an analog clock. the clock has 60 "pixels" and the circle 360. But, in some cases the clock has 12 "pixels". So how to do it? We divide 360 by 6 in the 60 "pixels" case(when we have to do with minutes and seconds) and 360 by 12 in the second case. This means that when the clock hand that shows seconds moves 1 second, it moves for 6 degrees, the same happens when the minutes clock hand moves for 1 minute it moves for 6 degrees. But when the hours clock hand moves for one hour, it moves for 30 degrees.

Now we are ready to write the code! First we get the current time and put it in ts,tm and th variables:


	CTime curTime = CTime::GetCurrentTime();


	ts = curTime.GetSecond();

	tm = curTime.GetMinute();

	th = curTime.GetHour();


Now we convert time into degrees and then into radians and at the end we calculate the x and y values.


		sAngleInRad = (((6 * ts)-90) * (pi / 180));


		sx = int((20 + 80 * cos(sAngleInRad)));

		sy = int((20 + 80 * sin(sAngleInRad)));




		mAngleInRad = (((6 * tm)-90) * (pi / 180));


		mx = int((20 + 70 * cos(mAngleInRad)));

		my = int((20 + 70 * sin(mAngleInRad)));




		hAngleInRad = (((30 * th)-90)* (pi / 180));


		hx = int((20 + 60 * cos(hAngleInRad)));

		hy = int((20 + 60 * sin(hAngleInRad)));


Now use these values to draw pixels and line the pixels with the center of the circle:


		{	

			CClientDC dc(this);

			dc.SetPixel(100 + sx,100 + sy, RGB(0, 0, 0));

			

			dc.MoveTo(120, 120);

			dc.LineTo(100 + sx, 100 + sy);

		}	

	



		{

			CClientDC dc(this);

			dc.SetPixel(100 + mx,100 + my, RGB(0, 0, 255));

			

			dc.MoveTo(120, 120);

			dc.LineTo(100 + mx, 100 + my);

		}	


	


		{

			CClientDC dc(this);

			dc.SetPixel(100 + hx,100 + hy, RGB(255, 0, 0));


			dc.MoveTo(120, 120);

			dc.LineTo(100 + hx, 100 + hy);

		}


Use a timer to do these functions every 1000 milliseconds and before every drawing use the Invalidate() function to clear the form.


Now just test it. It has to work. If it doesn't, download the project attached because I have talked too much!!!

PS: Play with the radius to make the clock an ellipse. Look at the code down here:

	for(in=1;in<361;in++)

	{

		AngleInRad = in * pi / 180;

		x = int([B]100[/B] * cos(AngleInRad));

		y = int([B]80[/B] * sin(AngleInRad));


		CClientDC dc(this);

		dc.SetPixel(120 + x,120 + y, RGB(0, 0, 0));

	}

Thanks again Xav for help.

Best wishes,
Dren

Attached Files



#2
Guest_Jordan_*

Guest_Jordan_*
  • Guests
Excellent tutorial Dren! +rep

#3
Xav

Xav

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 13,118 posts

Dren said:

Thanks again Xav for help.
You're welcome again, Dren. :D See, I told you that you could get more +rep from Jordan as well, if you posted this in the Tuts section!
Jordan said:

Good members, like yourself, stick around and post for ages to come!
Mr. Xav | Blog | Forums

#4
Dren

Dren

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 448 posts
THANK YOU SO MUCH. I'm planning to write another Tutorial tonight. I think it will be interesting.

Thanks again Jordan and Xav,
Dren

#5
Xav

Xav

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 13,118 posts
Can't wait for it! :)
Jordan said:

Good members, like yourself, stick around and post for ages to come!
Mr. Xav | Blog | Forums

#6
Dren

Dren

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 448 posts

Xav said:

Can't wait for it! :)

Ermmm, its in the VB Tutorials, its about creating a Web Server in Visual Basic 6. I have posted a reply on this thread too. Please check it, do you think I can make it a tutorial?

Thanks a lot Xav,
Dren

#7
Xav

Xav

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 13,118 posts
Definitely tutorial material! Post it! :D
Jordan said:

Good members, like yourself, stick around and post for ages to come!
Mr. Xav | Blog | Forums

#8
Dren

Dren

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 448 posts
I'll do some modifications on it and post it :D

Thanks again Xav,
Dren

#9
Xav

Xav

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 13,118 posts
It's OK, again, Dren. :D
Jordan said:

Good members, like yourself, stick around and post for ages to come!
Mr. Xav | Blog | Forums

#10
Code:Terminal

Code:Terminal

    Newbie

  • Members
  • Pip
  • 1 posts
excellent well done!

#11
kresh7

kresh7

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 661 posts
+rep greate tutorial dren
Posted Image

#12
MathX

MathX

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 4,001 posts
I can see that I have been a good teacher :P

Interested in participating in community events?
Want to harness your programming skill and turn it into absolute prowess?
Come join our programming events!