Я пытаюсь реализовать алгоритм Джарвиса для нахождения выпуклой оболочки множества точек, но по какой-то причине это не работает. Это моя реализация:
procedure TPointList.ConvexHull(aHull : TPointList); //Return the convex hull of a set of 2D points
var
vPointOnHull : TPoint2D;
vEndpoint : TPoint2D;
I : integer;
begin
aHull.Clear;
if Count < 3 then exit;
vPointOnHull := Self.LeftMostPoint;
repeat
aHull.Add(vPointOnHull);
vEndpoint := Self.Point[0];
for I := 1 to Self.Count-1 do
if Orientation(vPointOnHull,vEndpoint,Self.Point[I]) = LeftHandSide then
vEndpoint := Self.Point[I];
vPointOnHull := vEndpoint;
until vEndpoint = aHull.Point[0];
end;
- TPointList - это простой список точек.
- Ориентация - это функция из библиотеки Arash Partow "FastGEO"
- Реализация снята более или менее непосредственно из статьи в Википедии об алгоритме
Что происходит, так это то, что метод начинает добавлять одну и ту же точку в aHull снова и снова. В одном тестовом случае я посылаю в точках (200; 200) (300; 100) (200; 50) и (100; 100), и алгоритм начинается с добавления (100; 100) в aHull, который является правильным, но затем он начинает добавлять (200; 200) снова и снова.
Очевидно, что я сделал что-то не так в моей реализации, но для жизни меня не вижу, что.
UPDATE:
Джонатан Дурси поставил меня на правильный путь. Эта строка
if Orientation(vPointOnHull,vEndpoint,Self.Point[I]) = LeftHandSide then
следует заменить на это
if (vPointOnHull = vEndpoint) or (Orientation(vPointOnHull,vEndpoint,Self.Point[I]) = LeftHandSide) then
Работает как шарм: -)