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


Sign In
Create Account



Back to top










