При полигональном выделении области СЛИШКОМ приблизительно вычисляется количество тайлов в ней. Я полагаю вычисляется площадь охватывающего полигон прямоугольника.
Если координаты (в пикселях) вершин полигона выделения поделить на 256, то получим многоугольник с вершинами, заданными в тайловых координатах. Площадь этого полигона будет равна количеству тайлов внутри полигона.
Ниже функции вычисления площади многоугольника без самопересечений. Туда передаётся массив TPoint'ов. В этих TPoint'ах уже должны быть координаты тайлов, на которые приходятся вершины полигона. Функции вычисления площади самопересеченных многоугольников ещё не готовы, зато есть простая функция определения наличия самопересечений. Если она возвращает True, то можно считать пока как считали. а если false, то извольте =) показать точное количество тайлов.
- Код: Выделить всё
function Square(Poly: array of TPoint): Real;
var
i, n : Integer;
begin
n := Length(Poly);
Result := 0;
if n < 3 then
Exit;
i := 0;
while i < n - 1 do
begin
Result := Result + (Poly[i].x + Poly[i + 1].x) * (Poly[i].y - Poly[i + 1].y);
inc(i);
end;
Result := Result + (Poly[i].x + Poly[0].x) * (Poly[i].y - Poly[0].y);
Result := 0.5 * Abs(Result);
end;
function SCrossing(L1A, L1B, L2A, L2B: TPoint; var P: TPoint): boolean;
var
u1, u2, zn: real;
begin
u1 := (L2B.x-L2A.x)*(L1A.y-L2A.y) - (L2B.y-L2A.y)*(L1A.x-L2A.x);
u2 := (L1B.x-L1A.x)*(L1A.y-L2A.y) - (L1B.y-L1A.y)*(L1A.x-L2A.x);
zn := (L2B.y-L2A.y)*(L1B.x-L1A.x) - (L2B.x-L2A.x)*(L1B.y-L1A.y);
result := not IsZero(zn);
if result then
begin
u1 := u1 / zn;
u2 := u2 / zn;
p.x := round(L1A.x + u1 * (L1B.x - L1A.x));
p.y := round(L1A.y + u1 * (L1B.y - L1A.y));
result := (u1 >= 0) and (u1 <= 1) and (u2 >= 0) and (u2 <= 1);
end;
end;
function SimpleCheckSelfCrossing(Poly: array of TPoint): boolean;
function EqPoints(p1, p2: TPoint): boolean;
begin
result := (p1.X = p2.X) and (p1.Y = p2.Y);
end;
var
i, j, n: integer;
p: TPoint;
begin
result := false;
n := Length(Poly);
if n < 4 then
Exit;
for i := 0 to n - 1 - 1 do
for j := 0 to n - 3 - 1 do
begin
result := EqPoints(Poly[i], Poly[(i + 2 + j) mod n]);
result := result or SCrossing(
Poly[i],
Poly[(i + 1) mod n],
Poly[(i + 2 + j) mod n],
Poly[(i + 2 + j + 1) mod n],
p);
if result then
Exit;
end;
end;
P.S.
Требуется подключить модуль math.