geom.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. export function getRectCenter(rect) {
  2. return buildPoint(
  3. rect.left + rect.width / 2,
  4. rect.top + rect.height / 2
  5. )
  6. }
  7. export function intersectRects(rect0, rect1) {
  8. return buildRectViaEdges(
  9. Math.max(rect0.left, rect1.left),
  10. Math.max(rect0.top, rect1.top),
  11. Math.min(rect0.right, rect1.right),
  12. Math.min(rect0.bottom, rect1.bottom)
  13. )
  14. }
  15. export function joinRects(rect1, rect2) {
  16. return {
  17. left: Math.min(rect1.left, rect2.left),
  18. right: Math.max(rect1.right, rect2.right),
  19. top: Math.min(rect1.top, rect2.top),
  20. bottom: Math.max(rect1.bottom, rect2.bottom)
  21. }
  22. }
  23. function buildRectViaEdges(left, top, right, bottom) {
  24. return {
  25. left: left,
  26. top: top,
  27. width: right - left,
  28. height: bottom - top,
  29. right: right,
  30. bottom: bottom
  31. }
  32. }
  33. function buildPoint(left, top) {
  34. return {
  35. left: left,
  36. top: top
  37. }
  38. }
  39. export function subtractPoints(point1, point0) {
  40. return buildPoint(
  41. point1.left - point0.left,
  42. point1.top - point0.top
  43. )
  44. }
  45. export function addPoints(point0, point1) {
  46. return buildPoint(
  47. point0.left + point1.left,
  48. point0.top + point1.top
  49. )
  50. }
  51. export function getRectTopLeft(rect) {
  52. return buildPoint(rect.left, rect.top)
  53. }
  54. export function isRect(input) {
  55. return typeof input === 'object' && 'left' in input && 'right' in input && 'top' in input && 'bottom' in input
  56. }
  57. export function isRectMostlyAbove(subjectRect, otherRect) {
  58. return (subjectRect.bottom - otherRect.top) < // overlap is less than
  59. ((subjectRect.bottom - subjectRect.top) / 2) // half the height
  60. }
  61. export function isRectMostlyLeft(subjectRect, otherRect) {
  62. return (subjectRect.right - otherRect.left) < // overlap is less then
  63. ((subjectRect.right - subjectRect.left) / 2) // half the width
  64. }
  65. export function isRectMostlyBounded(subjectRect, boundRect) {
  66. return isRectMostlyHBounded(subjectRect, boundRect) &&
  67. isRectMostlyVBounded(subjectRect, boundRect)
  68. }
  69. export function isRectMostlyHBounded(subjectRect, boundRect) {
  70. return (Math.min(subjectRect.right, boundRect.right) -
  71. Math.max(subjectRect.left, boundRect.left)) > // overlap area is greater than
  72. ((subjectRect.right - subjectRect.left) / 2) // half the width
  73. }
  74. export function isRectMostlyVBounded(subjectRect, boundRect) {
  75. return (Math.min(subjectRect.bottom, boundRect.bottom) -
  76. Math.max(subjectRect.top, boundRect.top)) > // overlap area is greater than
  77. ((subjectRect.bottom - subjectRect.top) / 2) // half the height
  78. }
  79. export function isRectsSimilar(rect1, rect2) {
  80. return isRectsHSimilar(rect1, rect2) && isRectsVSimilar(rect1, rect2)
  81. }
  82. function isRectsHSimilar(rect1, rect2) {
  83. // 1, because of possible borders
  84. return (Math.abs(rect1.left - rect2.left) <= 2) && (Math.abs(rect1.right - rect2.right) <= 2)
  85. }
  86. function isRectsVSimilar(rect1, rect2) {
  87. // 1, because of possible borders
  88. return (Math.abs(rect1.top - rect2.top) <= 2) && (Math.abs(rect1.bottom - rect2.bottom) <= 2)
  89. }