Перевірка колізії точки з точкою була дуже простим, але з цього моменту, щоб перевірити, чи торкаються об’єкти один одного нам знадобиться елементарна математика. Перевірка того, чи знаходиться точка всередині круга, вимагає від нас згадати уроки математики середньої школи та теорему Піфагора:
a2 + b2 = c2
Ми можемо отримати довжину гіпотенузи трикутника c
за допомоги довжин двох інших сторін.
У перекладі на код це виглядає так:
c = sqrt((a * a) + (b * b));
Помножте значення довжини сторони a на саму себе (або, інакше кажучи, піднесіть це значення до квадрата), зробіть те саме для сторони b, додайте результати і обчисліть з отриманої суми корінь.
Навіщо нам це? Ми можемо використовувати теорему Піфагора, щоб отримати відстань між двома об’єктами у двомірному просторі! У цьому контексті a і b є горизонтальною і вертикальною відстанями між точкою і центром круга
Ми можемо обчислити відстані X і Y наступним чином:
const distX = pointX - circleX;
const distY = pointy - circleY;
Тоді ми можемо знайти відстань між двома точками за допомогою теореми Піфагора:
const distance = sqrt((distX * distX) + (distY * distY));
Отже, якщо точка має координати (10, 10), а центр круга — (40, 50), ми отримаємо відстань 50. Ви можете подумати: "А що, якщо відстань виявиться відʼємною?" Не хвилюйтеся: оскільки ми множимо значення відстаней самі на себе, навіть якщо вони негативні, результат буде позитивним.
Гаразд, але як ми використаємо це для тестування на зіткнення? Якщо відстань між точкою та центром круга менша за радіус круга, ми маємо зіткнення!
if (distance <= r) {
return true;
}
return false;
У повному прикладі, використовуючи нашу нову функцію, ми можемо змінити колір круга, коли точка знаходиться всередині нього.
// змінні для положення і радіуса круга
let circleX;
let circleY;
const circleRadius = 100;
function setup() {
createCanvas(window.innerWidth, window.innerHeight);
noCursor();
strokeWeight(15); // збільшена жирність точки, щоб краще її бачити
circleX = width / 2; // визначення горизонтального центра полотна
circleY = height / 2; // визначення вертикального центра полотна
}
function draw() {
background(255);
// результат перевірки на зіткнення
const isHit = isPointWithCircleCollides(mouseX, mouseY, circleX, circleY, circleRadius);
// зміна заливки при зіткненні
if (isHit) {
fill(255, 150, 0);
} else {
fill(0, 150, 255);
}
// малювання круга
noStroke();
ellipse(circleX, circleY, circleRadius * 2, circleRadius * 2);
// малювання точки
stroke(0);
point(mouseX, mouseY);
}
// перевірка на перетин між точкою та кругом
function isPointWithCircleCollides(mouseX, mouseY, circleX, circleY, r) {
// отримання відстані між точкою та центром кола за допомогою теореми Піфагора
let distX = pointX - circleX;
let distY = pointY - circleY;
let distance = sqrt((distX * distX) + (distY * distY));
// якщо відстань менша радіуса круга, тоді точка всередині
if (distance <= r) {
return true;
}
return false;
}
Цей метод із застосуванням теореми Піфагора буде зустрічатися ще багато разів. Та і в цілому це поширена задача, тому p5js має спеціальну вбудовану функцію dist(). Хоча цю функцію зручно використовувати, але в даному коді ми залишимо оригінальну математику для прикладу самостійної реалізації.
Одне застереження: якщо у вас є об’єкт який рухається дуже швидко, то іноді він може пройти крізь свою ціль, не спровокувавши зіткнення! Цей кейс іноді називають проблемою "bullet through paper". Для цього є багато рішень, але хорошим місцем для початку буде ця публікація на GameDev.net post. Стандартний спосіб виявлення цього називається "безперервним виявленням зіткнення" (Continuous Collision Detection або скорочено CCD.
Далі: Круг і Круг