原理:
1,点在直线上:点到直线的垂直距离是否为小于最小阈值。如果是判断点是否在线段内则
求垂足是否在线段内。
function IsPtAtLine(X,Y : Double;PtList : TList;OffSet : double) : Boolean;
var
TX1,TY1,TX2,TY2,VX1,VY1,LL : double; {交点}
An1,An2 : double; {角度}
I : integer;
GeoPt : PGeoPoint;
begin;
result := FALSE;
for I := 0 to PtList.Count - 2 do begin
GeoPt := PGeoPoint(PtList.Items);
TX1 := GeoPt^.X;
TY1 := GeoPt^.Y;
GeoPt := PGeoPoint(PtList.Items[I + 1]);
TX2 := GeoPt^.X;
TY2 := GeoPt^.Y;
if IsPtInRect(X,Y,TX1,TY1,TX2,TY2) then begin
An1 := GetDirection(TX1,TY1,X,Y);
An2 := GetDirection(TX1,TY1,TX2,TY2);
if Abs(Sin(An1 - An2) * GetLength(TX1,TY1,X,Y)) < Offset then begin
result := TRUE;
Exit;
end;
end
else begin
if Abs(TX1 - TX2) < Offset then begin
if (Y > GetMin(TY1,TY2)) and (Y < GetMax(TY1,TY2)) and (Abs(X - TX1) < Offset) then begin
result := TRUE;
exit;
end;
end;
if Abs(TY1 - TY2) < Offset then begin
if (X > GetMin(TX1,TX2)) and (X < GetMax(TX1,TX2)) and (Abs(Y - TY1) < Offset) then begin
result := TRUE;
exit;
end;
end;
end;
end;
end;
2,点是否在多边形内:过此点的直线同多边形的一侧交点数是否为奇数。
function IsPtInRegion(X,Y : Double;PtList : TList) : Boolean;
var
TX1,TY1,TX2,TY2 : double; {交点}
I : integer;
LCount,RCount : integer; {射线左右交点个数}
XX,YY : double;
GeoPt : PGeoPoint;
begin
LCount := 0;
RCount := 0;
for I := 0 to PtList.Count - 2 do begin
GeoPt := PGeoPoint(PtList.items);
TX1 := GeoPt^.X;
TY1 := GeoPt^.Y;
GeoPt := PGeoPoint(PtList.items[I + 1]);
TX2 := GeoPt^.X;
TY2 := GeoPt^.Y;
GetIntersectedPoint(X - 10,Y,X,Y,TX1,TY1,TX2,TY2,XX,YY,2);
if (XX < X) and IsPtInRect(XX,YY,TX1,TY1,TX2,TY2) then Inc(LCount);
end;
if (LCount Mod 2) <> 0 then Result := TRUE else Result := FALSE;
end;
其中TList中的数据类型为:
PGeoPoint = ^TGeoPoint;
TGeoPoint = record
X,Y : double;
end;
//获得X1,Y1,X2,Y2的交点,无交点时返回FALSE,Flag为1时交点必须位于两个矩形交叉区域内,Flag为2时交点为广义交点,即直线的延长线有效
//注意:Flag为2时前四个参数一定为剪切线}
function GetIntersectedPoint(X1,Y1,X2,Y2,X3,Y3,X4,Y4 : Double;var XX,YY : double;Flag : integer):Boolean;
var
K1,K2,B1,B2 : double; {二条直线的斜率}
V1,V2 : Boolean; {有斜率为无穷大的线存在}
// V1,V2 : integer; {1 :初始值,2:TRUE, 3 : FALSE}
begin
//X1,Y1,X2,Y2 为第一条直线,X3,Y3,X4,Y4 为第二条直线}
V1 := FALSE;
V2 := FALSE;
K1 := 1.7 * 10e308;
K2 := 5 * 10 - 324;
B1 := K1;
B2 := K2;
if Abs(X2-X1)>0.00000000001 then begin
K1 := (Y2-Y1)/(X2-X1);
B1 := Y1-K1*X1;
end
else begin
XX := X1;
V1 := TRUE;
end;
if Abs(X4-X3)>0.00000000001 then begin
K2 := (Y4-Y3)/(X4-X3);
B2 := Y3-K2*X3;
end
else begin
XX := X3;
V2 := TRUE;
end;
if (Abs(K1 - K2) < 0.000000000000001) or (V1 and V2) then begin
Result := FALSE;
Exit;
end;
if (not V1) and (not V2) then begin
XX := (B1-B2)/(K2-K1);
YY := K1*XX+B1;
end
else if V2 then begin
YY := K1*XX+B1;
end else begin
YY := K2*XX+B2;
end;
if Flag = 1 then begin
//如果计算出来的交点位于两个矩形的公共区域,则为真交点}
if (IsPtInRect(XX,YY,X1,Y1,X2,Y2)) and (IsPtInRect(XX,YY,X3,Y3,X4,Y4)) then
result := TRUE
else
result := FALSE;
end
else
if Flag = 2 then begin
if (IsPtInRect(XX,YY,X3,Y3,X4,Y4)) then
result := TRUE
else
result := FALSE;
end;
end;
function IsPtInRect(X, Y: Double; X1,Y1,X2,Y2 : double):Boolean;
const
Buf : double = 10e-10;
begin
Result := (X > MinValue([X1,X2])- Buf) and (X < MaxValue([X1,X2]) + Buf) and (Y > MinValue([Y1,Y2]) - Buf) and (Y < MaxValue([Y1,Y2]) + Buf);
end;
::