Вероятно, это не совпадение, что (200; 200) является точкой 0.
Похоже, вы не исключаете текущую точку (vPointOnHull) из конечной точки (vEndPoint), и ваша реализация ориентации не отвергает этот случай; по-видимому, он возвращает LHS, если перекрестный продукт положительный, а если vPointOnHull == vEndPoint, перекрестный продукт равен нулю, поэтому никогда не LHS. Так что ничто никогда не заменит точку 0, если точка 0 выбрана и т. Д.
Вы можете изменить Ориентацию, чтобы она возвращала «Вырождение» или что-то в этом случае, а также отклонить точку, или вы можете исключить текущую точку из когда-либо конечной точки. Обратите внимание, что вы не хотите делать очевидную вещь, отфильтровывать текущие точки CH из заданной точки во время прохождения, потому что вам нужно найти, что конечная точка является первой точкой, закрывающей цикл.
Обновление : Оглядываясь немного на вещи FastGEO, вероятно, не стоит обновлять Ориентацию (хотя в этом алгоритме нужно немного больше думать о коллинеарных точках; если есть коллинеарные точки на корпусе, вы действительно хотите сначала найти ближайший, поэтому вам нужно выражение else if Orientation = Collinear then.. update vEndpoint if new point is closer
после этого оператора if).
Проще всего добавить пару строк, отслеживающих текущие показатели, чтобы вы могли легко проверить на равенство: что-то вроде
iPointOnHull := Self.IndexOfLeftMostPoint;
vPointOnHull := Self.LeftMostPoint
...
vEndpoint := Self.Point[0];
iEndPoint := 0;
if (iPointOnHull = 0) then
begin
vEndPoint := Self.Point[1];
iEndPoint := 1;
end
...
vPointOnHull := vEndPoint;
iPointOnHull := iEndPoint;