• MATLAB | 一种简易的随机曼陀罗图形生成函数


    Wolfram Alpha艺术展的时候看到了一个很有趣的随机曼陀罗图像生成函数库,本人尝试仿写了一个简易版本,原始函数大体原理就是生成一系列随机点之后对其进行多次旋转,思想非常简单。

    完整代码

    function randMandalas(varargin)
    % @author : slandarer
    % @公众号 : slandarer随笔
    
    pntNum=randi([5,6],[1,1]);      % 随机点数量
    rotateTimes=randi([5,6],[1,1]);                  % 旋转次数
    
    randLenth=zeros([1,pntNum]);
    disMat=inf.*ones(pntNum);
    % 生成距离不太近,半径不太小的随机点
    while all(randLenth<0.8)||any(any(disMat<0.5))
        randTheta=rand([1,pntNum]).*2.*pi;
        randLenth=rand([1,pntNum]);
    
        disMat=abs((randLenth-randLenth').*(randTheta+randTheta')./2);
        disMat(eye(pntNum)==1)=inf;
    end
    randTheta=[randTheta,randTheta(1)];
    randLenth=[randLenth,randLenth(1)];
    X0=cos(randTheta).*randLenth; 
    Y0=sin(randTheta).*randLenth;
    
    % 坐标区域修饰
    if nargin<2
        ax=gca;
    else
        ax=varargin{1};
        varargin(1)=[];
    end
    if nargin==0
        varargin{1}='fill';
    end
    hold on;
    ax.XLim=[-1,1];
    ax.YLim=[-1,1];
    ax.XColor='none';
    ax.YColor='none';
    ax.PlotBoxAspectRatio=[1,1,1];
    
    % 绘制图像
    [tX1,tY1]=rotateData(X0,Y0,2*pi/rotateTimes);
    [tX2,tY2]=rotateData(-X0,Y0,2*pi/rotateTimes);
    showPnts(ax,tX1,tY1,varargin{1})
    showPnts(ax,tX2,tY2,varargin{1})
    for i=1:rotateTimes-1
        [tX1,tY1]=rotateData(tX1,tY1,2*pi/rotateTimes);
        [tX2,tY2]=rotateData(tX2,tY2,2*pi/rotateTimes);
        showPnts(ax,tX1,tY1,varargin{1})
        showPnts(ax,tX2,tY2,varargin{1})
    end
    
    % 根据方法绘制图像
        function showPnts(ax,X,Y,tmethod)
            switch tmethod
                case 'line'
                    plot(ax,X,Y,'Color',[0 0 0]);
                case 'fill'
                    fill(ax,X,Y,[0 0 0],'FaceAlpha',.2);
                case 'bezier'
                    XY=bezierCurve([X(:),Y(:)],50);
                    plot(ax,XY(:,1),XY(:,2),'Color',[0 0 0]);
                case 'bfill'
                    XY=bezierCurve([X(:),Y(:)],80);
                    fill(ax,XY(:,1),XY(:,2),[0 0 0],'FaceAlpha',.2);
            end
        end
    % 数据旋转角度
        function [X,Y]=rotateData(X,Y,theta)
            rotateMat=[cos(theta),-sin(theta);sin(theta),cos(theta)];
            XY=rotateMat*[X;Y];
            X=XY(1,:);Y=XY(2,:);
        end
    % 贝塞尔函数
        function pnts=bezierCurve(pnts,N)
            t=linspace(0,1,N);
            p=size(pnts,1)-1;
            coe1=factorial(p)./factorial(0:p)./factorial(p:-1:0);
            coe2=((t).^((0:p)')).*((1-t).^((p:-1:0)'));
            pnts=(pnts'*(coe1'.*coe2))';
        end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    使用方法

    基本使用:\运行以下代码会随机生成一个贝塞尔曲线插值的随机填充图像。

    randMandalas('bfill')
    
    • 1

    多子图示例:

    M=3;N=3;
    for m=1:M
        for n=1:N
            axes(gcf,'Position',[(n-1)/N,(m-1)/M,1/N,1/M])
            randMandalas('bfill')
        end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    其他方法:
    对于同一组随机数种子,将参数分别变为linefillbezierbfill的效果对比:

    • line

    • fill

    • bezier

    • bfill

    可以看出还是贝塞尔曲线插值后的图像更顺滑好看!

    图像赋色

    原理就是读取图片后,使用colormap函数将灰度映射到颜色:
    原图:(图像导出时尽量选择高分辨率)

    tpic=imread('test.png');
    
    surf(tpic(:,:,1),'EdgeColor','none');
    hold on;axis equal;view(2);
    set(gca,'XTick',[],'YTick',[],'XColor','none','YColor','none','Ydir','reverse')
    
    
    CList=[parula(15);1,1,1];
    % CList=[PYCM().cubehelix(15);1,1,1];
    
    colormap(CList) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其他 colormap

    当然除了parula配色,MATLAB自带的其他配色也可用:

    pink

    bone

    PYCM

    本人自写的PYCM函数也可用,使用方式见代码片中的注释。有关PYCM函数的介绍可点击链接跳转推送:

    https://mp.weixin.qq.com/s/fHpCRQxD39_mBcPpLU0xpA

    cubehelix

    GnBu

    magma

    PuOr

    RdBu

    RdYlBu

    Spectral


  • 相关阅读:
    Java项目:基于JSP的养老院管理系统
    C++ 入门
    Win11如何增强麦克风?Win11增强麦克风的设置
    矩阵分析与应用+张贤达
    461. 汉明距离
    FPGA行业应用二:通用仪器行业
    cocos2d-lua:骨骼动画的使用
    新材料生产工厂MES系统选型指南
    SpringBoot集成Spring Security——【认证流程】
    VScode安装与汉化
  • 原文地址:https://blog.csdn.net/slandarer/article/details/126114475