基于Matlab的六边形细胞自动机

1.简介

目前大多数细胞自动机都是矩形的,这个是六边形的。

生存规则在倒数13 - 倒数18行。

2.演示

下面是两种不同规则的动画。

 

3.程序

clear;

N_col = 20;
% 列数设置
N_row = round(N_col/0.433*1.5/1.2);
Cell = zeros(N_row,N_col, 14,2);
% Cell - [细胞状态 细胞中点坐标 六个边点坐标 六个邻近图形序号]
% 细胞状态(1)- [当前状态 下一步状态]; 0- 死亡 ,1- 存活。
% 中方点坐标(2)- [x, y]
% 六个边点坐标(3~8)- [x,y]。
% 六个邻近图形行、列号(9~14)- [行号,列号]。


% 生成六边形中点坐标 %
y_point= 0;
for i_row =1:1:N_row
    if(mod(i_row,2)==1)
        x_point = 0.5;
    else
        x_point = 1.25;
    end
    y_point= y_point+ 0.433;
    for i_col = 1:1:N_col
        x_point = x_point+ 1.5;
        Cell(i_row, i_col,2,:)= [x_point,y_point];
    end
end

% 生成六边形角点坐标 %
Cell(:,:,3,1)= Cell(:,: ,2,1)-0.5;
Cell(:,:,[4,8],1)= repmat(Cell(:,: ,2,1)-0.25,1,1,2);
Cell(:,:,[5,7],1)= repmat(Cell(:,: ,2,1)+0.25,1,1,2);
Cell(:,:,6,1)= Cell(:,: ,2,1)+0.5;
Cell(:,:,[3,6],2)= repmat(Cell(:,: ,2,2),1,1,2);
Cell(:,:,[4,5],2)= repmat(Cell(:,: ,2,2)+0.433,1,1,2);
Cell(:,:,[7,8],2)= repmat(Cell(:,: ,2,2)-0.433,1,1,2);

% 绘制中点 %
plot(Cell(:, :,2,1),Cell(:, :,2,2),'LineStyle','none','Marker','.','color','b' );hold on;
if(Cell(N_row,N_col,2,1)>1.2*Cell(N_row,N_col,2,2))
    xlim([0, Cell(N_row,N_col,2,1)]+1.5);ylim([0, Cell(N_row,N_col,2,1)]./1.2);
else
    xlim([0, Cell(N_row,N_col,2,2).*1.2+1]);ylim([0, Cell(N_row,N_col,2,2)]);
end

% 绘制六边形 %
pic= cell(N_row,N_col);
for i=1:1:N_row
    for j=1:1:N_col
        pic{i,j}= patch(reshape(Cell(i,j,3:8,1),[1,6]),reshape(Cell(i,j,3:8,2),[1,6]),'w');
    end
end

% 寻找邻近图形的行、列号(没有细胞的位置为[-1,-1])
for i_center=1:1:N_row
    for j_center=1:1:N_col
        for i=1:1:6
            found = 0;
            % 在目标细胞附近 士2 格的范围内寻找,减少运算量
            for i_find= max(1, i_center-2):min(N_row, i_center+2)
                for j_find= max(1, j_center-2):min(N_col, j_center+2)
                    distance = sqrt((Cell(i_center, j_center,2,1)- Cell(i_find, j_find,2,1))^2 ...
                        + (Cell(i_center, j_center,2,2)- Cell(i_find, j_find,2,2))^2);
                    % 初步根据距离判断
                    if distance> 0.85 && distance< 0.9
                        x_range = [1,1].* cos(1.0472* (i-1)-0.5236)* distance+ [-0.1 0.1]+ Cell(i_center, j_center,2,1);
                        y_range = [1,1].* sin(1.0472* (i-1)-0.5236)* distance+ [-0.1 0.1]+ Cell(i_center, j_center,2,2);
                        % 再根据夹角判断
                        if  Cell(i_find, j_find,2,1)> x_range(1) && Cell(i_find, j_find,2,1)< x_range(2) ...
                                && Cell(i_find, j_find,2,2)> y_range(1) && Cell(i_find, j_find,2,2)< y_range(2)
                            Cell(i_center, j_center,i+8,:) = [i_find, j_find];
                            found= 1;
                        end
                    end
                end
            end
            if found ==0
                Cell(i_center, j_center,i+8,:)= -1;
            end
        end
    end
end

% 赋予细胞随机初试状态
Cell( :, :, 1, 1)=round(rand(N_row, N_col));

% 开始迭代
while 2>1
    for i=1:1:N_row
        for j=1:1:N_col
            % 计算细胞周围存活细胞数量
            N_live = 0;
            for k=1:1:6
                if Cell( i, j, k+8, 1)~= -1 && Cell( i, j, k+8, 2)~= -1
                    N_live = N_live+ Cell(Cell( i, j, k+8, 1), Cell( i, j, k+8, 2), 1, 1);
                end
            end
            % 判断生死
            if N_live>4 || N_live<3
                Cell( i, j, 1, 2)= 0;
            else
                Cell( i, j, 1, 2)= 1;
            end
            % 更新显示状态
            if Cell( i, j, 1, 1) >0.5
                set(pic{i, j},'FaceColor',[0.5 1 0.5]);
            else
                set(pic{i, j},'FaceColor',[1 1 1]);
            end
        end
    end
    drawnow;
    % 更新生死状态
    Cell( :, :, 1, 1)= Cell( :, :, 1, 2);
end

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值