判断一点是否在一多边型内

  • 主题发起人 主题发起人 import
  • 开始时间 开始时间
I

import

Unregistered / Unconfirmed
GUEST, unregistred user!
function ptInPolygon(x,y : integer; Points: array of TPoint) : boolean; var
rgn:HRGN;
bmp : Tbitmap;
begin
bmp := Tbitmap.create;
BeginPath(bmp.canvas.handle); //开始记录路径
bmp.Canvas.Polygon(points);
EndPath(bmp.canvas.handle); // 闭合路径
rgn:= PathToRegion(bmp.canvas.handle); // 简切视窗
result := PtInRegion(rgn,x,y); // 判断
bmp.free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if ptinpolygon(1000,1000,[Point(10, 10), Point(30, 10),
Point(130, 30), Point(240, 120)]) then showmessage('In!')
else showmessage('out!');
end;
***********************************
下面是真正的实现的算法:
huizhang (1998-12-31 8:01:35)
实在对不起, 那个算法确实有问题, 缺少一点判断。
现在给你另外一个算法,叫做“跳栅栏算法”。其原理如下:
 
假设有一个栅栏,你从现在所站地点沿着一个方向跑过去,遇到栅栏时就跳过去,记住你跳了几次。如果次数是单数,则你在栅栏内;如果是双数,则你在栅栏外。以下算法是向东跑过去的实现方法。该算法虽然用了一点除法,但是由于排除了不相关的栅栏,故速度也很快。此外它的优点是与多边形的排列方向无关。
 
function TForm1.PointInFence(p: TPoint; Fence: Array of TPoint): boolean;
var
p1: TPoint;
ar: integer;
i, j: integer;
begin
ar:=0;
for i:=0 to PtNos-1 do
begin
if i=PtNos-1 then j:=0 else j:=i+1;
//如果在所站点的水平方向上有栅栏存在
if ((((p.y>=Fence.y) and (p.y<fence[j].y)) or
((p.y>=fence[j].y) and (p.y<fence.y))) and
//且栅栏在我的右方
(p.x<(fence[j].x-fence.x)*(p.y-fence.y)/(fence[j].y-fence.y)+fence.x)) then
ar := Ar+1;
end;
result:= (Ar and $1) > 0;
end;
 

Similar threads

后退
顶部