<>0. Operation effect

<> Complete steps

<>1. Picture preparation and import

To make an album, enough pictures are essential , Otherwise, there is only one picture in the whole album. How boring it is to repeat back and forth , So we need a folder for pictures , To facilitate import , It's all here jpg format ：

Picture import code ：
path='.\album\';% Folder path files=dir(fullfile(path,'*.jpg')); picNum=size(files,1);
% Traverse each image under the path for i=1:picNum fileName = strcat(path,files(i).name); img = imread(
fileName); imgSet.(['p',num2str(i)])=img; end
<>2. Make a mask layer for each picture
for i=1:length(BlockNum)% Number of ring layers blockNum=BlockNum(i);% Number of pictures per layer Rrange=R(i,:);%
Radius range of one layer at a time for j=1:blockNum tempBoard=ones(2401,2401)==1; tempBoard=tempBoard&(
disMesh>Rrange(1))&(disMesh<Rrange(2)); tempBoard=tempBoard&(thetaMesh>((j-1)*2*
pi/blockNum))&(thetaMesh<(j*2*pi/blockNum)); end end
The fan-shaped structure is constructed by superposition of two judgment conditions ：

* The radius from the center point is [r,R] Range
* And x The included angle of the positive half shaft of the shaft is at [theta1,theta2] between
This is a process of taking intersection , The picture description is about the following ：

Suppose we have built Xmesh,Ymesh matrix
[XMesh,YMesh]=meshgrid(-1200:1:1200,-1200:1:1200);
Distance matrix ：
Then the distance matrix disMesh It can be constructed like this ：
disMesh=sqrt(XMesh.^2+YMesh.^2);
theta Angular matrix ：
We can certainly think of it first atan2, A four quadrant anti sinusoidal function , His mapping relationship is like this ：

Is from z The value range is -pi reach pi, And so x The negative half axis is 0 Angular , Here we will z Value increase pi And flip the axis , Can get theta Angular matrix ：
thetaMesh=atan2(YMesh,XMesh)+pi; thetaMesh=thetaMesh(:,end:-1:1);

After the change is from x Shaft positive half shaft start , Mapping range is [0,2*pi].

<>3. Resize each chart

We found every mask x,y Cut it out of the range ：

Then, the size of the original image is transformed to at least one side length equal to the mask according to the scale , The other side is longer than the mask , Then intercept the center of the picture , The code is as follows ：
for i=1:length(BlockNum)% Number of ring layers blockNum=BlockNum(i);% Number of pictures per layer Rrange=R(i,:);%
Radius range of each layer for j=1:blockNum tempBoard=ones(2401,2401)==1; tempBoard=tempBoard&(
disMesh>Rrange(1))&(disMesh<Rrange(2)); tempBoard=tempBoard&(thetaMesh>((j-1)*2*
pi/blockNum))&(thetaMesh<(j*2*pi/blockNum)); TrueX=find(sum(tempBoard,1)>0);
TrueX):max(TrueX)); x1=YMesh(min(TrueX),min(TrueY)); y1=XMesh(min(TrueX),min(
TrueY)); x2=YMesh(max(TrueX),max(TrueY)); y2=XMesh(max(TrueX),max(TrueY)); xdiff
=x2-x1; ydiff=y2-y1; pic=imgSet.(['p',num2str(tempPic)]); [rows,cols,~]=size(pic
); ratio=[ydiff+1,xdiff+1]./[rows,cols]; newsize=ceil([rows,cols].*max(ratio));
offset=floor((newsize-[ydiff+1,xdiff+1])./2); pic=imresize(pic,newsize); pic=pic
((1:ydiff+1)+offset(1),(1:xdiff+1)+offset(2),:); end end
<>3. Detailed explanation of drawing and drawing parameters

Basic parameters ：

