# analog_clock_without_graphics_v2.c

Jan 30th, 2020
330
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. /*
2.
3.     analog_clock_without_graphics_v2.c      Author: Dragan Milicev
4.
5.     Draw a line in console window without graphics.
6.     Bresenham's line algorithm
7.     https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
8.
9.     Draw a circle in console window without graphics.
10.
11.     Equation of a line that passes through points (x1,y1) and (x2,y2)
12.     y-y1 = (y2-y1)/(x2-x1) * (x-x1)
13.
14.     Equation of a circle of radius r, whose center coordinates are p and q
15.     (x-p)^2 + (y-q)^2 = r^2
16.
17.     Equation of a circle in polar coordinates:
18.     x = p + r * cos(f)
19.     y = q + r * sin(f)
20.
21.
22.     For digital clock:
23.
24.     https://www.quora.com/How-do-I-print-a-digital-clock-in-C
25.
26.     https://stackoverflow.com/questions/9253250/need-help-understanding-how-n-b-and-r-will-render-printf-output
27.
28.     https://www.tutorialspoint.com/c-program-to-print-digital-clock-with-current-time
29.
30.
31. size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr)
32. Formats the time represented in the structure timeptr
33. according to the formatting rules defined in format and stored into str.
34. https://www.tutorialspoint.com/c_standard_library/c_function_strftime.htm
35.
36. struct tm *localtime(const time_t *timer)
37. Uses the time pointed by timer to fill a tm structure
38. with the values that represent the corresponding local time.
39. The value of timer is broken up into the structure tm
40. and expressed in the local time zone.
41. https://www.tutorialspoint.com/c_standard_library/c_function_localtime.htm
42.
43.
44.     You can find all my C programs at Dragan Milicev's pastebin:
45.
46.     https://pastebin.com/u/dmilicev
47.
49.
50. */
51.
52.
53. #include <stdio.h>
54. #include <time.h>       // for clock_t
55. #include <math.h>       // for round()
56. #include <windows.h>    // tracking cursor all the time, for cursor position functions
57.                         // gotoxy(x,y) , wherex() , wherey(), showcursor(), hidecursor()
58.
59. #define PI              3.14159
60. #define CENTER_X        40          // x coordinate of centre
61. #define CENTER_Y        12          // y coordinate of centre
62. #define CLOCK_R         11          // R is for radius
63. #define SECOND_HAND_R   9
64. #define MINUTE_HAND_R   9
65. #define HOUR_HAND_R     8
66. #define RATIO           1.7         // for aspect ratio, to avoid eclipse clock
67. #define LEN             100
68. #define ESC             27
69.
70.
71. // wait (do nothing) for time in milliseconds
72. void wait( int milliseconds )
73. {
74.     clock_t start_time = clock();       // get start time
75.
76.     // looping (do nothing) till required time is not acheived
77.     while ( clock() < start_time + milliseconds )
78.         ;                               // do nothing
79. }
80.
81.
82. // ----------CURSOR CONTROL FUNCTIONS------------------------------------------
83.
84. // make console cursor invisible
85. void hidecursor()
86. {
87.    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
88.    CONSOLE_CURSOR_INFO info;
89.    info.dwSize = 20;
90.    info.bVisible = FALSE;
91.    SetConsoleCursorInfo(consoleHandle, &info);
92. }
93.
94. // make console cursor invisible
95. void showcursor()
96. {
97.    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
98.    CONSOLE_CURSOR_INFO info;
99.    info.dwSize = 20;
100.    info.bVisible = TRUE;
101.    SetConsoleCursorInfo(consoleHandle, &info);
102. }
103.
104. // place cursor at position ( x, y ) = ( row, column )
105. void gotoxy( int x, int y )
106. {
107.     COORD coord;
108.
109.     coord.X = x;
110.     coord.Y = y;
111.
112.     SetConsoleCursorPosition( GetStdHandle(STD_OUTPUT_HANDLE), coord );
113. }
114.
115. // return x coordinate (column) of current cursor position
116. // on failure return -1
117. int wherex()
118. {
119.     CONSOLE_SCREEN_BUFFER_INFO csbi;
120.
121.     if (!GetConsoleScreenBufferInfo( GetStdHandle(STD_OUTPUT_HANDLE), &csbi ) )
122.         return -1;
123.
124.     return csbi.dwCursorPosition.X;
125. }
126.
127. // return y coordinate (row) of current cursor position
128. // on failure return -1
129. int wherey()
130. {
131.     CONSOLE_SCREEN_BUFFER_INFO csbi;
132.
133.     if (!GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &csbi ) )
134.         return -1;
135.
136.     return csbi.dwCursorPosition.Y;
137. }
138.
139. // END OF-----CURSOR CONTROL FUNCTIONS------------------------------------------
140.
141.
142. // Draw a line between two points (x0, y0) and (x1, y1)
143. // Bresenham's line algorithm
144. // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
145. void drawLine(const char *str, int x0, int y0, int x1, int y1)
146. {
147.     int dx, dy, sx, sy, err, e2;
148.
149.     dx = abs(x1-x0);
150.     sx = x0<x1 ? 1 : -1;
151.     dy = -abs(y1-y0);
152.     sy = y0<y1 ? 1 : -1;
153.     err = dx+dy;                // error value e_xy
154.
155.     while(1)
156.     {
157.         gotoxy( x0, y0 );       // move cursor to (column, row)
158.         fputs(str, stdout);     // print string str without '\n'
159.
160.         if (x0==x1 && y0==y1)
161.             break;
162.
163.         e2 = 2*err;
164.
165.         if (e2 >= dy)
166.         {
167.             err += dy;          // e_xy+e_x > 0
168.             x0 += sx;
169.         }
170.
171.         if (e2 <= dx)           // e_xy+e_y < 0
172.         {
173.             err += dx;
174.             y0 += sy;
175.         }
176.     } // while(1)
177. } // drawLine()
178.
179.
180. // Draws clock second hand and minute hand
181. void drawClockHand( char *str, float p, float q, float r, float minute )
182. {
183.     float x, y, f = minute * (PI/30)-(PI/2);    // f is angle of hand
184.
185.     x = round( p + 1.7 * r * cos(f) );
186.     y = round( q + r * sin(f) );
187.
188.     drawLine(str, p, q, x, y);
189. } // drawClockHand()
190.
191.
192. // Draws clock hour hand
193. void drawClockHourHand( char *str, float p, float q, float r, int hr, float min )
194. {
195.     float x, y, f;                              // f is angle of hand
196.
197.      // determining the angle of the line with respect to vertical
198.      if(hr<=12)
199.         f=(hr*(PI/6)-(PI/2))+((min/12)*(PI/30));
200.
201.      if(hr>12)
202.         f=((hr-12)*(PI/6)-(PI/2))+((min/12)*(PI/30));
203.
204.     x = round( p + 1.7 * r * cos(f) );
205.     y = round( q + r * sin(f) );
206.
207.     drawLine(str, p, q, x, y);
208. } // drawClockHourHand()
209.
210.
211. // Draws clock hours numbers, radius r, whose center coordinates are p and q
212. void drawClockNumbers( float p, float q, float r )
213. {
214.     int minute, hour=1;
215.     float x, y, f;
216.     char str[3];
217.
218.     for( minute=5; minute<=60; minute+=5 )      // print hours
219.     {
220.         f = minute * (PI/30)-(PI/2);
221.
222.         x = round( p + RATIO * r * cos(f) );
223.         y = round( q + r * sin(f) );
224.
225.         sprintf( str, "%d", hour++ );
226.         gotoxy( x, y );         // move cursor to (column, row)
227.         fputs(str, stdout);     // print string str without '\n'
228.     }
229. } // drawClockNumbers()
230.
231.
232.
233. int main (void)
234. {
235.     int i, memS, memM, memH, ch;        // ch is for pressed key
236.     char buf[LEN];                      // string buffer
237.     time_t curtime;                     // current local time from system
238.     struct tm *loc_time;                // tm structure for local time
239.
240.     hidecursor();
241.
242.     gotoxy( 1, 22 );                    // move cursor to (column, row)
243.     fputs("Escape for quit.", stdout);                  // print string str without '\n'
244.
245.     drawClockNumbers( CENTER_X, CENTER_Y, CLOCK_R );
246.
247.     while(1)                // an infinite loop that exits with choice Ecsape, ESC (27)
248.     {
249.         while( !_kbhit() )  // rotates in that loop until some key is pressed
250.         {
251.             curtime = time (NULL);              // reset
252.             loc_time = localtime (&curtime);    // get current local time from system
253.
254.             // print digital clock, date and time
255.
256.             // fill buf with local date and time              %I hour in 12h format (01-12)
257.             //strftime( buf, LEN, "\r Date is %d.%m.%Y. Time is %I:%M:%S %p", loc_time );
258.
259.             // or
260.
261.             // fill buf with local date and time              %H hour in 24h format (00-23)
262.             strftime( buf, LEN, "Date is %d.%m.%Y.", loc_time );
263.
264.             gotoxy( 1, 1 );         // move cursor to (column, row)
265.             fputs(buf, stdout);     // print string str without '\n'
266.
267.             // fill buf with local date and time              %H hour in 24h format (00-23)
268.             strftime( buf, LEN, "Time is %H:%M:%S ", loc_time );
269.
270.             gotoxy( 1, 3 );         // move cursor to (column, row)
271.             fputs(buf, stdout);     // print string str without '\n'
272.
273.             // print analog clock, date and time
274.
275.             // fill buf with local time, minutes
276.             strftime( buf, LEN, "%M", loc_time );
277.             i = atoi(buf);          // convert string to integer
278.             memM = i;               // memorize minutes value
279.             // draw clock hour hand
280.             drawClockHand("M", CENTER_X, CENTER_Y, MINUTE_HAND_R, i );
281.
282.             // fill buf with local time, hours
283.             strftime( buf, LEN, "%H", loc_time );
284.             i = atoi(buf);          // convert string to integer
285.             memH = i;               // memorize hour value
286.             // draw clock hour hand
287.             //drawClockHand("H", CENTER_X, CENTER_Y, HOUR_HAND_R, i );
288.             drawClockHourHand("H", CENTER_X, CENTER_Y, HOUR_HAND_R, i, (float)memM );
289.
290.             // fill buf with local time, seconds
291.             strftime( buf, LEN, "%S", loc_time );
292.             i = atoi(buf);          // convert string to integer
293.             memS = i;               // memorize seconds value
294.             // draw clock hour hand
295.             drawClockHand(".", CENTER_X, CENTER_Y, SECOND_HAND_R, i );
296.
297.             wait(1000);                 // wait 1 second = 1000 ms
298.
299.             // erase clock hands
300.             drawClockHand(" ", CENTER_X, CENTER_Y, HOUR_HAND_R,   memH );
301.             drawClockHand(" ", CENTER_X, CENTER_Y, MINUTE_HAND_R, memM );
302.             drawClockHand(" ", CENTER_X, CENTER_Y, SECOND_HAND_R, memS );
303.
304.         } // while( !_kbhit() )
305.
306.         ch = _getch();                  // now key is pressed, read the keyboard
307.
308.         if( ch == 0 || ch == 224 )      // if is pressed function key with leading 0 or 224
309.             ch = _getch();              // let's empty that 0 or 224
310.
311.         if( ch == ESC )                 // if is pressed ESC
312.         {
313.             gotoxy(0,22);               // move cursor to (column, row)
314.             showcursor();
315.             return(0);                  // end of work, have to return something
316.         }
317.
318.     } // while(1)
319.
320.    //return 0;                  // this line is never executed and is therefore commented
321. }