Треугольник - Тест пересечения треугольника - PullRequest
3 голосов
/ 14 декабря 2009

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

Я собирался реализовать это после теоретического PDF, но я довольно застрял на

  1. Вычислить уравнение плоскости треугольника 2.
  2. Отклонить как тривиальное, если все точки треугольника 1 находятся на одной стороне.
  3. Вычислить плоское уравнение треугольника 1.
  4. Отклонить как тривиальное, если все точки треугольника 2 находятся на одной стороне.
  5. Вычислить линию пересечения и спроецировать на наибольшую ось.
  6. Вычислить интервалы для каждого треугольника.
  7. Пересечь интервалы.

пункт 5 данного руководства. Я действительно не знаю, о чем спрашиваю (все 5,6 и 7). XD

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

Спасибо за помощь

Ответы [ 5 ]

12 голосов
/ 15 декабря 2009

Вы сказали:

Я хотел бы знать, есть ли там некоторый учебник или руководство, чтобы понять и реализовать треугольник-треугольник тест пересечения в трехмерной среде.

И тогда вы сказали:

большинство ссылок указывают на 4-5 страницы, полные формул, я не очень хочу знать

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

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

Шаги 5, 6 и 7 просты для понимания, если вы знаете, что означают слова. Линия пересечения - это линия, образованная пересечением двух плоскостей. Каждый треугольник лежит в плоскости. Есть три случая:

  • Плоскости параллельны и не пересекаются. Треугольники явно не пересекаются.
  • самолеты - это один и тот же самолет. Треугольники могут встречаться или не встречаться.
  • Плоскости - это два разных плана, которые встречаются на одной линии. Если треугольники пересекаются, они, очевидно, должны пересекаться на этой линии.

Предположим, мы в третьем случае. Вычислить отрезок линии пересечения, который содержится в первом треугольнике. Вычислить отрезок линии пересечения, который находится во втором треугольнике. Вопрос сейчас в том, перекрывают ли эти сегменты?

Это можно решить, спроецировав сегменты на удобную ось и увидев, перекрываются ли сегменты линии на этой оси. По сути, это работает так: представьте, что вы освещаете отрезки линий так, что их тени падают на ось. Если тени на оси пересекаются, то отрезки должны пересекаться. Если между тенями на оси есть зазор, то, очевидно, должен быть зазор между отрезками, и поэтому треугольники не пересекаются.

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

2 голосов
/ 03 февраля 2011

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

