В настоящее время у меня есть платформа для платформы JavaScript. Я создал обнаружение столкновений многоугольников и полигонов с ответом, используя метод SAT, изображенный на многих других сайтах.
Я также создал функцию внутри конструктора Polygon, которая вернет либо стороны, открытые к вершине многоугольника, либо бокам, открывающимся под днищем многоугольника, в зависимости от того, какое направление выбрано. Возвращаемый массив содержит много разных векторов, которые будут более подробно объяснены позже.
Текущий код выглядит примерно так:
Polygon.prototype.getSidesOn = function(dir) {
if (dir === "top" || dir === "bottom") {
var result = [], start = false, stop = false, elen =
this.calcPoints.length, e = 0, f = 0, point, next, prevX, prevY, directionX, directionY;
while (!stop) {
if (e >= 5*elen) {return;}
f = e%elen;
prev = f-1 < 0 ? this.calcPoints[elen-1] : this.calcPoints[f-1];
point = this.calcPoints[f];
prevX = directionX;
prevY = directionY;
directionX = point.x > prev.x ? "right" : point.x < prev.x ? "left" : directionX;
directionY = point.y < prev.y ? "up" : point.y > prev.y ? "down" : directionY;
if (prevX !== directionX && prevX && prevY) {
if (!start) {
start = dir === "top" ? directionY === "up" : directionY === "down";
} else {
break;
}
}
if (start) {
if (point.x !== prev.x) {
if (!result.length) {
result.push(new Vector(prev.x,prev.y),new
Vector(point.x,point.y));
} else {
result.push(new Vector(point.x,point.y));
}
} else {
break;
}
}
e++;
}
return result;
} else {
return;
}
}
Я понимаю, что это немного грязно, но это не беспокойство, поскольку я буду оптимизировать его позже.
В принципе, он работает только на выпуклых многоугольниках (я имею в виду слово "выпуклое", как в треугольнике или форме, которая не возвращается в себя). Во всяком случае, это работает из-за того, что все выпуклые многоугольники имеют только две точки, где смежные стороны обращены в противоположном направлении X.
В любом случае массив, который выводится, выглядит примерно так:
//[Vector,Vector,Vector,Vector...]
это не то, на что он на самом деле выглядит, но в основном он выводит массив векторов для каждой обнаруженной точки.
То, что мне нужно реализовать, - это способ обнаружения столкновения между двумя из этих полилиний. В отличие от системы обнаружения столкновений многоугольников и полигонов, не обязательно должен быть вектор отклика, а вместо этого код должен выводить либо "истинный", либо "ложный" bool.
Единственный способ, с помощью которого я могу сейчас это сделать, состоит в следующем:
function PolylinePolyline(line1,line2) {
var i, ilen = line1.length, j, jlen = line2.length;
for (i = 0; i < ilen; i++) {
for (j = 0; j < jlen; j++) {
var point1 = line1[i];
var point2 = i+1 < ilen ? line1[i+1] : line1[0];
var point3 = line2[j];
var point4 = j+1 < jlen ? line2[j+1] : line2[0];
var line01 = new line(point1,point2);
var line02 = new line(point3,point4);
if (LineLine(line01,line02) {
return true;
}
}
}
return false;
}
И хотя это работает, очень дорого использовать, если строки, скажем, 5 баллов, и я должен обнаружить столкновение между ними. Я бы предпочел альтернативу, которая возвращает true, если они сталкиваются, и false, если нет. Я не буду объяснять, зачем мне это нужно, поскольку это немного абстрактно, но примером полилинии будет следующее:
Вы можете ускорить поиск столкновений, определяя (псевдослучайные) бесконечные линии длины, которые идут между двумя полигонами, так что линия разбивает полигоны на 3 множества: выше, ниже и сталкивается. Поскольку они находятся на линии, вы знаете, что все вышеперечисленное не сталкивается со всеми ниже. Повторите это несколько раз, пока не получите небольшое количество нерешённых пар полигонов, а затем примените старый алгоритм к оставшимся парам.
Вы можете найти (псевдослучайные) бесконечные линии длины, вычисляя нормаль в середине линии, соединяющей центры двух полигонов в вашем наборе полигонов.