From 4627fe4f7648ba7851d6c45583f0ea34a98524f1 Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Thu, 16 Jul 2026 12:37:56 +0300 Subject: [PATCH] =?UTF-8?q?feat(calculateCollision):=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B2=D1=8B=D1=87=D0=B8=D1=81=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BF=D0=B5=D1=80=D0=B5=D1=81=D0=B5=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=B4=D0=B2=D1=83=D1=85=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=8A=D0=B5=D0=BA=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculateCollision/calculateCollision.js | 51 +++++++ .../calculateCollision.test.js | 130 ++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 src/lib/calculateCollision/calculateCollision.js create mode 100644 src/lib/calculateCollision/calculateCollision.test.js diff --git a/src/lib/calculateCollision/calculateCollision.js b/src/lib/calculateCollision/calculateCollision.js new file mode 100644 index 0000000..1ed41b9 --- /dev/null +++ b/src/lib/calculateCollision/calculateCollision.js @@ -0,0 +1,51 @@ +/** + * Вычисляет пересеклись ли два объекта по ААBB формуле в системе координат где ось X идет справа налево, ось Y идет сверху вних + * @param {Object} firstObject - первый объект + * @param {number} firstObject.left - Min X координата первого объекта + * @param {number} firstObject.right - Max X координата первого объекта + * @param {number} firstObject.top - Min Y координата первого объекта (ось смотрит вниз) + * @param {number} firstObject.bottom - Max Y координата первого объекта + * @param {Object} secondObject - второй объект + * @param {number} secondObject.left - Min X координата второго объекта + * @param {number} secondObject.right - Max X координата второго объекта + * @param {number} secondObject.top - Min Y координата второго объекта (ось смотрит вниз) + * @param {number} secondObject.bottom - Max Y координата второго объекта + * @returns {boolean} + */ +export function calculateCollision(firstObject, secondObject) { + try { + const coordinates = [ + firstObject.left, + firstObject.right, + firstObject.top, + firstObject.bottom, + secondObject.left, + secondObject.right, + secondObject.top, + secondObject.bottom, + ]; + + if (coordinates.some((element) => typeof element !== 'number')) { + throw new Error('Координаты должны являться числовыми значениями'); + } + + if ( + firstObject.left > firstObject.right || + firstObject.top > firstObject.bottom || + secondObject.left > secondObject.right || + secondObject.top > secondObject.bottom + ) { + throw new Error('Координаты должны быть корректными'); + } + + return ( + firstObject.left <= secondObject.right && + firstObject.right >= secondObject.left && + firstObject.top <= secondObject.bottom && + firstObject.bottom >= secondObject.top + ); + } catch (err) { + console.error(err); + return null; + } +} diff --git a/src/lib/calculateCollision/calculateCollision.test.js b/src/lib/calculateCollision/calculateCollision.test.js new file mode 100644 index 0000000..e6d5748 --- /dev/null +++ b/src/lib/calculateCollision/calculateCollision.test.js @@ -0,0 +1,130 @@ +import { describe, expect, it } from 'vitest'; +import { calculateCollision } from './calculateCollision'; + +describe('calculateCollision', () => { + it('Корректно обрабатывает невозможные кейсы (левая координата больше правой)', () => { + const firstObject = { + left: 0, + right: 20, + top: 0, + bottom: 20, + }; + + const secondObject = { + left: 10, + right: 0, + top: 0, + bottom: 10, + }; + + expect(calculateCollision(firstObject, secondObject)).toBeNull(); + }); + + it('Корректно обрабатывает неверный формат данных', () => { + const firstObject = { + left: 'wrong', + right: 20, + top: 0, + bottom: 20, + }; + + const secondObject = { + left: 0, + right: 10, + top: 0, + bottom: 10, + }; + + expect(calculateCollision(firstObject, secondObject)).toBeNull(); + }); + + it('Корректно обрабатывает отсутствие пересечения по X', () => { + const firstObject = { + left: 0, + right: 20, + top: 0, + bottom: 20, + }; + + const secondObject = { + left: 25, + right: 30, + top: 0, + bottom: 10, + }; + + expect(calculateCollision(firstObject, secondObject)).toBe(false); + }); + + it('Корректно обрабатывает отсутствие пересечения по Y', () => { + const firstObject = { + left: 0, + right: 20, + top: 0, + bottom: 20, + }; + + const secondObject = { + left: 0, + right: 30, + top: 25, + bottom: 30, + }; + + expect(calculateCollision(firstObject, secondObject)).toBe(false); + }); + + it('Корректно обрабатывает отсутствие пересечения по X и Y', () => { + const firstObject = { + left: 0, + right: 20, + top: 0, + bottom: 20, + }; + + const secondObject = { + left: 25, + right: 30, + top: 25, + bottom: 30, + }; + + expect(calculateCollision(firstObject, secondObject)).toBe(false); + }); + + it('Корректно обрабатывает пересечение', () => { + const firstObject = { + left: 0, + right: 20, + top: 0, + bottom: 20, + }; + + const secondObject = { + left: 10, + right: 30, + top: 10, + bottom: 30, + }; + + expect(calculateCollision(firstObject, secondObject)).toBe(true); + }); + + it('Корректно обрабатывает вхождение', () => { + const firstObject = { + left: 0, + right: 20, + top: 0, + bottom: 20, + }; + + const secondObject = { + left: 10, + right: 15, + top: 10, + bottom: 15, + }; + + expect(calculateCollision(firstObject, secondObject)).toBe(true); + }); +});