Следующий пример не оптимизирован, он написан только для понимания решения. Исключения и соответствующие им операторы if могут быть удалены вместе с несколькими векторными преобразованиями.

    public static bool CheckColision(Vector3 t1a, Vector3 t1b, Vector3 t1c, Vector3 t2a, Vector3 t2b, Vector3 t2c)
    {//rotates each edge of the first triangle to the Z axis and checks the second triangle against it then repeats with the second one against the first, and lastly checks to see if all points of the second triangle are on the same side as the first
        if(! CheckColisionLookAt(t1a, t1b, t1c, t2a, t2b, t2c))
            return false;
        if (!CheckColisionLookAt(t1b, t1c, t1a, t2a, t2b, t2c))
            return false;
        if (!CheckColisionLookAt(t1c, t1a, t1b, t2a, t2b, t2c))
            return false;

        if (!CheckColisionLookAt(t2a, t2b, t2c, t1a, t1b, t1c))
            return false;
        if (!CheckColisionLookAt(t2b, t2c, t2a, t1a, t1b, t1c))
            return false;
        if (!CheckColisionLookAt(t2c, t2a, t2b, t1a, t1b, t1c))
            return false;

        return CheckColisionAllOnOneSide(t1a, t1b, t1c, t2a, t2b, t2c);
    }

    public static bool CheckColisionAllOnOneSide(Vector3 t1a, Vector3 t1b, Vector3 t1c, Vector3 t2a, Vector3 t2b, Vector3 t2c)
    {//simply performs a transformation to check if all points on one triangle are on the same side of the other triangle
        Matrix m = Matrix.CreateLookAt(t1a, t1b, t1c - t1a);
        t2a = Vector3.Transform(t2a, m);
        t2b = Vector3.Transform(t2b, m);
        t2c = Vector3.Transform(t2c, m);
        if (t2a.X < 0 && t2b.X < 0 && t2c.X < 0)
            return false;
        if (0 < t2a.X && 0 < t2b.X && 0 < t2c.X)
            return false;
        return true;
    }

    public static bool CheckColisionLookAt(Vector3 t1a, Vector3 t1b, Vector3 t1c, Vector3 t2a, Vector3 t2b, Vector3 t2c)
    {//performs a transformation and checks if all points of the one triangle are under the other triangle after the transformation

        Matrix m = Matrix.CreateLookAt(t1a, t1b, t1c - t1a);
        t1a = Vector3.Transform(t1a, m);//  (0,     0,      0)
        if ( ZERRO < Math.Abs(t1a.X)|| ZERRO < Math.Abs(t1a.Y) || ZERRO < Math.Abs(t1a.Z))
            throw new Exception();
        t1b = Vector3.Transform(t1b, m);//  (0,     0,      maxZ)
        if (ZERRO < Math.Abs(t1a.X) || ZERRO < Math.Abs(t1a.Y))
            throw new Exception();
        t1c = Vector3.Transform(t1c, m);//  (0,     maxY,   someZ)
        if (ZERRO < Math.Abs(t1a.X))
            throw new Exception();
        t2a = Vector3.Transform(t2a, m);
        t2b = Vector3.Transform(t2b, m);
        t2c = Vector3.Transform(t2c, m);
        if (t2a.Y < 0 && t2b.Y < 0 && t2c.Y < 0)
            return false;
        return true;
    }
1 голос
/ 15 декабря 2009

Метод, который вы опубликовали, выглядит так, как будто он использует что-то похожее на этот алгоритм , чтобы определить, пересекаются ли выпуклые многоугольники, основываясь на теореме о разделяющей оси. Это не очень сложно понять.

Если линию, называемую разделяющей осью, можно провести между двумя полигонами, они не пересекаются. Каждое ребро каждого многоугольника является потенциальной разделяющей осью. Полигоны проецируются на вектор, перпендикулярный этой оси, и одномерные экстенты проверяются на перекрытие. Если нет одномерного перекрытия, текущий край является разделительной осью, и два многоугольника не пересекаются. Если имеется 1D-перекрытие, результаты будут неубедительными до тех пор, пока не будут проверены все потенциальные ребра, и в этот момент делается вывод, что два многоугольника пересекаются. Обратите внимание, что двум полигонам разрешено делить ребро.

1 голос
/ 14 декабря 2009

Полагаю, у вас есть координаты x, y для вершин треугольника. например.
для треугольника A:
1. Сторона А1: ха1, я1 2. Сторона А2: ха2, я2 3. Сторона А3: ха3, я3 для треугольника B:
1. Сторона B1: xb1, yb1 2. Сторона B2: xb2, yb2 3. Сторона B3: xb3, yb3

Треугольники пересекаются, если пересекаются любые комбинации их линий. Значение, если A1 пересекает B1 или B2 или B3, или если A2 пересекает B1 или B2 или B3, или если A3 пересекает B1 или B2 или B3.

Так что вам нужен алгоритм, который обманывает, если две линии пересекаются. Вот самый простой пример, который я нашел: http://www.mathopenref.com/coordintersection.html

1 голос
/ 14 декабря 2009

Вот сайт, который содержит ссылки на множество пересечений:

Страница рендеринга объекта / пересечения объектов в реальном времени

Вот что они перечисляют для Tri / Tri:

M & l; jgt 2 (2) ;
Проведено JGT 2 (4) ;
GTweb ;
M? Ller ;
GPG с.393;
GTCG с.539;
TGS ;
RTCD с.155,172;
Шен JGT 8 (1) ;
Guigue JGT 8 (1) ;
SoftSurfer ;
Рендеринг в реальном времени, 2-е издание, стр.590;
Рендеринг в реальном времени, третье издание, стр.757

...