function cross(p0x, p0y, p1x, p1y,
p2x, p2y, p3x, p3y)
{
const d = ((p3y - p2y) * (p1x - p0x)) - ((p3x - p2x) * (p1y - p0y));
if (d === 0)
{
return null;
}
const d02x = p0x - p2x;
const d02y = p0y - p2y;
let n1 = ((p3x - p2x) * d02y) - ((p3y - p2y) * d02x);
let n2 = ((p1x - p0x) * d02y) - ((p1y - p0y) * d02x);
const v01 = n1 / d;
const v23 = n2 / d;
if (v01 < 0 || v01 > 1)
{
return null;
}
if (v23 < 0 || v23 > 1)
{
return null;
}
const x = p0x + (v01 * (p1x - p0x));
const y = p0y + (v01 * (p1y - p0y));
return {x, y};
}
var maxDistanceSquared = circle0.radius + circle1.radius;
maxDistanceSquared *= maxDistanceSquared;
var insideDistance = maxDistance - currentDistance;
Осталась только одна проблема, хоть и не вещественная, иногда шар с большой скоростью проникает сквозь другой, что не красиво, а избежать не знаю как, в каких пределах должно быть изменение скорости, или по пикселю двигать?
А иногда вообще успевает залесть внутрь, там отрабатывается коллизия, а на следующем шагу он не успевает выйти из шара, в результате 3-10 шагов они колеблется
// вычисляем дистанции
var currentDistance = Math.sqrt(currentDistanceSquared);
var maxDistance = Math.sqrt(maxDistanceSquared);
// вычисляем степень проникновения двух кругов друг в друга
var collideDistance = currentDistance - maxDistance;
// вычисляем скейл для масштабирования вектора
// получаем вектор приникновения
var scale = collideDistance / currentDistance
dx *= scale;
dy *= scale;
// для одного круга прибавляем(или вычитаем?)
circle0.x += dx * 0.5;
circle0.y += dy * 0.5;
// для второго вычитаем (или прибавляем?)
circle1.x -= dx * 0.5;
circle1.y -= dy * 0.5;
//вычисляем старую скорость (это можно запомнить)
var oldSpeed = Math.sqrt(circle0.speed.x * circle0.speed.x + circle0.speed.y + circle0.speed.y);
// прибавляем новый вектор скорости
circle0.speed.x += dx * 0.5;
circle0.speed.y += dy * 0.5;
// вычисляем текущую скорость
var currentSpeed = Math.sqrt(circle0.speed.x * circle0.speed.x + circle0.speed.y + circle0.speed.y);
// корректируем вектор скорости
circle0.speed.x *= currentSpeed / oldSpeed;
circle0.speed.y *= currentSpeed / oldSpeed;