3 точки коллинеарны в 2d - PullRequest
       29

3 точки коллинеарны в 2d

7 голосов
/ 16 февраля 2011

Я пытаюсь проверить, когда 3 точки (двойные) коллинеарны в 2-D. я нашел различные функции Паскаля, которые возвращают true, если это проверено; эти функции используют целое число для указания координат X и Y. Мне нужен более точный расчет по крайней мере, до первых 3 цифр десятичной части X и Y, выраженных как двойной тип. Кто может мне помочь с этим?

Я нашел эту функцию:

function Collinear(x1, y1, x2, y2, x3, y3: Double): Boolean;
begin
  Result := (((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) = 0);
end;

Но я думаю, что вычисление никогда не будет 0. Должен ли я использовать что-то подобное?

function Collinear(x1, y1, x2, y2, x3, y3: Double): Boolean;
begin
  Result := (((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) < 0.01);
end;

Ответы [ 2 ]

8 голосов
/ 16 февраля 2011

Уравнение скалярного произведения, которое вы вычисляете, равно нулю тогда и только тогда, когда три точки коллинеарны.Однако на машине с конечной точностью вы не хотите проверять на равенство нулю, а вместо этого проверяете на нулевое значение до некоторого небольшого допуска.

Поскольку уравнение может быть как отрицательным, так и положительным, ваш тест нене собираюсь на работу.Он вернет ложные срабатывания, когда уравнение оценивается в большое отрицательное значение.Таким образом, вам нужно проверить, что значение absolute мало:

function Collinear(const x1, y1, x2, y2, x3, y3: Double): Boolean;
const
  tolerance = 0.01;//need a rationale for this magic number
begin
  Result := abs((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) < tolerance;
end;

Как точно выбрать допуск, зависит от информации, которую вы не предоставили.Откуда берутся ценности?Они размерны?

3 голосов
/ 10 марта 2011

Код Дэвида будет работать, но вы должны получить допуск как функцию параметров, например:

function Collinear(const x1, y1, x2, y2, x3, y3: Double): Boolean; inline;   
var  
  tolerance: double;  
begin  
  tolerance := abs(max(x1,x2,x3,y1,y2,y3)) * 0.000001;  
  Result := abs((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) < tolerance;  
end;  

Если вы этого не сделаете и вместо этого используете константу, вы можете столкнуться со странными ошибками с большими значениями x1..y3.

...