Advertisement
dmilicev

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.  
  48.     https://www.facebook.com/dmilicev
  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. }
Advertisement
RAW Paste Data Copied
Advertisement