ShapeCorners.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. namespace ChunkyImageLib.DataHolders;
  2. public struct ShapeCorners
  3. {
  4. public ShapeCorners(Vector2d center, Vector2d size, double angle)
  5. {
  6. TopLeft = center - size / 2;
  7. TopRight = center + new Vector2d(size.X / 2, -size.Y / 2);
  8. BottomRight = center + size / 2;
  9. BottomLeft = center + new Vector2d(-size.X / 2, size.Y / 2);
  10. }
  11. public ShapeCorners(Vector2d topLeft, Vector2d size)
  12. {
  13. TopLeft = topLeft;
  14. TopRight = new(topLeft.X + size.X, topLeft.Y);
  15. BottomRight = topLeft + size;
  16. BottomLeft = new(topLeft.X, topLeft.Y + size.Y);
  17. }
  18. public Vector2d TopLeft { get; set; }
  19. public Vector2d TopRight { get; set; }
  20. public Vector2d BottomLeft { get; set; }
  21. public Vector2d BottomRight { get; set; }
  22. public bool IsLegal
  23. {
  24. get
  25. {
  26. var top = TopLeft - TopRight;
  27. var right = TopRight - BottomRight;
  28. var bottom = BottomRight - BottomLeft;
  29. var left = BottomLeft - TopLeft;
  30. var topRight = Math.Sign(top.Cross(right));
  31. return topRight == Math.Sign(right.Cross(bottom)) && topRight == Math.Sign(bottom.Cross(left)) && topRight == Math.Sign(left.Cross(top));
  32. }
  33. }
  34. public bool HasNaNOrInfinity => TopLeft.IsNaNOrInfinity() || TopRight.IsNaNOrInfinity() || BottomLeft.IsNaNOrInfinity() || BottomRight.IsNaNOrInfinity();
  35. public bool IsRect => Math.Abs((TopLeft - BottomRight).Length - (TopRight - BottomLeft).Length) < 0.001;
  36. public Vector2d RectSize => new((TopLeft - TopRight).Length, (TopLeft - BottomLeft).Length);
  37. public Vector2d RectCenter => (TopLeft - BottomRight) / 2 + BottomRight;
  38. public double RectRotation =>
  39. (TopLeft - TopRight).Cross(TopLeft - BottomLeft) > 0 ?
  40. RectSize.CCWAngleTo(BottomRight - TopLeft) :
  41. RectSize.CCWAngleTo(BottomLeft - TopRight);
  42. public bool IsSnappedToPixels
  43. {
  44. get
  45. {
  46. double epsilon = 0.01;
  47. return
  48. (TopLeft - TopLeft.Round()).TaxicabLength < epsilon &&
  49. (TopRight - TopRight.Round()).TaxicabLength < epsilon &&
  50. (BottomLeft - BottomLeft.Round()).TaxicabLength < epsilon &&
  51. (BottomRight - BottomRight.Round()).TaxicabLength < epsilon;
  52. }
  53. }
  54. public bool IsPointInside(Vector2d point)
  55. {
  56. var top = TopLeft - TopRight;
  57. var right = TopRight - BottomRight;
  58. var bottom = BottomRight - BottomLeft;
  59. var left = BottomLeft - TopLeft;
  60. var deltaTopLeft = point - TopLeft;
  61. var deltaTopRight = point - TopRight;
  62. var deltaBottomRight = point - BottomRight;
  63. var deltaBottomLeft = point - BottomLeft;
  64. if (deltaTopRight.IsNaNOrInfinity() || deltaTopLeft.IsNaNOrInfinity() || deltaBottomRight.IsNaNOrInfinity() || deltaBottomRight.IsNaNOrInfinity())
  65. return false;
  66. var crossTop = Math.Sign(top.Cross(deltaTopLeft));
  67. var crossRight = Math.Sign(right.Cross(deltaTopRight));
  68. var crossBottom = Math.Sign(bottom.Cross(deltaBottomRight));
  69. var crossLeft = Math.Sign(left.Cross(deltaBottomLeft));
  70. return crossTop == crossRight && crossTop == crossLeft && crossTop == crossBottom;
  71. }
  72. }