From: Special Ed
See thats what I need. Except I really need FindColorsPoly, but I can make that happen if I have the groundwork…
function FindColorInPoly(var Points: TPointArray; Color: Integer; Lines: Array of Array of Integer; Tol: Integer): Boolean;
var
Slope: TPointArray;
Current, p, y, i, X1, X2, Y1, Y2: Integer;
Pointss: TPointArray;
Cross: Array of Array of Boolean;
begin
SetArrayLength(Slope, GetArrayLength(Lines));
for i := 0 to GetArrayLength(Lines) - 1 do
begin
Slope[i].x := Lines[i][0] - Lines[i][2];
Slope[i].y := Lines[i][1] - Lines[i][3];
end;
for i := 0 to GetArrayLength(Lines) - 1 do
begin
if (i = 0) then
begin
X1 := Lines[i][0];
Y1 := Lines[i][1];
X2 := Lines[i][2];
Y2 := Lines[i][3];
i := i + 1;
end;
if (Lines[i][0] < X1) then X1 := Lines[i][0];
if (Lines[i][2] < X1) then X1 := Lines[i][2];
if (Lines[i][1] < Y1) then Y1 := Lines[i][1];
if (Lines[i][3] < Y1) then Y1 := Lines[i][3];
if (Lines[i][2] > X2) then X2 := Lines[i][2];
if (Lines[i][0] > X2) then X2 := Lines[i][0];
if (Lines[i][3] > Y2) then Y2 := Lines[i][3];
if (Lines[i][1] > Y2) then Y2 := Lines[i][1];
end;
// WriteLN('X1: ' + IntToStr(X1) + ' Y1: ' + IntToStr(Y1) + ' X2: ' + IntToStr(X2) + ' Y2: ' + IntToStr(Y2));
FindColorsTolerance(Pointss, Color, X1, Y1, X2, Y2, Tol);
// WriteLN(IntToStr(GetArrayLength(Pointss)));
if (GetArrayLength(Pointss) = 0) then Exit;
// WriteLN('');
SetArrayLength(Cross, GetArrayLength(Pointss));
for p := 0 to GetArrayLength(Cross) - 1 do
SetArrayLength(Cross[p], GetArrayLength(Lines));
for p := 0 to GetArrayLength(Pointss) - 1 do
begin
for i := 0 to GetArrayLength(Lines) - 1 do
begin
if (Pointss[p].y > Lines[i][1]) and (Pointss[p].y > Lines[i][3]) then
begin
Cross[p][i] := True;
end else
begin
if (Pointss[p].y > Lines[i][1]) or (Pointss[p].y > Lines[i][3]) then
begin
try
if (Lines[i][1] > Lines[i][3]) then y := ((Lines[i][1] - Pointss[i].y) / Slope[i].y)
else y := ((Lines[i][3] - Pointss[i].y) / Slope[i].y);
except
end;
if (Lines[i][0] < Lines[i][2]) then
begin
if (Lines[i][0] + (Slope[i].x * y) = Pointss[p].x) then
begin
Cross[p][i] := True;
end;
end else
begin
if (Lines[i][2] + (Slope[i].x * y) = Pointss[p].x) then
begin
Cross[p][i] := True;
end;
end;
end;
end;
end;
end;
for p := 0 to GetArrayLength(Pointss) - 1 do
begin
for i := 0 to GetArrayLength(Lines) - 1 do
if (Cross[p][i]) then Current := Current + 1;
// WriteLN(IntToStr(Current));
if (Current mod 2 <> 0) then
begin
SetArrayLength(Points, GetArrayLength(Points) + 1);
Points[GetArrayLength(Points) - 1] := Pointss[p];
end;
Current := 0;
end;
if (GetArrayLength(Points) > 0) then Result := True;
end;
It may be a little buggy. If it pops up with any runtime errors or anything tell me. It worked correctly like this:
var
Lines: Array[0..5] of Array of Integer;
Points: TPointArray;
i: Integer;
begin
Lines[0] := [215, 138, 392, 225];
Lines[1] := [392, 225, 423, 225];
Lines[2] := [423, 225, 443, 234];
Lines[3] := [443, 234, 425, 241];
Lines[4] := [425, 241, 393, 240];
Lines[5] := [393, 240, 215, 138];
if (FindColorInPoly(Points, 6491917, Lines, 1)) then WriteLN('yes');
for i := 0 to GetArrayLength(Points) - 1 do
WriteLN('x: ' + IntToStr(Points[i].x) + ' y: ' + IntToStr(Points[i].y));
end.
I don't think it will return the coordinates of it is on top of a line but I can fix that if it makes a difference.
If you don't understand whatsoever how I made that function, read this:
http://en.wikipedia.org/wiki/Point_in_polygon.
– I have some time so I'll explain how it works (or should work, I'm pretty sure I messed something up):
(0, 1) and (2, 3) makes a line. All of those lines make the polygon. First, I make a square that will pull up some coordinates that are outside of the polygon but will make a starting array. Then, I sort through the array by counting the number of lines it crosses going down the y axis until it is out of the polygon. If that number is odd then it is in the polygon, if the number is even then it is out of the polygon.