GeometryCalculator.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. /// <summary>
  10. /// A class that contains all algorithms related to geometry.
  11. /// </summary>
  12. public static class GeometryCalculator
  13. {
  14. /// <summary>
  15. /// A simple algorithm that returns a filled circle with a radius and a center point.
  16. /// </summary>
  17. /// <param name="center">The center point of the alorithm </param>
  18. /// <param name="radius">The radius of the circle, if its less or equal to 1
  19. /// only the center point is returned. </param>
  20. /// <returns>All the points in or on the circle.</returns>
  21. public static HashSet<Point> FilledCircleAlgorithm(Point center, int radius)
  22. {
  23. HashSet<Point> returnSet = new HashSet<Point> { center };
  24. //Fill the circle
  25. for (int x = 0; x < radius; x++)
  26. {
  27. for (int y = 0; y < radius; y++)
  28. {
  29. //Check if point is on or in the circle
  30. if ((x * x + y * y - radius * radius) <= 0)
  31. {
  32. returnSet.Add(new Point(center.X + x, center.Y + y));
  33. returnSet.Add(new Point(center.X - x, center.Y + y));
  34. returnSet.Add(new Point(center.X + x, center.Y - y));
  35. returnSet.Add(new Point(center.X - x, center.Y - y));
  36. }
  37. }
  38. }
  39. return returnSet;
  40. }
  41. /// <summary>
  42. /// An implementation of the Bresenham Line Algorithm,
  43. /// which calculates all points between two points in a straight line.
  44. /// Implemented using the pseudocode on Wikipedia.
  45. /// </summary>
  46. /// <param name="p0">The start point</param>
  47. /// <param name="p1">The end point</param>
  48. /// <returns>All points between p0 and p1 (including p0 and p1)</returns>
  49. public static List<Point> BresenhamLineAlgorithm(Point p0, Point p1)
  50. {
  51. int p1x = (int)p1.X;
  52. int p1y = (int)p1.Y;
  53. int p0x = (int)p0.X;
  54. int p0y = (int)p0.Y;
  55. int deltaX = p1x - p0x;
  56. int deltaY = p1y - p0y;
  57. List<Point> returnList;
  58. if (Math.Abs(deltaY) < Math.Abs(deltaX))
  59. {
  60. if (p0.X > p1.X)
  61. {
  62. returnList = GetLineLow(p1x, p1y, p0x, p0y);
  63. returnList.Reverse();
  64. }
  65. else
  66. {
  67. returnList = GetLineLow(p0x, p0y, p1x, p1y);
  68. }
  69. }
  70. else
  71. {
  72. if (p0.Y > p1.Y)
  73. {
  74. returnList = GetLineHigh(p1x, p1y, p0x, p0y);
  75. returnList.Reverse();
  76. }
  77. else
  78. {
  79. returnList = GetLineHigh(p0x, p0y, p1x, p1y);
  80. }
  81. }
  82. return returnList;
  83. }
  84. /// <summary>
  85. /// Helping function of the Bresenham Line algorithm,
  86. /// under the assumption that abs(deltaY) is smaller than abs(deltX)
  87. /// and x0 is smaller than x1
  88. /// </summary>
  89. /// <param name="x0">x value of point 0</param>
  90. /// <param name="y0">y value of point 0</param>
  91. /// <param name="x1">x value of point 1</param>
  92. /// <param name="y1">y value of point 1</param>
  93. /// <returns>All points on the line between the two points</returns>
  94. private static List<Point> GetLineLow(int x0, int y0, int x1, int y1)
  95. {
  96. List<Point> returnList = new List<Point>();
  97. int dx = x1 - x0;
  98. int dy = y1 - y0;
  99. int yi = 1;
  100. if (dy < 0)
  101. {
  102. yi = -1;
  103. dy = -dy;
  104. }
  105. int D = 2 * dy - dx;
  106. int y = y0;
  107. for (int x = x0; x <= x1; x++)
  108. {
  109. returnList.Add(new Point(x, y));
  110. if (D > 0)
  111. {
  112. y = y + yi;
  113. D = D - 2 * dx;
  114. }
  115. D = D + 2 * dy;
  116. }
  117. return returnList;
  118. }
  119. /// <summary>
  120. /// Helping function of the Bresenham Line algorithm,
  121. /// under the assumption that abs(deltaY) is larger or equal than abs(deltX)
  122. /// and y0 is smaller than y1
  123. /// </summary>
  124. /// <param name="x0">x value of point 0</param>
  125. /// <param name="y0">y value of point 0</param>
  126. /// <param name="x1">x value of point 1</param>
  127. /// <param name="y1">y value of point 1</param>
  128. /// <returns>All points on the line between the two points</returns>
  129. private static List<Point> GetLineHigh(int x0, int y0, int x1, int y1)
  130. {
  131. List<Point> returnList = new List<Point>();
  132. int dx = x1 - x0;
  133. int dy = y1 - y0;
  134. int xi = 1;
  135. if (dx < 0)
  136. {
  137. xi = -1;
  138. dx = -dx;
  139. }
  140. int D = 2 * dx - dy;
  141. int x = x0;
  142. for (int y = y0; y <= y1; y++)
  143. {
  144. returnList.Add(new Point(x, y));
  145. if (D > 0)
  146. {
  147. x = x + xi;
  148. D = D - 2 * dy;
  149. }
  150. D = D + 2 * dx;
  151. }
  152. return returnList;
  153. }
  154. }
  155. }