判断点是否在区域内

function PtInArea(InPoint: TGPPointF; AreaPts:array of TGPPointF): Boolean;

var
nCross, PointIndex: Integer;
TempSP, TempEP, InTempP: TGPPointF;
TempX: Single;
begin
nCross := 0;
Result := False;
if Length(AreaPts)<3 then
Exit;

InTempP.X := Round(InPoint.X * 100);
InTempP.Y := Round(InPoint.Y * 100);
for PointIndex := 0 to Length(AreaPts) - 1 do
begin
TempSP.X := Round(AreaPts[PointIndex].X * 100);
TempSP.Y := Round(AreaPts[PointIndex].Y * 100);
if PointIndex = Length(AreaPts) - 1 then
begin
TempEP.X := Round(AreaPts[0].X * 100);
TempEP.Y := Round(AreaPts[0].Y * 100);
end
else
begin
TempEP.X := Round(AreaPts[PointIndex + 1].X * 100);
TempEP.Y := Round(AreaPts[PointIndex + 1].Y * 100);
end;

if TempSP.Y = TempEP.Y then
begin
if (InTempP.Y = TempSP.Y) and (InTempP.X >= Min(TempSP.X, TempEP.X)) and (InTempP.X <= Max(TempSP.X, TempEP.X)) then
begin
Result := True;
Exit;
end;
end
else if TempSP.X = TempEP.X then
begin
if (InTempP.X = TempSP.X) and (InTempP.Y >= Min(TempSP.Y, TempEP.Y)) and (InTempP.Y <= Max(TempSP.Y, TempEP.Y)) then
begin
Result := True;
Exit;
end;
end;

if (TempSP.Y <> TempEP.Y) and (InTempP.Y > Min(TempSP.Y, TempEP.Y)) and (InTempP.Y <= Max(TempSP.Y, TempEP.Y)) and (InTempP.X <= Max(TempSP.X, TempEP.X)) then
begin
if (TempSP.X = TempEP.X) then
begin
nCross := nCross + 1;
end
else
begin
TempX := Round((InTempP.Y - TempSP.Y) * (TempEP.X - TempSP.X) / (TempEP.Y - TempSP.Y) + TempSP.X);
if InTempP.X <= TempX then
nCross := nCross + 1;
end;
end;
end;

if (nCross mod 2 = 1) then
Result := True
else
Result := False;
end;

原文地址:https://www.cnblogs.com/jeenmablog/p/12020595.html