Line2D.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace bbiwarg.Utility
  7. {
  8. public enum LineSide {
  9. onLine = 0,
  10. above = 1,
  11. below = 2
  12. }
  13. class Line2D
  14. {
  15. private Vector2D p1;
  16. private Vector2D p2;
  17. private Vector2D direction;
  18. private float length;
  19. private int numCombinedLines;
  20. public Vector2D P1 { get { return p1; } private set { p1 = value; } }
  21. public Vector2D P2 { get { return p2; } private set { p2 = value; } }
  22. public Vector2D Direction { get { return direction; } private set { direction = value; } }
  23. public float Length { get { return length; } private set { length = value; } }
  24. public int NumCombinedLines { get { return numCombinedLines; } private set { numCombinedLines = value; } }
  25. public Line2D(Vector2D p1, Vector2D p2) {
  26. setPoints(p1, p2);
  27. NumCombinedLines = 1;
  28. }
  29. private void setPoints(Vector2D p1, Vector2D p2) {
  30. //endpoints
  31. P1 = p1;
  32. P2 = p2;
  33. //direction
  34. direction = (P1-P2).normalize();
  35. //length
  36. Length = P1.getDistanceTo(P2);
  37. }
  38. public float getAngleBetween(Line2D line) {
  39. float angle = direction.getAngleBetween(line.Direction);
  40. return Math.Min(angle, 180-angle);
  41. }
  42. public float getParallelDistanceTo(Line2D line) {
  43. if (onSide(line.P1) != onSide(line.P2)) return 0;
  44. Vector2D a1 = projectToLine(line.P1);
  45. Vector2D a2 = projectToLine(line.P2);
  46. float distanceA1 = a1.getDistanceTo(line.P1);
  47. float distanceA2 = a2.getDistanceTo(line.P2);
  48. return Math.Min(distanceA1, distanceA2);
  49. }
  50. public float getVerticalDistanceTo(Line2D line) {
  51. Vector2D a1 = projectToLine(line.P1);
  52. Vector2D a2 = projectToLine(line.P2);
  53. if (P1.isInBox(a1, a2) || P2.isInBox(a1, a2)) return 0;
  54. float distanceP1A1 = P1.getDistanceTo(a1);
  55. float distanceP1A2 = P1.getDistanceTo(a2);
  56. float distanceP2A1 = p2.getDistanceTo(a1);
  57. float distanceP2A2 = p2.getDistanceTo(a2);
  58. return Math.Min(Math.Min(distanceP1A1, distanceP1A2), Math.Min(distanceP2A1, distanceP2A2));
  59. }
  60. public LineSide onSide(Vector2D point) {
  61. float yPerX = direction.Y / direction.X;
  62. float xDiff = point.X - P1.X;
  63. float newY = P1.Y + yPerX * xDiff;
  64. if (newY < point.Y) return LineSide.above;
  65. else if (newY > point.Y) return LineSide.below;
  66. else return LineSide.onLine;
  67. }
  68. public Vector2D projectToLine(Vector2D point) {
  69. float px = point.X, py = point.Y, dx = Direction.X, dy = Direction.Y, ox = P1.X, oy = P1.Y;
  70. float diffx = px - ox;
  71. float diffy = py - oy;
  72. float diff_d = (diffx * dx + diffy * dy);
  73. float d_d = (dx * dx + dy * dy);
  74. float q = diff_d / d_d;
  75. float newX = ox + q * dx;
  76. float newY = oy + q * dy;
  77. return new Vector2D(newX, newY);
  78. }
  79. public override string ToString()
  80. {
  81. return (int)P1.X + "|" + (int)P1.Y + " --- " + (int)P2.X + "|" + (int)P2.Y;
  82. }
  83. }
  84. }