TouchEventVisualizer.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using bbiwarg.Recognition.TouchRecognition;
  9. using bbiwarg.Utility;
  10. namespace bbiwarg.Graphics
  11. {
  12. class TouchEventVisualizer
  13. {
  14. public OutputImage OutputImage { get; private set; }
  15. private int width, height;
  16. private Stopwatch timer;
  17. private Dictionary<int, int> idTranslations;
  18. private Dictionary<int, List<Vector2D>> positions;
  19. private Dictionary<int, long> lastUpdates;
  20. private int nextFreeID;
  21. private int lastUpdated;
  22. private bool active;
  23. public TouchEventVisualizer(int width, int height)
  24. {
  25. this.width = width;
  26. this.height = height;
  27. reset();
  28. }
  29. public void reset()
  30. {
  31. timer = new Stopwatch();
  32. timer.Start();
  33. nextFreeID = 1;
  34. lastUpdated = 0;
  35. active = false;
  36. idTranslations = new Dictionary<int, int>();
  37. positions = new Dictionary<int, List<Vector2D>>();
  38. lastUpdates = new Dictionary<int, long>();
  39. }
  40. public void touchDown(object sender, TouchEventArgs tea)
  41. {
  42. int id = nextFreeID;
  43. nextFreeID++;
  44. idTranslations.Add(tea.TrackID, id);
  45. positions.Add(id, new List<Vector2D>());
  46. positions[id].Add(tea.RelativePosition);
  47. lastUpdates.Add(id, timer.ElapsedMilliseconds);
  48. lastUpdated = id;
  49. active = true;
  50. }
  51. public void touchMove(object sender, TouchEventArgs tea)
  52. {
  53. int id = idTranslations[tea.TrackID];
  54. positions[id].Add(tea.RelativePosition);
  55. lastUpdates[id] = timer.ElapsedMilliseconds;
  56. lastUpdated = id;
  57. }
  58. public void touchUp(object sender, TouchEventArgs tea)
  59. {
  60. int id = idTranslations[tea.TrackID];
  61. positions[id].Add(tea.RelativePosition);
  62. lastUpdates[id] = timer.ElapsedMilliseconds;
  63. lastUpdated = id;
  64. idTranslations.Remove(tea.TrackID);
  65. }
  66. public void updateImage()
  67. {
  68. //remove old positions
  69. long currentTime = timer.ElapsedMilliseconds;
  70. List<int> ids = new List<int>(lastUpdates.Keys);
  71. for (int i = ids.Count - 1; i >= 0; i--) {
  72. int id = ids[i];
  73. if (currentTime - lastUpdates[id] > Parameters.TouchEventVisualizerFadeOutTime) {
  74. positions.Remove(id);
  75. lastUpdates.Remove(id);
  76. if (id == lastUpdated)
  77. active = false;
  78. }
  79. }
  80. OutputImage = new OutputImage(width, height);
  81. //border
  82. OutputImage.drawRectangle(0, 0, width - 1, height - 1, Parameters.TouchEventVisualizerGridColor);
  83. //draw grid
  84. int numRows = Parameters.PalmGridNumRows;
  85. int numColumns = Parameters.PalmGridNumColumns;
  86. int widthPerColumn = width / numColumns;
  87. int heightPerRow = height / numRows;
  88. int activeRow = -1;
  89. int activeCol = -1;
  90. if (active && numRows*numColumns > 1) {
  91. Vector2D position = positions[lastUpdated][positions[lastUpdated].Count-1];
  92. activeRow = (int)Math.Floor(position.Y * Parameters.PalmGridNumRows);
  93. activeCol = (int)Math.Floor(position.X * Parameters.PalmGridNumColumns);
  94. }
  95. for (int i = 0; i <= numColumns; i++)
  96. {
  97. OutputImage.drawLineSegment(new LineSegment2D(new Vector2D(i * widthPerColumn, 0), new Vector2D(i * widthPerColumn, height - 1)), Parameters.TouchEventVisualizerGridColor);
  98. }
  99. for (int i = 0; i <= numRows; i++)
  100. {
  101. OutputImage.drawLineSegment(new LineSegment2D(new Vector2D(0, i * heightPerRow), new Vector2D(width - 1, i * heightPerRow)), Parameters.TouchEventVisualizerGridColor);
  102. }
  103. for (int row = 0; row < numRows; row++) {
  104. for (int col = 0; col < numColumns; col++) {
  105. if(row == activeRow && col == activeCol)
  106. OutputImage.fillRectangle(col*widthPerColumn, row*heightPerRow, widthPerColumn, heightPerRow, Parameters.TouchEventVisualizerActiveBlockColor);
  107. int x = (int)((col+0.5f)*widthPerColumn)-5;
  108. int y = (int)((row+0.5f)*heightPerRow)+5;
  109. OutputImage.drawText(x,y,(1+row*numColumns+col).ToString(),Parameters.TouchEventVisualizerTextColor);
  110. }
  111. }
  112. foreach (int id in positions.Keys)
  113. drawTouchGesture(positions[id], 1 - ((currentTime - lastUpdates[id]) / (float)Parameters.TouchEventVisualizerFadeOutTime));
  114. }
  115. public void drawTouchGesture(List<Vector2D> positions, float opacity)
  116. {
  117. Vector2D maxPixel = new Vector2D(width - 1, height - 1);
  118. int numPositions = positions.Count;
  119. Color lineColor = Parameters.TouchEventVisualizerLineColor;
  120. Color pointColor = Parameters.TouchEventVisualizerPointColor;
  121. Color lineColorFaded = Color.FromArgb((int)(opacity * lineColor.R), (int)(opacity * lineColor.G), (int)(opacity * lineColor.B));
  122. Color pointColorFaded = Color.FromArgb((int)(opacity * pointColor.R), (int)(opacity * pointColor.G), (int)(opacity * pointColor.B));
  123. for (int i = 1; i < numPositions; i++)
  124. {
  125. OutputImage.drawLineSegment(new LineSegment2D(positions[i - 1].scale(maxPixel), positions[i].scale(maxPixel)), lineColorFaded);
  126. }
  127. Vector2D lastPos = positions[numPositions - 1].scale(maxPixel);
  128. OutputImage.fillCircle(lastPos.IntX, lastPos.IntY, 3, pointColorFaded);
  129. }
  130. }
  131. }