SRL Archive - General

Calculating the area of a self intersecting polygon


mxtrix

2014-03-17 04:03:27

Hey guys, I am currently trying to figure out how to accomplish this. For those who do not know a self intersecting polygon looks like:

[ATTACH=CONFIG]23091[/ATTACH]

The area of a normal polygon (of which does not self intercept) can be calculated using the shoelace formula however one of its limitations is that it must be a normal polygon. So far I have created a script which can find the points where the polygon intercepts with itself (the red dot on the above picture) however I need to find a way to split the self intersecting polygon into several normal polygons. It may be easy enough for the image above but if there are multiple interception points then it becomes increasingly complicated to accomplish this task. Does anyone have any ideas on how this could be accomplished? cheers.

Frement

2014-03-17 06:35:38

I think this function should do the job.

procedure FillPolygon(Clear: Boolean; Points: TPointArray; Color: LongInt; Transparency: Extended);
var
C, R, G, B, R2, G2, B2: LongInt;
I, J, N, M: Integer;
XF: T2DIntegerArray;
YF: TIntegerArray;
begin
ColorToRGB(Color, R2, G2, B2);
SetLength(XF, N);
SetLength(YF, N);
for I := 0 to High(Points) do begin
M := 0;
Inc(N);
Inc(M);
SetLength(XF, N);
SetLength(XF[N - 1], M);
SetLength(YF, N);
XF[High(XF)][M - 1] := Points[I].X;
YF[High(YF)] := Points[I].Y;
for J := 0 to High(Points) do begin
if (Points[J].Y = Points[I].Y) and (Points[J].X <> Points[I].X) then begin
Inc(M);
SetLength(XF[N - 1], M);
XF[High(XF)][M - 1] := Points[J].X;
end;
end;
end;
for I := 0 to High(YF) do begin
QuickSort(XF[I]);
for J := XF[I][0] to XF[I][High(XF[I])] do begin
C := GetTClient.IOManager.GetColor(J, YF[I]);
ColorToRGB(C, R, G, B);
R := Round((R * (1.0 - Transparency)) + (R2 * Transparency));
G := Round((G * (1.0 - Transparency)) + (G2 * Transparency));
B := Round((B * (1.0 - Transparency)) + (B2 * Transparency));
C := RGBToColor(R, G, B);
if (J > 0) then
SMART_Canvas.FastSetPixel(J, YF[I], C);
end;
end;
end;

You need to create lines between all the points, and merge them to one TPA, then pass that TPA to the function.