アムロがコメントしたように、ポイントの正しい順序を見つけるのは難しい部分です。この機能で十分ですか?
function [idx] = Polyfy(x, y)
% [idx] = Polyfy(x, y)
% Given vectors x and y that contain pairs of points, find the order that
% joins them into a polygon. fill(x(idx),y(idx),'r') should show no holes.
%ensure column vectors
if (size(x,1) == 1)
x = x';
end
if (size(y,1) == 1)
y = y';
end
% vectors from centroid of points to each point
vx = x - mean(x);
vy = y - mean(y);
% unit vectors from centroid towards each point
v = (vx + 1i*vy)./abs(vx + 1i*vy);
vx = real(v);
vy = imag(v);
% rotate all unit vectors by first
rot = [vx(1) vy(1) ; -vy(1) vx(1)];
v = (rot*[vx vy]')';
% find angles from first vector to each vector
angles = atan2(v(:,2), v(:,1));
[angles, idx] = sort(angles);
end
アイデアは、点の重心を見つけてから、重心から各点へのベクトルを見つけることです。これらのベクトルは、三角形の辺と考えることができます。ポリゴンは、各ベクトルが「左」と「右」として一度だけ使用され、ベクトルがスキップされない三角形のセットで構成されます。これは、重心の周りの角度によってベクトルを並べ替えることに要約されます。
ベクトルを単位長に正規化し、そのうちの 1 つを回転ベクトルとして選択し、残りを回転させることでこれを行うことにしました。これにより、単純に atan2 を使用して角度を見つけることができました。おそらく、これを行うためのより高速かつ/またはよりエレガントな方法がありますが、私はトリガーのアイデンティティと混同していました。最後に、これらの角度を並べ替えると、ポイントが目的のポリゴンを形成するための正しい順序が提供されます。
これはテスト関数です:
function [x, y] = TestPolyArea(N)
x = rand(N,1);
y = rand(N,1);
[indexes] = Polyfy(x, y);
x2 = x(indexes);
y2 = y(indexes);
a = polyarea(x2, y2);
disp(num2str(a));
fill(x2, y2, 'r');
hold on
plot(x2, y2, '.');
hold off
end
N = 100 程度を渡すと、かなりワイルドな写真が得られます。