Re[5]: проверка на попадание точки в треугольник
От: ministr Россия  
Дата: 07.08.06 01:47
Оценка:
Господа, какое это векторное произведение? а тем более смешанное...
Начнем с того что cross_product- это скаляр! а вот остальные — это векторы:
смешанное произведение — вектор коллинеарный первому,имеющий длину равную площади параллелограмма основанного на двух ост векторах.
векторное произведение — вектор, обладающий след тремя св-вами:
1.направлен перпендикулярно плоскости исходных векторов;
2.образует с ними правую тройку;
3.имеющий длину равную площади параллелограмма основанного на двух ост векторах.

ближе к сути. Я покопался и нарыл в математике следующее обоснование cross_product:
Пусть а(ax,ay) и b(bx,by) -два ненулевых вектора,отложенных от одной точки. Рассмотрим правую СК
Направленный угол между векторами a и b — угол по модулю равный неориентированному углу между a и b и имеющий положительный знак если кратчайший поворт от вектора a к b осуществляется против часовой стрелки.
*)уголы между (a и b) и (b и a) имеют разные знаки.
Величина (ax*by-bx*a1) называется косым (или псевдоскалярным) произведением векторов a и b (обозначим за {a,b}). Эта величина определяет ориентированную площадь параллелограма посторенного на векторах a и b(знак площади тот же что и у знака угла).
*)к сведению: тангенс угла между a и b равен отношению косого произведения к скалярному, те tg W=(ax*by-bx*ay)/(ax*bx+ay*by)

приводя векторык общему началу, cross_product вычисляет именно косое произведение векторов, затем мы берем его знак и сравниваем с остальными, таким образом важно при выпуклых полигонах учитывать порядок следования вершин. По такому же принципу строятся алгоритмы нахождения выпуклой оболочки множества точек и алгоритмы определения порядка следования вершин выпуклого многоугольника.
Интересно то что для нулевых векторов косое произведение неопределено и существуют контр примеры неработоспособности данного алгоритма при замене < на <= поэтому необходимо (в случае необходимости,тк в данном листинге это не рассматривается) проверять на конгруэнтность вершинам и принадлежность сторонам треугольника (достаточно чтоб cross_product==0 и выполнить && с принадлежностью проэкций точки и стороны на оси координат).
Что бы зрительно представить работу алгоритма в качесве общей вершины следует брать саму проверяемую на принадлежность треугольнику точку. Те весьма красиво получается если заменить соответствующую часть алгоритма на:
        bool cp1 = cross_product(x1, y1, x, y, x2, y2) < 0.0;
        bool cp2 = cross_product(x2, y2, x, y, x3, y3) < 0.0;
        bool cp3 = cross_product(x3, y3, x, y, x1, y1) < 0.0;
"640 KB должно быть достаточно для любого"
(Билл Гейтс 1981)
Re[6]: проверка на попадание точки в треугольник
От: Vintik_69 Швейцария  
Дата: 07.08.06 08:40
Оценка:
Здравствуйте, ministr, Вы писали:

M> Господа, какое это векторное произведение? а тем более смешанное...

Тут вот ссылку давали выше, сходите: http://en.wikipedia.org/wiki/Cross_product.

То что вы описали — это и есть векторное произведение, в случае если векторы лежать в плоскости Oxy. Тогда действительно, векторное произведение можно рассматривать как скаляр (поскольку у него только z-компонента отлична от нуля).

А вообще же cross product — это именно векторное произведение, и никак иначе.
Re[6]: проверка на попадание точки в треугольник
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 07.08.06 18:16
Оценка:
Здравствуйте, ministr, Вы писали:

M> Господа, какое это векторное произведение? а тем более смешанное...

M>Начнем с того что cross_product- это скаляр! а вот остальные — это векторы:

Cross product — векторное произведение

M>смешанное произведение — вектор коллинеарный первому,имеющий длину равную площади параллелограмма основанного на двух ост векторах.


Triple scalar product

M>векторное произведение — вектор, обладающий след тремя св-вами:


Cross product

А вот скаларное произведение — inner product.
Нужно носить в себе еще хаос, чтобы быть в состоянии родить танцующую звезду.
Re[7]: проверка на попадание точки в треугольник
От: vvotan Россия  
Дата: 07.08.06 19:01
Оценка:
Здравствуйте, konsoletyper, Вы писали:

K>А вот скаларное произведение — inner product.


Еще называют dot product (обозначается точеой, по аналогии с cross product, обозначаемым крестиком)
--
Sergey Chadov

... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: проверка на попадание точки в треугольник
От: Au1  
Дата: 18.08.06 07:44
Оценка:
Здравствуйте, Logic Bomb, Вы писали:


LB>Неужели нет алгоритма проще? Что-то из векторной алгебры вертится в голове но не могу перенести на бумагу..


Самое простое, что есть на эту тему, посчитать площадь исходного треугольника, и сумму площадей pAB, pAC, pBС. Затем сравнить их с некоторой точностью. Если совпали — внутри. Иначе снаружи.

Вот площадь треугольника: abs((x2-x1)*(y3-y2)-(x3-x2)*(y2-y1))/2.

В нашем случае можно и не делить на 2. Лишнее вычисление, на проверку не влияет.

Проверка с точностью выглядит так: if (abs(a-b)<eps) {...}, где const eps=0.0000001, или сколько там хочется.
Re[3]: проверка на попадание точки в треугольник
От: xtile  
Дата: 19.08.06 17:09
Оценка:
Здравствуйте, Smal, Вы писали:

S>Здравствуйте, Anpek, Вы писали:


A>>Проводишь любой луч из этой точки — если луч пересечет стороны нечетное количество раз — то внутри, иначе — снаружи


S>Хреново работает, если луч прошел через вершину


Отлично работает. Если луч прошел через вершину — нужно просто учесть между лучом и каждым ребром
Re: проверка на попадание точки в треугольник
От: Olegator  
Дата: 20.08.06 00:39
Оценка:
Здравствуйте, Logic Bomb, Вы писали:

LB>Неужели нет алгоритма проще? Что-то из векторной алгебры вертится в голове но не могу перенести на бумагу...


Стандартный способ — смотреть на знаки так называемых косых (или псевдоскалярных) произведений. Для двух векторов a{x1,x2} и b{x2,y2} косое произведение определено так: x1*y2-x2*y1 и равно ориентированной площади параллелограмма, построенного на этих векторах.

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

struct point
{
  int x;
  int y;

  point(int x, int y) : x(x), y(y)
  {}

  point operator-(const point& p) const
  { return point(x - p.x, y - p.y); }
};

int pseudoScalarProduct(const point& p1, const point& p2)
{
  return (p1.x * p2.y - p2.x * p1.y);
}

bool doesPointBelongsToNgon(const point&    p,
                            const point     ngon[], // обход против часовой стрелки
                            int             n)
{
  for(int i = 0; i < n; i++)
  {
    int ps = pseudoScalarProduct(ngon[(i+1)%n] - ngon[i], p - ngon[i]);
    if(ps == 0)
      return true;  // принадлежит стороне
    if(ps < 0)      // если по часовой, знак >
      return false; // снаружи
  }
  return true;
}


Этот алгоритм имеет сложность O(N), хотя есть вариант и за O(logN).
... << RSDN@Home 1.1.4 stable rev. 510>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.