Guest User

Untitled

a guest
May 21st, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.67 KB | None | 0 0
  1. // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
  2. // Small example how to use the library.
  3. // For more examples, look at demo-main.cc
  4. //
  5. // This code is public domain
  6. // (but note, that the led-matrix library this depends on is GPL v2)
  7.  
  8. #include "led-matrix.h"
  9.  
  10. #include <unistd.h>
  11. #include <math.h>
  12. #include <stdio.h>
  13. #include <signal.h>
  14. #include <getopt.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <time.h>
  18.  
  19. using rgb_matrix::GPIO;
  20. using rgb_matrix::RGBMatrix;
  21. using rgb_matrix::Canvas;
  22.  
  23. // IntPoint data type
  24. struct IntPoint
  25. {
  26. int X;
  27. int Y;
  28. IntPoint(int InX, int InY)
  29. {
  30. X = InX;
  31. Y = InY;
  32. }
  33. };
  34.  
  35. // Color data type
  36. struct Color
  37. {
  38. int R;
  39. int G;
  40. int B;
  41. Color(int InR, int InG, int InB)
  42. {
  43. R = InR;
  44. G = InG;
  45. B = InB;
  46. }
  47. };
  48.  
  49. volatile bool interrupt_received = false;
  50. static void InterruptHandler(int signo) {
  51. interrupt_received = true;
  52. }
  53. /*
  54. static int abs(int n)
  55. {
  56. if (n >= 0)
  57. return n;
  58. else
  59. return n * -1;
  60. }
  61. */
  62. // Parse a string into a color
  63. static bool parseColor(Color *color, const char *str)
  64. {
  65. return sscanf(str, "%hhu,%hhu,%hhu", &color->R, &color->G, &color->B) == 3;
  66. }
  67.  
  68. // Function do draw a circle with given radius and center point
  69. static void DrawCircle(Canvas *canvas, float radius, IntPoint center, Color color)
  70. {
  71. /*float angleStep = 1.0 / 360;
  72.  
  73. for (float a = 0, r = 0; r < radius; a+= angleStep, r+= angleStep) {
  74. float dotX = cos(a * 2 * M_PI) * r;
  75. float dotY = sin(a * 2 * M_PI) * r;
  76.  
  77. canvas->SetPixel(center.X + dotX, center.Y + dotY, color.R, color.G, color.B);
  78. }*/
  79.  
  80. for (int y = -radius; y <= radius; y++)
  81. {
  82. for(int x = -radius; x <= radius; x++)
  83. {
  84. if (x*x + y*y <= radius*radius + radius * 0.8)
  85. {
  86. canvas->SetPixel(center.X + x, center.Y + y, color.R, color.G, color.B);
  87. }
  88. }
  89. }
  90. }
  91.  
  92. // Function to fill a specific area with color
  93. static void FillArea(Canvas *canvas, IntPoint topLeft, IntPoint bottomRight, Color color)
  94. {
  95. for (int x = topLeft.X; x <= bottomRight.X; x++)
  96. {
  97. for (int y = topLeft.Y; y <= bottomRight.Y; y++)
  98. {
  99. canvas->SetPixel(x, y, color.R, color.G, color.B);
  100. }
  101. }
  102. }
  103.  
  104. // Function to draw a line from point A to point B
  105. static void DrawLine(Canvas *canvas, IntPoint A, IntPoint B, Color color)
  106. {
  107. int deltaX = B.X - A.X;
  108. signed char const ix = (deltaX > 0) - (deltaX < 0);
  109. deltaX = 2 * abs(deltaX);
  110.  
  111. int deltaY = B.Y - A.Y;
  112. signed char const iy = (deltaY > 0) - (deltaY < 0);
  113. deltaY = 2 * abs(deltaY);
  114.  
  115. int x1 = A.X;
  116. int y1 = A.Y;
  117. int x2 = B.X;
  118. int y2 = B.Y;
  119.  
  120. canvas->SetPixel(x1, y1, color.R, color.G, color.B);
  121.  
  122. if (deltaX >= deltaY)
  123. {
  124. int error = deltaY - (deltaX / 2);
  125.  
  126. while (x1 != x2)
  127. {
  128. if ((error > 0) || (!error && (ix > 0)))
  129. {
  130. error -= deltaX;
  131. y1 += iy;
  132. }
  133.  
  134. error += deltaY;
  135. x1 += ix;
  136.  
  137. canvas->SetPixel(x1, y1, color.R, color.G, color.B);
  138. }
  139. }
  140. else
  141. {
  142. int error = deltaX - (deltaY / 2);
  143.  
  144. while (y1 != y2)
  145. {
  146. if ((error > 0) || (!error && (iy > 0)))
  147. {
  148. error -= deltaY;
  149. x1 += ix;
  150. }
  151.  
  152. error += deltaX;
  153. y1 += iy;
  154.  
  155. canvas->SetPixel(x1, y1, color.R, color.G, color.B);
  156. }
  157. }
  158. }
  159.  
  160. static IntPoint CalculatePointerEndPoint(float progress, int pointerLength, IntPoint origin)
  161. {
  162. IntPoint result = IntPoint(0,0);
  163.  
  164. result.X = origin.X + pointerLength * cos((progress * 2 * M_PI) - M_PI / 2);
  165. result.Y = origin.Y + pointerLength * sin((progress * 2 * M_PI) - M_PI / 2);
  166.  
  167. //printf("Progress: %f, Angle: %f, nPi: %f, res: %d,%d\n", progress, progress * 360.0, progress * 2 * M_PI, result.X, result.Y);
  168.  
  169. return result;
  170. }
  171.  
  172. static void printUsage()
  173. {
  174. printf("Invalid command line. Options:\n");
  175. printf("\t-o <r,g,b> : Clock circle and center point color. Default 255,0,0.\n");
  176. printf("\t-h <r,g,b> : Hour pointer color. Default 0,255,0.\n");
  177. printf("\t-m <r,g,b> : Minute pointer color. Default 0,255,0.\n");
  178. printf("\t-s <r,g,b> : Second pointer color. Default 0,0,255.\n");
  179. printf("\t-r <radius> : Clock radius. Default 25.\n");
  180. printf("\t-d <depth> : Outer circle depth. Default 2.\n");
  181. }
  182.  
  183. // Main function
  184. int main(int argc, char *argv[])
  185. {
  186. // Set up display
  187. RGBMatrix::Options defaults;
  188. defaults.hardware_mapping = "regular"; // or e.g. "adafruit-hat"
  189. defaults.rows = 64;
  190. defaults.chain_length = 2;
  191. defaults.parallel = 1;
  192. defaults.show_refresh_rate = true;
  193.  
  194. Canvas *canvas = rgb_matrix::CreateMatrixFromFlags(&argc, &argv, &defaults);
  195. if (canvas == NULL)
  196. return 1;
  197.  
  198. // Adjustable settings
  199. Color outlineColor = Color(255,0,0);
  200. Color hourPointerColor = Color(0,255,0);
  201. Color minPointerColor = Color(0,255,0);
  202. Color secPointerColor = Color(0,0,255);
  203. int clockRadius = 25;
  204. int circleDepth = 2;
  205.  
  206. int opt;
  207. while ((opt = getopt(argc, argv, "o:h:m:s:r:d:")) != -1)
  208. {
  209. switch(opt)
  210. {
  211. case 'o':
  212. if (!parseColor(&outlineColor, optarg))
  213. {
  214. printf("Invalid outline color: %s\n", optarg);
  215. printUsage();
  216. }
  217. break;
  218. case 'h':
  219. if (!parseColor(&hourPointerColor, optarg))
  220. {
  221. printf("Invalid hour pointer color: %s\n", optarg);
  222. printUsage();
  223. }
  224. break;
  225. case 'm':
  226. if (!parseColor(&minPointerColor, optarg))
  227. {
  228. printf("Invalid min pointer color: %s\n", optarg);
  229. printUsage();
  230. }
  231. break;
  232. case 's':
  233. if (!parseColor(&secPointerColor, optarg))
  234. {
  235. printf("Invalid sec pointer color: %s\n", optarg);
  236. printUsage();
  237. }
  238. break;
  239. case 'r': clockRadius = atoi(optarg); break;
  240. case 'd': circleDepth = atoi(optarg); break;
  241. default:
  242. printUsage();
  243. break;
  244. }
  245. }
  246.  
  247. // Set up interrupt handlers
  248. signal(SIGTERM, InterruptHandler);
  249. signal(SIGINT, InterruptHandler);
  250.  
  251. IntPoint centerOfScreen = IntPoint(canvas->width() / 2, canvas->height() / 2);
  252.  
  253. // Draw clock circle
  254. DrawCircle(canvas, clockRadius, centerOfScreen, outlineColor);
  255. DrawCircle(canvas, clockRadius - circleDepth, centerOfScreen, Color(0,0,0));
  256.  
  257. // Draw center clock point
  258. FillArea(canvas, IntPoint(centerOfScreen.X - 1, centerOfScreen.Y - 1), IntPoint(centerOfScreen.X + 1, centerOfScreen.Y + 1), Color(255,0,0));
  259.  
  260. struct timespec next_time;
  261. next_time.tv_sec = time(NULL);
  262. next_time.tv_nsec = 0;
  263. struct tm tm;
  264.  
  265. IntPoint lastHourPointerEnd = IntPoint(0,0);
  266.  
  267. while (!interrupt_received)
  268. {
  269. localtime_r(&next_time.tv_sec, &tm);
  270.  
  271. // Remove pointers from last tick
  272. DrawLine(canvas, centerOfScreen, lastHourPointerEnd, Color(0,0,0));
  273. DrawLine(canvas, centerOfScreen, CalculatePointerEndPoint((tm.tm_min - 1) / 60.0, clockRadius - 5, centerOfScreen), Color(0,0,0));
  274. DrawLine(canvas, centerOfScreen, CalculatePointerEndPoint((tm.tm_sec - 1) / 60.0, clockRadius - 8, centerOfScreen), Color(0,0,0));
  275.  
  276. // Draw new pointers
  277. lastHourPointerEnd = CalculatePointerEndPoint((tm.tm_hour / 12.0) + (tm.tm_min / 600.0), clockRadius - 11, centerOfScreen);
  278. DrawLine(canvas, centerOfScreen, lastHourPointerEnd, hourPointerColor);
  279. DrawLine(canvas, centerOfScreen, CalculatePointerEndPoint(tm.tm_min / 60.0, clockRadius - 5, centerOfScreen), minPointerColor);
  280. DrawLine(canvas, centerOfScreen, CalculatePointerEndPoint(tm.tm_sec / 60.0, clockRadius - 8, centerOfScreen), secPointerColor);
  281.  
  282. // Draw center point on top
  283. FillArea(canvas, IntPoint(centerOfScreen.X - 1, centerOfScreen.Y - 1), IntPoint(centerOfScreen.X + 1, centerOfScreen.Y + 1), outlineColor);
  284.  
  285. // Sleep for a second
  286. clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next_time, NULL);
  287. next_time.tv_sec += 1;
  288. }
  289.  
  290. canvas->Clear();
  291. delete canvas;
  292.  
  293. return 0;
  294. }
Add Comment
Please, Sign In to add comment