Как реализовать обнаружение столкновения полилиний в Javascript

1

В настоящее время у меня есть платформа для платформы 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, если нет. Я не буду объяснять, зачем мне это нужно, поскольку это немного абстрактно, но примером полилинии будет следующее:

Обратите внимание, что полилинии имеют выпуклую форму

Теги:
collision
polyline

1 ответ

0

Вы можете ускорить поиск столкновений, определяя (псевдослучайные) бесконечные линии длины, которые идут между двумя полигонами, так что линия разбивает полигоны на 3 множества: выше, ниже и сталкивается. Поскольку они находятся на линии, вы знаете, что все вышеперечисленное не сталкивается со всеми ниже. Повторите это несколько раз, пока не получите небольшое количество нерешённых пар полигонов, а затем примените старый алгоритм к оставшимся парам.

Вы можете найти (псевдослучайные) бесконечные линии длины, вычисляя нормаль в середине линии, соединяющей центры двух полигонов в вашем наборе полигонов.

  • 0
    Я не понимаю Только многоугольники могут быть выпуклыми. И алгоритм, который я предлагаю, работает и для линий.
  • 0
    Вы по-прежнему можете использовать алгоритм разделительной линии, чтобы разделить две полилинии, если каждая линия имеет несколько сегментов.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню