TrajectoryGenerator.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace SketchAssistantWPF
  8. {
  9. class TrajectoryGenerator
  10. {
  11. static int constantA= 10;
  12. InternalLine currentLine;
  13. List<Point> currentPoints;
  14. Point lastCursorPosition;
  15. int index;
  16. public void setCurrentLine(InternalLine newCurrentLine)
  17. {
  18. currentLine = newCurrentLine;
  19. currentPoints = currentLine.GetPoints();
  20. lastCursorPosition = currentPoints.ElementAt(0);
  21. index = 1;
  22. }
  23. public int GenerateTrajectory(Point cursorPosition)
  24. {
  25. //update index to point to current section if one or more section divideing lines have been passed since last call
  26. while (index < (currentPoints.Count - 1) && SectionDividingLinePassed(lastCursorPosition, cursorPosition, currentPoints.ElementAt(index - 1), currentPoints.ElementAt(index), currentPoints.ElementAt(index + 1)))
  27. {
  28. index++;
  29. }
  30. lastCursorPosition = cursorPosition;
  31. //project teh point onto the active line segment to be able to compute distances
  32. Point orthogonalProjection = ComputeOrthogonalProjection(cursorPosition, currentPoints.ElementAt(index - 1), currentPoints.ElementAt(index));
  33. //index of the last reachable actual point
  34. int targetIndex = index;
  35. List<Tuple<Point, Point>> strikeZones = new List<Tuple<Point, Point>>();
  36. //if "far" away from the next actual point of the line, generate an auxiliary point at a constant distance (constantA) on the current line segment
  37. Point auxiliaryPoint = null;
  38. if (ComputeDistance(orthogonalProjection, currentPoints.ElementAt(index)) <= constantA)
  39. {
  40. auxiliaryPoint = moveAlongLine(orthogonalProjection, currentPoints.ElementAt(index - 1), currentPoints.ElementAt(index), constantA);
  41. strikeZones.Add(computeStrikeZone(auxiliaryPoint, orthogonalProjection, cursorPosition));
  42. targetIndex--;
  43. }
  44. //aim for the furthest actual point of the line reachable by the descent rate constraints (lower bounds) given by the various strike zones
  45. while (targetIndex < (currentPoints.Count - 1) && allStrikeZonesPassed(strikeZones, cursorPosition, currentPoints.ElementAt(targetIndex + 1)))
  46. {
  47. strikeZones.Add(computeStrikeZone(currentPoints.ElementAt(targetIndex + 1), orthogonalProjection, cursorPosition));
  48. targetIndex++;
  49. }
  50. Point furthestCrossingPoint = null;
  51. if (targetIndex < index) //auxiliary point created and next actual point not reachable
  52. {
  53. furthestCrossingPoint = ComputeFurthestCrossingPoint(cursorPosition, strikeZones, auxiliaryPoint, currentPoints.ElementAt(targetIndex + 1));
  54. //if such a point exists, use it as target for the new trajectory
  55. if (furthestCrossingPoint != null)
  56. {
  57. Debug_DrawStrikeZones(strikeZones);
  58. Debug_DrawTrajectoryVector(cursorPosition, furthestCrossingPoint);
  59. return computeOrientationOfVector(cursorPosition, furthestCrossingPoint);
  60. }
  61. //else use the last reachable actual point
  62. else
  63. {
  64. Debug_DrawStrikeZones(strikeZones);
  65. Debug_DrawTrajectoryVector(cursorPosition, auxiliaryPoint);
  66. return computeOrientationOfVector(cursorPosition, auxiliaryPoint);
  67. }
  68. }
  69. else
  70. {
  71. //aim for the furthest (auxiliary) point on the line segment after the last reachable actual point (only if there is such a segment: not if that last reachable point is the last point of the line)
  72. if (targetIndex < (currentPoints.Count - 1))
  73. {
  74. furthestCrossingPoint = ComputeFurthestCrossingPoint(cursorPosition, strikeZones, currentPoints.ElementAt(targetIndex), currentPoints.ElementAt(targetIndex + 1));
  75. }
  76. //if such a point exists, use it as target for the new trajectory
  77. if (furthestCrossingPoint != null)
  78. {
  79. Debug_DrawStrikeZones(strikeZones);
  80. Debug_DrawTrajectoryVector(cursorPosition, furthestCrossingPoint);
  81. return computeOrientationOfVector(cursorPosition, furthestCrossingPoint);
  82. }
  83. //else use the last reachable actual point
  84. else
  85. {
  86. Debug_DrawStrikeZones(strikeZones);
  87. Debug_DrawTrajectoryVector(cursorPosition, currentPoints.ElementAt(targetIndex));
  88. return computeOrientationOfVector(cursorPosition, currentPoints.ElementAt(targetIndex));
  89. }
  90. }
  91. }
  92. /// <summary>
  93. /// prints the trajectory vector on the drawing pane for debugging and calibration purposes
  94. /// </summary>
  95. /// <param name="vectorStartPoint">origin point of the trajectory vector</param>
  96. /// <param name="vectorEndPoint">target point of the trajectory vector</param>
  97. private void Debug_DrawTrajectoryVector(Point vectorStartPoint, Point vectorEndPoint)
  98. {
  99. throw new NotImplementedException();
  100. }
  101. /// <summary>
  102. /// prints all strike zones on the drawing pane for debugging and calibration purposes
  103. /// </summary>
  104. /// <param name="strikeZones">list of all strike zones to be drawn</param>
  105. private void Debug_DrawStrikeZones(List<Tuple<Point, Point>> strikeZones)
  106. {
  107. throw new NotImplementedException();
  108. }
  109. /// <summary>
  110. /// computes the orientation of the given vector on the drawing plane
  111. /// </summary>
  112. /// <param name="vectorStartPoint">origin point of the direction vector</param>
  113. /// <param name="vectorEndPoint">target point of the direction vector</param>
  114. /// <returns>the orientation angle, in degree format</returns>
  115. private int computeOrientationOfVector(Point vectorStartPoint, Point vectorEndPoint)
  116. {
  117. throw new NotImplementedException();
  118. }
  119. /// <summary>
  120. /// computes the furthest point on the given line segment that will still pass all previous strike zones when connecting it with the current cursor position in a straight line
  121. /// </summary>
  122. /// <param name="cursorPosition">the current cursor position</param>
  123. /// <param name="strikeZones">list of all strike zones which have to be passed</param>
  124. /// <param name="lineSegmentStartPoint">starting point of the line segment on which the point has to be found</param>
  125. /// <param name="lineSegmentEndPoint">ending point of the line segment on which the point has to be found</param>
  126. /// <returns>the furthest such point or null, if there is no such point on the given segment (start and end point excluded)</returns>
  127. private Point ComputeFurthestCrossingPoint(Point cursorPosition, List<Tuple<Point, Point>> strikeZones, Point lineSegmentStartPoint, Point lineSegmentEndPoint)
  128. {
  129. throw new NotImplementedException();
  130. }
  131. /// <summary>
  132. /// checks if all strike zones are passed by the trajectory given by the straight line from the cursor position to the next target point
  133. /// </summary>
  134. /// <param name="strikeZones">list of all already computed strike zones</param>
  135. /// <param name="cursorPosition">the current cursor position</param>
  136. /// <param name="targetIndex">index of the next target point</param>
  137. /// <returns>true if all strike zones are passed, else false</returns>
  138. private bool allStrikeZonesPassed(List<Tuple<Point, Point>> strikeZones, Point cursorPosition, Point targetIndex)
  139. {
  140. throw new NotImplementedException();
  141. }
  142. /// <summary>
  143. /// computes the strike zone for a point using the cursor position, its orthogonal projection onto the active line segment and tunable constants
  144. /// </summary>
  145. /// <param name="targetedPoint">the point to compute the strike zone of</param>
  146. /// <param name="orthogonalProjection">orthogonal projection of the cursor position onto the active line segment</param>
  147. /// <param name="cursorPosition">the current cursor position</param>
  148. /// <returns></returns>
  149. private Tuple<Point, Point> computeStrikeZone(Point targetedPoint, Point orthogonalProjection, Point cursorPosition)
  150. {
  151. throw new NotImplementedException();
  152. }
  153. /// <summary>
  154. /// moves a point a given distance along a vector defined by two points
  155. /// </summary>
  156. /// <param name="pointToBeMoved">the point to be moved along the line</param>
  157. /// <param name="lineStartPoint">origin point of the direction vector</param>
  158. /// <param name="lineEndPoint">target point of the direction vector</param>
  159. /// <param name="distance">distance by which to move the point</param>
  160. /// <returns>a new point that is located distance away from pointToBeMoved in the direction of the given vector</returns>
  161. private Point moveAlongLine(Point pointToBeMoved, Point lineStartPoint, Point lineEndPoint, int distance)
  162. {
  163. throw new NotImplementedException();
  164. }
  165. /// <summary>
  166. /// computes the euclidean distance between two points
  167. /// </summary>
  168. /// <param name="point1">point 1</param>
  169. /// <param name="point2">point 2</param>
  170. /// <returns>euclidean distance between point1 and point2</returns>
  171. private int ComputeDistance(Point point1, Point point2)
  172. {
  173. throw new NotImplementedException();
  174. }
  175. private Point ComputeOrthogonalProjection(Point cursorPosition, Point lastPoint, Point currentPoint)
  176. {
  177. throw new NotImplementedException();
  178. }
  179. private bool SectionDividingLinePassed(Point lastCursorPosition, Point cursorPosition, Point lastPoint, Point currentPoint, Point nextPoint)
  180. {
  181. throw new NotImplementedException();
  182. }
  183. }
  184. }