суббота, 24 сентября 2016 г.

#1267. Хотел написать "ругательный пост"

Хотел написать "ругательный пост". О "программистах" и "математиках".

Вместо этого "пока лишь" задам вопрос".

Вот тут - http://algolist.manual.ru/maths/geom/datastruct.php

Обсуждается "задача определения принадлежности точки прямой".

И всё вроде бы "хорошо". Даже "решение" дано:

enum {LEFT,  RIGHT,  BEYOND,  BEHIND, BETWEEN, ORIGIN, DESTINATION};
//    СЛЕВА, СПРАВА, ВПЕРЕДИ, ПОЗАДИ, МЕЖДУ,   НАЧАЛО, КОНЕЦ

int Point::classify(Point &p0, Point &pl)
{
  Point p2 = *this;
  Point a = p1 - pO;
  Point b = p2 - pO;
  double sa = a. x * b.y - b.x * a.y;
  if (sa > 0.0)
    return LEFT;
  if (sa < 0.0)
    return RIGHT;
  if ((a.x * b.x < 0.0) || (a.y * b.y < 0.0))
    return BEHIND;
  if (a.length() < b.length())
    return BEYOND;
  if (pO == p2)
    return ORIGIN;
  if (p1 == p2)
    return DESTINATION;
  return BETWEEN;
}

И "пояснительный текст":

"Вначале проверяется ориентация точек p0, p1 и р2, чтобы определить, располагается ли точка р2 слева или справа, или она коллинеарна с отрезком p0p1. В последнем случае необходимы дополнительные вычисления, ели векторы a=pl-pO и b=р2-p0 имеют противоположное направление, то точка р2 лежит позади направленного отрезка p0p1 если вектор а короче вектора b, то точка р2 расположена после отрезка p0p1. В противном случае точка р2 сравнивается с точками p0 и р1 для определения, совпадает ли с одной из этих концевых точек или лежит между ними."

И "теоретическая база"...

И всё такое...

Векторное произведение. "Площадь параллелограмма". Коллинеарность и "всё такое"..

Определитель матрицы "если точнее"...

Но! Почему это НЕ РАБОТАЕТ?

И что такое sa?

И ПОЧЕМУ там написано sa < 0 и sa > 0?

И НИКТО не подумал про "эпсилон окрестность"... И дело даже не в "разрядной сетке".

А вот в чём?

Вот ЗАДАЮ вопрос - "в чём дело и ПОЧЕМУ ЭТО не работает".

И как это ИСПРАВИТЬ?

Не надо только думать, что я "лох который не смог разобраться".

Я то - разобрался.

И НАШЁЛ как "это" исправить".

И даже "понял" - почему этот метод НЕЛЬЗЯ применять "на практике".

В этом кстати кроется отличие между "математиками" и "программистами"...

Так вот "почему" и "что не работает"?

И как заставить работать?

И ещё вопрос.

Раз уж мы говорим о векторах и углах между ними.

То ПОЧЕМУ бы нам просто не посчитать УГЛЫ от оси X для одного вектора и другого. В РАДИАНАХ. И не сравнить их равенство в "той самой эпсилон окрестности"?

Ну или "длину нормали к прямой" уж на "худой конец". Хотя "в пределе" она будет стремиться к "разнице углов в радианах".

Ну или почему бы просто не "решить уравнение" прямой - https://habrahabr.ru/post/148325/

Ну и "на закуску" - http://math.stackexchange.com/questions/175896/finding-a-point-along-a-line-a-certain-distance-away-from-another-point

http://gospodaretsva.com/urok-31-proverka-prinadlezhnosti-tochki-otrezku.html

http://forum.codenet.ru/q35421/

"Если вместо x и y подставить координаты точки, то:
(x - x1) * (y2 - y1) - (x2 - x1) * (y - y1) > 0 , когда точка лежит ниже(правее) линии и
(x - x1) * (y2 - y1) - (x2 - x1) * (y - y1) < 0 , когда точка лежит выше(левее) линии.
Линию с заданной толщиной воспринимай как две линии, смещенные в разные стороны на половину толщины."

ОПЯТЬ! Тоже самое "векторное произведение" или "определитель матрицы".

Ну и ПОЧЕМУ это НЕЛЬЗЯ использовать?

Особенно на "длинных" отрезках.

B ЧТО написать ВМЕСТО sa < 0 и sa> 0?

Хинт.. |sa| < e, Где e - это "эпсилон вычислительной точности" - НЕ РАБОТАЕТ!

1 комментарий:

  1. Два "длинных" вектора с "небольшим" углом между ними. Какая будет "площадь параллелограмма построенного на этих векторах"? При том что вектора "длинные"? Она будет стремится к совсем НЕНУЛЕВОМУ значению. Даже БОЛЬШЕ "машинного эпсилон"...

    ОтветитьУдалить