如何寻找一点的封闭边界?(200分)

  • 主题发起人 主题发起人 liuxuqi
  • 开始时间 开始时间
L

liuxuqi

Unregistered / Unconfirmed
GUEST, unregistred user!
用autocad所做的中国地图,省与省的交界处用一条线(有句柄)代替。现在如果我已知该省的省会
城市坐标,如何查找出该省的边界。
就这个问题象大家请教。
我认为:可以分解为二个问题,一是用什么算法能够求出某封闭区域中最小的一块封闭区域。
就是说中国地图中的湖北省的边界?
二是如何判断一点在封闭区域内?

 
第二个问题好解决。
判断一点在某个封闭区域中好说。用PtInRegion就可以了。
但是,第一个问题,它与最短路径不同,与旅行员售货问题也不同。
关键是要找出最小的封闭区域。
 
function ptInPolygon(x,y : integer;
Points: array of TPoint) : boolean;

var
rgn:HRGN;

bmp : Tbitmap;

begin

bmp := Tbitmap.create;

begin
Path(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-1do

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;
 
我记得地图中,每个省与其相邻省的颜色标记时不同的;
所以,我们可以利用[red]连通域的种子搜索算法[/red]来实现边界的查找。

建议你看看我这里的程序,是连通域的色替换,与你的意思大致是一致的;
自己再改改就是了。

http://www.delphibbs.com/delphibbs/dispq.asp?lid=929636
 
谢谢yanlei,你提供的程序前半部分可以判断一点在某个封闭区域中。

谢谢卷起千堆雪tyn,我现在主要需要在数据库上做文章。我已知所有的坐标的经度和纬度。
实际上这个问题可以通俗地说是这样:
在一个大的封闭区域中怎么样求出其中最小的封闭区域。一条直线最多属于二个小的封闭区域。
当围成一个封闭区域后,这些直线是首尾相连的。
 
问题解决。其实是一个算法问题。
 
后退
顶部