//Based on http://astronomy.swin.edu.au/~pbourke/geometry/insidepoly/

type point = record
              x,y : double;
             end;

type polygon = array of point;

var firstx : double = -1;
    firsty : double = -1;
    poly   : polygon;

function PointInPoly(p : point;poly : polygon) : Boolean;
var i,j : integer;
Begin
 result := false;
 j := High(poly);
 For i := Low(poly) to High(poly) do begin
  if (
   ( ((poly[i].y <= p.y) and (p.y < poly[j].y)) or ((poly[j].y <= p.y) and (p.y < poly[i].y)) ) and
   (p.x < ((poly[j].x - poly[i].x) * (p.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x))
  ) then result := not result;
  j := i
 end;
End;

// más rápido

type tpunto = record x,y:double end;
type tpoligono = array of tpunto;

function PointInPoly( p : tpunto; const v : tpoligono ): boolean;
var
p0,p1:tpunto;
i: integer;
UpSide:boolean;
begin
result:= false;

p1 := v[High(v)];
UpSide := ( p.y < p1.y );
for i := 0 to High(v) do begin
p0 := p1;
p1 := v;
if (UpSide xor (p.y < p1.y)) then begin
if (p.x < (p0.x - p1.x) * (p.y - p1.y) / (p0.y - p1.y) + p1.x) then
result := not result;
UpSide := not UpSide;
end;
end;
end;