Подтвердить что ты не робот

JavaScript - Разделительная ось. Теорема. Столкновение работает, но не ответ.

Итак, я пытаюсь применить ответ на мои столкновения SAT, Circle - Poly, Poly - Poly. Я портировал этот код в этой статье на JavaScript:

http://rocketmandevelopment.com/blog/separation-of-axis-theorem-for-collision-detection/

Теперь обнаружение работает на всех типах, но ответ терпит неудачу и идет со безумной скоростью и неправильным углом, он не зависит от массы объектов (площадь ^ 2 вместо массы) и angular скорость isn 't применяется

JSFiddle (гравитация не применяется для симуляции, перемещается со стрелками), первая часть в JS - это векторы, а затем физика и затем Главная.

Это мое определение фигур: (нужно было добавить код для ссылки "JSFiddle": P)

var Circle = function(body, c, r, cor, cof) {
    this.body = body // Static or dynamic
    this.c = c; // Center
    this.r = r; // Radius
    this.m = getCMass(r); // Mass = Area
    this.v = new Vector(); // Velocity
    this.cor = cor; // Coefficient of restitution
    this.cof = cof; // Coefficient of friction
    this.a = 0; // Angle
    this.av = 0; // Angular velocity
    this.type = "Circle";
}

var Polygon = function(body, c, vs, cor, cof) {
    this.body = body // Static or dynamic
    this.c = c; // Center
    this.vs = vs; // Vertices
    this.m = getPMass(vs); // Mass = Area
    this.v = new Vector(); // Velocity
    this.cor = cor; // Coefficient of restitution
    this.cof = cof; // Coefficient of friction
    this.a = 0; // Angle
    this.av = 0; // Angular velocity
    this.type = "Polygon";
}

function getCMass(r) { // More like, getCArea
    return (r * r * Math.PI);
}

function getPMass(vs) {
    var area = 0;
    var j = vs.length - 1;

    for (var i = 0; i < vs.length; i++) {
        area += (vs[j].x + vs[i].x) * (vs[j].y - vs[i].y); 
        j = i;
    }

    return (area / 2);
}

Все функции Collision дают результаты неудачного ответа, поэтому должно быть какое-то соединение.

Вернуться к скорости angular Я знаю, как вращать полигоны, но я ищу, чтобы получить новый av после столкновения:

px = x * cos(a) - y * sin(a); 
py = x * sin(a) + y * cos(a);

Также я сделал хороший физический симулятор для строк и безьеров, которые он мог бы помочь: http://murplyx.net/projects/csb/

Итак, самая важная часть в этом для меня - как я буду исправлять, чтобы скорость шла правильно по скорости и углу? (Я использую векторы, а не тригонометрию -.-) Тогда я могу думать о массовых и angular скоростях. Благодарю. Я остаюсь в коробке Box2D.

EDIT: Добавлены функции, которые вычисляют площадь ^ 2, чтобы установить массу равной.

4b9b3361

Ответ 1

В функции столкновения круга круга getCCCol(a, b) вы вычисляете a.center - b.center, который является вектором между центрами, и затем вы масштабируете его скаляром, представляющим перекрытие двух окружностей, измеренных в единицах длины вдоль вектора между центры кругов. Я не могу понять, что означает этот вектор, но это что-то, представляющее длину или какую-то ориентированную область.

В update() вы затем добавляете - в случае столкновения - упомянутое выше значение скорости кругов, если они не фиксированы. Добавление скоростей и длин (или областей) не имеет смысла. То, что вы действительно хотите сделать, это изменить векторы скорости объектов в зависимости от их текущих скоростей, плоскости контакта между ними, их масс и, возможно, их упругости. Это может также потребовать выполнения моделирования назад в течение некоторого времени, чтобы удалить перекрытие объектов из-за ваших фиксированных шагов времени. Так, например, для двух полностью эластичных кругов одинаковой массы, сталкивающейся с вами, вы просто хотите повернуть векторы скорости, но ничего не добавить к ним в зависимости от геометрии столкновения.

То же самое относится к getPCCol(p, c) и getPPCol(a, b), где вы снова вычисляете какое-то расстояние, которое затем добавляется к скоростям в случае столкновения. Какие значения предназначены для представления?

В конце концов нет ни одной проблемы, на которую я могу указать, что это устранит проблемы. Код, обновляющий скорости в случае столкновения, не соответствует физике этого процесса. Я также предлагаю явно ввести временной шаг, потому что ваш шаг обновления позиции position = position + velocity действительно должен быть position = position + velocity x timestep. Сделав это явным, даже если вы выберете его как единое целое, вы можете более легко проверить, действительно ли единицы ваших расчетов имеют смысл.

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

Я надеюсь, что это поможет и, конечно, не стесняйтесь спрашивать, что-то неясно или требует дальнейшей разработки.


Вот как я, вероятно, попытаюсь реализовать динамику твердого тела, т.е. порядок, в котором я бы добавил функции. Каждый шаг добавляет более или менее одну особенность, но они все более сложны, чем это может звучать. Существуют тысячи страниц исследований для каждого шага и десятки или сотни альтернатив реализации.

  • Динамика частиц без импульса angular

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

  • Динамика частиц с импульсом angular

    Добавьте тензор инерции и скорости angular. Рассмотрим использование кватернионов. Реализуйте реакцию на силу, действующую в любой точке, а не только на центр масс.

  • Динамика твердого тела с столкновениями

    Внедрить алгоритм поиска столкновений, который прогнозирует время столкновений и точку столкновения. Вычислите реакцию столкновения с использованием простой модели, такой как модель контакта с импульсом. Для этого, вероятно, потребуется ввести временное разбиение.

  • Динамика твердого тела с трением

    Добавьте простую модель трения, например, колумское трение.

  • Добавление полей силы тяжести и других сил

    Здесь вы должны решить, хотите ли вы иметь только постоянную гравитационную силу, или если вы также хотите рассчитать гравитационные силы между объектами. Вы можете добавить гравитацию сразу после шага 1, потому что это просто сила, действующая на центр масс, а потому, что гравитационная сила становится бесконечной по мере того, как два объекта становятся все ближе и ближе друг к другу. Вся симуляция легко взрывается, т.е. Ваши объекты улетают с большими скоростями. Для имитации гравитации и других силовых полей обычно требуются более сложные алгоритмы интеграции. В общем, вы увидите, что добавление дополнительных возможностей в симуляцию обычно увеличивает требования к алгоритму интеграции, и вы получите неустойчивости.