还是计算几何, 多边形的核可以这样理解:这个核为原多边形内部的一个多边形,站在这个叫核的多边形中,我们能看到原多边形的任何一个位置。
算法步骤如下:
1.根据原多边形最大和最小的x,y初始化核多边形,就是个矩形。
2.计算多边形当前处理的点的凹凸性。
3.用当前点与其后继点构成直线,判断当前点的前驱点在该直线的左边或右边。
4.用该直线将原核多边形分为两个部分,选择其中一个部分作为处理下一个点将用到的核,选择的依据有以下两点:
1)如果当前点为凸点,那么选择的核与3步中前驱点的所在方向相同。
2)如果当前点为凹点,那么选择的核与3步中前驱点的所在方向相反。
在编程中正好是三个标记连乘为正。
5.使用新的核,计算下一个点,循环第2步直到遍历所有点。
结果如下:
matlab代码如下:
1 clear all;close all;clc;
2
3 n=20;
4 p=rand(n,2);
5
6 p=createSimplyPoly(p);
7 n=n+1;
8 p(n,:)=p(1,:);
9
10 maxX=max(p(:,1));
11 minX=min(p(:,1));
12 maxY=max(p(:,2));
13 minY=min(p(:,2));
14
15 core=[minX minY; %初始化核
16 minX maxY;
17 maxX maxY;
18 maxX minY;
19 minX minY];
20
21 for i=2:n
22 [m ~]=size(core);
23
24 p_pre=p(i-1,:); %多边形当前点的前一个点
25 p_cur=p(i,:); %多边形当前点
26 if i~=n %如果回到第一个点,那么下一个点则为第二个点
27 p_nxt=p(i+1,:);
28 else
29 p_nxt=p(2,:);
30 end
31
32 k=(p_nxt(2)-p_cur(2))/(p_nxt(1)-p_cur(1)); %当前点与下一个点构成的多边形的其中一边
33 b=p_cur(2)-k*p_cur(1);
34 flag=k*p_pre(1)-p_pre(2)+b; %标记当前点的前一个点在该边的左边或右边
35
36 v1=p_pre-p_cur; %计算当期点的凹凸性
37 v2=p_nxt-p_cur;
38 r=det([v1;v2]); %大于0为凸,反之为凹
39
40 re=[];
41 for j=1:m-1
42 core_cur_flag=core(j,1)*k-core(j,2)+b; %标记当前核中的点在边的左边或右边
43 core_nxt_flag=core(j+1,1)*k-core(j+1,2)+b; %标记下一个核中的点在边的左边或右边
44 if r*core_cur_flag*flag>0 %当当前多边形点为凸点,且前一个点和核的点同方向或当前多边形点为凹点,且前一个点和核的点是反方向时标记该点为新核的点
45 re=[core(j,:);re];
46 end
47
48 if core_cur_flag*core_nxt_flag<=0 %标记多边形边与核的边的交点为新核的点
49 if core(j,1)~=core(j+1,1)
50 kbar=(core(j,2)-core(j+1,2))/(core(j,1)-core(j+1,1));
51 bbar=core(j,2)-kbar*core(j,1);
52
53 xx=-(b-bbar)/(k-kbar);
54 yy=-(-bbar*k+b*kbar)/(k-kbar);
55 else
56 xx=core(j,1);
57 yy=k*xx+b;
58 end
59 re=[xx yy;re];
60 end
61
62 end
63
64 core=re;
65 core(size(core,1)+1,:)=core(1,:); %多边形第一个点和最后一个点相同
66 end
67
68 hold on;
69 plot(p(:,1),p(:,2));
70 plot(core(:,1),core(:,2),'r')
71 axis equal;
createSimplyPoly函数在这里,因为生成简单多边形策略的问题,这里几乎所有的多边形都会有核存在的。
部分可能除0的地方没有处理。