BlockNum=[7,11];% Number of sectors per floor
R=[300,670;% Radius range of the first floor
670,1090];% Radius range of the second layer
lineColor=[0.98,0.98,0.98]; Line color
lineWidth=2;% Line thickness

We'll talk about the properties of the line later

Drawing is directly used image function , There's nothing to say about this , If there are not many pictures in the folder, we will use the remainder method to cycle the previous pictures ：
tempPic=1; for i=1:length(BlockNum) blockNum=BlockNum(i); for j=1:blockNum
tempPic=tempPic+1; tempPic=mod(tempPic-1,picNum)+1; end end
We find that the edge aliasing is more serious when drawing directly ：

It's easy for us to think of drawing lines to hide our ugliness ：
t=0:0.001:(2*pi+0.001); for i=1:length(BlockNum) blockNum=BlockNum(i); Rrange=R
(i,:); for j=1:blockNum plot(cos(j*2*pi/blockNum).*Rrange,sin(j*2*pi/blockNum).*
Rrange,'Color',lineColor,'LineWidth',lineWidth) end plot(cos(t).*Rrange(1),sin(t
).*Rrange(1),'Color',lineColor,'LineWidth',lineWidth) plot(cos(t).*Rrange(2),sin
(t).*Rrange(2),'Color',lineColor,'LineWidth',lineWidth) end

Of course, you can also draw a black line ：
It only needs lineColor=[0,0,0] perhaps lineColor='k’ that will do

<>4. Complete code
function ringAlbum BlockNum=[7,11]; R=[300,670; 670,1090]; lineColor=[0.98,0.98
,0.98]; lineWidth=2; path='.\album\';% Folder name files=dir(fullfile(path,'*.jpg'));
picNum=size(files,1); % Traverse each image under the path for i=1:picNum fileName = strcat(path,files(i)
.name); img = imread(fileName); imgSet.(['p',num2str(i)])=img; end fig=figure(
'units','pixels',... 'position',[20 60 560 560],... 'Color',[1 1 1]); ax=axes(
'Units','pixels',... 'parent',fig,... 'Color',[1 1 1],... 'Position',[0 0 560,
560],... 'XLim',[-1200,1200],... 'YLim',[-1200,1200],... 'XColor','none',...
'YColor','none'); hold(ax,'on') ax.YDir='reverse'; ax.XDir='normal'; [XMesh,
YMesh]=meshgrid(-1200:1:1200,-1200:1:1200); disMesh=sqrt(XMesh.^2+YMesh.^2);
thetaMesh=atan2(YMesh,XMesh)+pi; thetaMesh=thetaMesh(:,end:-1:1); tempPic=1; t=0
:0.001:(2*pi+0.001); for i=1:length(BlockNum) blockNum=BlockNum(i); Rrange=R(i,:
); for j=1:blockNum tempBoard=ones(2401,2401)==1; tempBoard=tempBoard&(disMesh>
Rrange(1))&(disMesh<Rrange(2)); tempBoard=tempBoard&(thetaMesh>((j-1)*2*pi/
blockNum))&(thetaMesh<(j*2*pi/blockNum)); TrueX=find(sum(tempBoard,1)>0); TrueY=
max(TrueX)); x1=YMesh(min(TrueX),min(TrueY)); y1=XMesh(min(TrueX),min(TrueY));
x2=YMesh(max(TrueX),max(TrueY)); y2=XMesh(max(TrueX),max(TrueY)); xdiff=x2-x1;
ydiff=y2-y1; pic=imgSet.(['p',num2str(tempPic)]); [rows,cols,~]=size(pic); ratio
=[ydiff+1,xdiff+1]./[rows,cols]; newsize=ceil([rows,cols].*max(ratio)); offset=
floor((newsize-[ydiff+1,xdiff+1])./2); pic=imresize(pic,newsize); pic=pic((1:
ydiff+1)+offset(1),(1:xdiff+1)+offset(2),:); image(ax,[x1,x2],[y1,y2],pic,