1
考虑一个直径为10的圆,在其中做一个内接正十边形,计算其形状数
1.1 求围盒和单位格大小
本题中圆的直径为10个像素,其函数方程为 x^2+y^2=5,则 x=5cost,y=5sint
,那么正十边形的十个边界点为 x=5cos(n*pi/5),y=5sin(n*pi/5),n=0,1,...,10
那么可以得到正十边形宽度为10,长度为9.5106,其长宽比为1.051:1,接近于1,因此围盒大小为10×10平方像素单位,单位格大小为1×1平方像素单位,阶数为40。围盒和单位格如图1黑色方框所示。
1.2 求出边界多边形
本题我采用的是将面积的50%以上包在边界内的正方形划入内部的方法,得到了与边界最吻合的多边形如图1蓝色线框所示。

图
1
正十边形的形状数计算示意图
1.3 求链码与差分码
以(-5,
0)
为起始点,按顺时针方向循环计算链码,其为一个由方向数构成的自然数,结果为:1-1-0-1-0-1-0-1-0-0-0-0-3-0-3-0-3-0-3-3-3-3-2-3-2-3-2-3-2-2-2-2-1-2-1-2-1-2-1-1。
为了解决链码会因为目标旋转而改变的问题,我们需要利用链码的一阶差分来重新构造一个序列,主要采取相邻两个方向数相减得到,结果为:0-0-3-1-3-1-3-1-3-0-0-0-3-1-3-1-3-1-3-0-0-0-3-1-3-1-3-1-3-0-0-0-3-1-3-1-3-1-3-0。
1.4 求形状数
形状数是值最小的差分码,因此我们要对差分码进行循环进而得到直径为10的圆的内接正十边形的形状数为:0-0-0-3-1-3-1-3-1-3-0-0-0-3-1-3-1-3-1-3-0-0-
0-3-1-3-1-3-1-3-0-0-0-3-1-3-1-3-1-3。
2
计算该正十边形与圆两形状之间的距离(此时不限定正多边形和圆的尺寸)
2.1 距离计算
利用第一题给的步骤对圆形和圆形的内接正十边形分别计算形状数大小,其形状数如表1所示,可以明显看出圆形和正十边形的相似度为22,其距离D=1/k=1/22。
表 1
圆形和正十边形的各阶形状数
|
圆形
|
正十边形
|
4阶
|
3-3-3-3
|
3-3-3-3
|
…
|
…
|
…
|
22阶
|
0-0-1-3-1-0-1-3-1-0-0-1-3-1-0-1-3-1-3-1-3-1
|
0-0-1-3-1-0-1-3-1-0-0-1-3-1-0-1-3-1-3-1-3-1
|
24阶
|
0-0-3-1-3-0-0-0-3-1-3-0-0-0-3-1-3-0-0-0-3-1-3-0
|
0-3-1-3-1-3-0-3-1-3-1-3-0-3-1-3-1-3-0-3-1-3-1-3
|
3 部分源码
clear all;
clc;
%%%%%%%%%%%%%%%%%%%%%%%画围盒
layer=22; %形状数的阶数
w1=0;
h1=0;
minx1=0;
maxx1=0;
miny1=0;
maxy1=0;
if mod(layer,4)==0;
w1=layer/4;
h1=layer/4;
minx1=-5;
maxx1=5;
miny1=-5;
maxy1=5;
point(1,1)=1;
point(2,1)=fix(h1/2)+1;
else
w1=fix(layer/4)+1;
h1=fix(layer/4);
miny1=-5;
maxy1=5;
minx1=-5*w1/h1;
maxx1=5*w1/h1;
point(1,1)=fix(w1/2)+1;
point(2,1)=1;
end;
rectangle('Position',[minx1,miny1,maxx1-minx1,maxy1-miny1],'EdgeColor','k');
%%%%%%%%%%%%%%%%%%%%%%%画等边正方形
w2=(maxx1-minx1)/w1;
h2=(maxy1-miny1)/h1;
......
%%%%%%%%%%%%%%%%%%%%%%计算链码
count=1;
while 1;
if point(1,count)+1<=w1+1
&&
boundry1(point(1,count)+1,point(2,count))~=0
&&
boundry1(point(1,count)+1,point(2,count))~=100
&& (count==1 ||
point(1,count)+1~=point(1,count-1));
flag(count)=0;
point(1,count+1)=point(1,count)+1;
point(2,count+1)=point(2,count);
else
if point(2,count)+1<=h1+1
&&
boundry1(point(1,count),point(2,count)+1)~=0
&&
boundry1(point(1,count),point(2,count)+1)~=100
&& (count==1 ||
point(2,count)+1~=point(2,count-1));
flag(count)=1;
point(1,count+1)=point(1,count);
point(2,count+1)=point(2,count)+1;
else
if point(1,count)-1>0
&&
boundry1(point(1,count)-1,point(2,count))~=0
&&
boundry1(point(1,count)-1,point(2,count))~=100
&& (count==1 ||
point(1,count)-1~=point(1,count-1));
flag(count)=2;
point(1,count+1)=point(1,count)-1;
point(2,count+1)=point(2,count);
else
if point(2,count)-1>0;
flag(count)=3;
point(1,count+1)=point(1,count);
point(2,count+1)=point(2,count)-1;
end;
end;
end;
end;
a=minx1+([boundry1(point(1,count),point(2,count)),boundry1(point(1,count+1),point(2,count+1))]-1)*w2;
b=miny1+([boundry2(point(1,count),point(2,count)),boundry2(point(1,count+1),point(2,count+1))]-1)*h2;
plot(minx1+(boundry1(point(1,count+1),point(2,count+1))-1)*w2,miny1+(boundry2(point(1,count+1),point(2,count+1))-1)*h2,'*b');
plot(a,b,'b','LineWidth',2);
count=count+1;
if point(1,count)==1 &&
point(2,count)==fix(h1/2)+1;
break;
end;
if count>layer;
%防止程序进入死循环
break;
end;
end;
title(strcat('圆形
阶数:',int2str(layer)));
%%%%%%%%%%%%%%%%%%%%%%%计算差分链码
Dflag(1)=mod(flag(1)-flag(count-1),4);
for i=2:count-1;
Dflag(i)=mod(flag(i)-flag(i-1),4);
end;