玖叶教程网

前端编程开发入门

抢不到冰墩墩?那就自己画一个吧

北京冬奥会期间,吉祥物“冰墩墩”可是火出了圈,多少人排长队都买不到。



为了帮助大家早日实现“一户一墩”,小编连夜加班,为大家梳理了用MATLAB和Python冰墩墩教程及完整代码!既然抢不到冰墩墩,那就自己画一个吧!


话不多说,先看看超可爱的成品图一睹为快!过过眼瘾再说!


接着看一下绘制动图

是不是超可爱!


好了好了!别馋了!

哈喇子擦一擦~

下面我们自己动手画一画!

后面还有动图和完整代码


敲黑板注意听!

手把手教你用MATLAB和Python把冰墩墩带回家

一、MATLAB绘制教程

冰墩墩可以看成是一系列椭圆、圆角矩形及心形拼成的,下面介绍各部分怎么在MATLAB实现:

1. 椭圆

椭圆用的是函数getEllipse生成数据点,再用fill函数绘制而成:

% 椭圆数据计算函数,输入协方差矩阵、中心点、半径生成椭圆数据
function [X,Y]=getEllipse(Mu,Sigma,S,pntNum)
    % (X-Mu)*inv(Sigma)*(X-Mu)=S
    invSig=inv(Sigma);

    [V,D]=eig(invSig);
    aa=sqrt(S/D(1));
    bb=sqrt(S/D(4));

    t=linspace(0,2*pi,pntNum);
    XY=V*[aa*cos(t);bb*sin(t)];
    X=(XY(1,:)+Mu(1))';
    Y=(XY(2,:)+Mu(2))';
end

?

2.圆角矩形

圆角矩形是使用MATLAB自带的圆角矩阵生成函数,详细信息可以去MATHWORKS官网查看:

rectangle('Position',pos,'Curvature',cur)


3. 心形

心形使用心形函数绘制:

函数代码:

t=linspace(-2.9,2.9,1000);
X=16.*(sin(t)).^3;
Y=13.*cos(t)-5.*cos(2.*t)-2.*cos(3.*t)-cos(4.*t);
fill(X,Y,[180,39,45]./255,'EdgeColor',[180,39,45]./255,'LineWidth',2)

下面是完整代码,可直接粘贴运行,拿来吧你!

(代码较长,可直接下划至Python绘制教程)


function bingdundungif
ax=gca;
ax.DataAspectRatio=[1 1 1];
ax.XLim=[-5 5];
ax.YLim=[-5 5];
hold(ax,'on')


% =========================================================================
% 绘制冰糖外壳
[X,Y]=getEllipse([0,0],[1,0;0,1.3],3.17^2,200);
plot(X,Y,'Color',[57,57,57]./255,'LineWidth',1.8)
%
[X,Y]=getEllipse([1.7,2.6],[1.2,0;0,1.8],.65^2,200);
plot(X,Y,'Color',[57,57,57]./255,'LineWidth',1.8)
plot(-X,Y,'Color',[57,57,57]./255,'LineWidth',1.8)
[X,Y]=getEllipse([1.7,2.6],[1.2,0;0,1.8],.6^2,200);
fill(X,Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',1.8)
fill(-X,Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',1.8)
%
[X,Y]=getEllipse([-3.5,-1],[1.1,.3;.3,1.1],.75^2,200);
plot(X,Y,'Color',[57,57,57]./255,'LineWidth',1.8)
[X,Y]=getEllipse([-3.5,-1],[1.1,.3;.3,1.1],.68^2,200);
fill(X,Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',1.8)
[X,Y]=getEllipse([3.5,1],[1.1,.3;.3,1.1],.75^2,200);
plot(X,Y,'Color',[57,57,57]./255,'LineWidth',1.8)
[X,Y]=getEllipse([3.5,1],[1.1,.3;.3,1.1],.68^2,200);
fill(X,Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',1.8)
%
X=[-3.8,-2,-3];
Y=[-.51+.13,1+.13,-1];
plot(X,Y,'Color',[57,57,57]./255,'LineWidth',1.8)
plot(-X,-Y,'Color',[57,57,57]./255,'LineWidth',1.8)
X=[-3.8,-2,-3];
Y=[-.51+.03,1+.03,-1];
fill(X,Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',1.8)
fill(-X,-Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',1.8)
%
[X,Y]=getEllipse([0,-.1],[1,0;0,1.6],.9^2,200);
Y(Y<0)=Y(Y<0).*.2;Y=Y-4.2;X=X-1.2;
plot(X,Y,'Color',[57,57,57]./255,'LineWidth',2)
plot(-X,Y,'Color',[57,57,57]./255,'LineWidth',2)
rectangle('Position',[-2.1 -4.2 1.7 3],'Curvature',0.4,...
    'FaceColor',[1 1 1],'EdgeColor',[57,57,57]./255,'LineWidth',1.8)
rectangle('Position',[2.1-1.7 -4.2 1.7 3],'Curvature',0.4,...
    'FaceColor',[1 1 1],'EdgeColor',[57,57,57]./255,'LineWidth',1.8)
[X,Y]=getEllipse([0,-.1],[1,0;0,1.6],.8^2,200);
Y(Y<0)=Y(Y<0).*.2;Y=Y-4.1;X=X-1.2;
fill(X,Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',1.8)
fill(-X,Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',1.8)
%
[X,Y]=getEllipse([0,0],[1,0;0,1.3],3.1^2,200);
fill(X,Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',1.8)
pause(.5)

% =========================================================================
% 耳朵
[X,Y]=getEllipse([1.7,2.6],[1.2,0;0,1.8],.5^2,200);
fill(X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
fill(-X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
pause(.5)
% 胳膊
[X,Y]=getEllipse([-3.5,-1],[1.1,.3;.3,1.1],.6^2,200);
fill(X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
[X,Y]=getEllipse([3.5,1],[1.1,.3;.3,1.1],.6^2,200);
fill(X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
X=[-3.8,-2,-3];
Y=[-.51,1,-1];
fill(X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255)
fill(-X,-Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255)
pause(.5)
tt=linspace(-2.9,2.9,1000);
X=16.*(sin(tt)).^3;
Y=13.*cos(tt)-5.*cos(2.*tt)-2.*cos(3.*tt)-cos(4.*tt);
X=X.*.018+3.6;
Y=Y.*.018+1.1;
fill(X,Y,[180,39,45]./255,'EdgeColor',[180,39,45]./255,'LineWidth',2)
pause(.5)
% 腿
[X,Y]=getEllipse([0,-.1],[1,0;0,1.6],.7^2,200);
Y(Y<0)=Y(Y<0).*.2;Y=Y-4.1;X=X-1.2;
fill(X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
fill(-X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
rectangle('Position',[-1.95 -4.3 1.4 3],'Curvature',0.4,...
    'FaceColor',[57,57,57]./255,'EdgeColor',[57,57,57]./255)
rectangle('Position',[1.95-1.4 -4.3 1.4 3],'Curvature',0.4,...
    'FaceColor',[57,57,57]./255,'EdgeColor',[57,57,57]./255)
pause(.5)
% 身体
[X,Y]=getEllipse([0,0],[1,0;0,1.3],3^2,200);
fill(X,Y,[1,1,1],'EdgeColor',[57,57,57]./255,'LineWidth',2.5)
pause(.5)
% 五环
cList=[132,199,114;251,184,77;89,120,177;158,48,87;98,205,247];
for i=1:5
    [X,Y]=getEllipse([0,0],[1.6,0;0,1.3],(2.05-0.05.*i)^2,200);
    Y(Y<0)=Y(Y<0).*.8;Y=Y+.5;
    fill(X,Y,[1,1,1],'EdgeColor',cList(i,:)./255,'LineWidth',2.5)
    pause(.5)
end
% 眼睛
[X,Y]=getEllipse([1.2,1.2],[1.2,-.5;-.5,1.1],.65^2,200);
fill(X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
pause(.5)
fill(-X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
pause(.5)
[X,Y]=getEllipse([.95,1.3],[1,0;0,1],.35^2,200);
fill(X,Y,[57,57,57]./255,'EdgeColor',[1,1,1],'LineWidth',1.6)
pause(.5)
fill(-X,Y,[57,57,57]./255,'EdgeColor',[1,1,1],'LineWidth',1.6)
pause(.5)
[X,Y]=getEllipse([.95,1.3],[1,0;0,1],.1^2,200);
fill(X+.18,Y,[1,1,1],'EdgeColor',[57,57,57]./255,'LineWidth',.5)
fill(-X+.18,Y,[1,1,1],'EdgeColor',[57,57,57]./255,'LineWidth',.5)
pause(.5)
% 嘴巴
[X,Y]=getEllipse([0.05,.2],[1.2,.15;.15,.8],.69^2,200);
fill(X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
[X,Y]=getEllipse([0,.75],[1,0.2;0.2,.3],.4^2,200);
fill(X,Y,[1,1,1],'EdgeColor',[1,1,1],'LineWidth',2)
pause(.5)
[X,Y]=getEllipse([0,0],[.8,0;0,.2],.6^2,200);
fill(X,Y,[180,39,45]./255,'EdgeColor',[180,39,45]./255,'LineWidth',2)
pause(.5)
% 鼻子
[X,Y]=getEllipse([0,-.1],[1,0;0,1.6],.2^2,200);
Y(Y<0)=Y(Y<0).*.2;Y=-Y+.9;
fill(X,Y,[57,57,57]./255,'EdgeColor',[57,57,57]./255,'LineWidth',2)
pause(.5)


% =========================================================================
% 冬奥会标志及五环
% 五环
tt=linspace(0,2*pi,100);
X=cos(tt).*.14;
Y=sin(tt).*.14;
plot(X,Y-2.8,'Color',[57,57,57]./255,'LineWidth',1.2)
pause(.5)
plot(X-.3,Y-2.8,'Color',[106,201,245]./255,'LineWidth',1.2)
pause(.5)
plot(X+.3,Y-2.8,'Color',[155,79,87]./255,'LineWidth',1.2)
pause(.5)
plot(X-.15,Y-2.9,'Color',[236,197,107]./255,'LineWidth',1.2)
pause(.5)
plot(X+.15,Y-2.9,'Color',[126,159,101]./255,'LineWidth',1.2)
pause(.5)
% 文本
text(0,-2.4,'BEIJING 2022','HorizontalAlignment','center',...
    'FontSize',8,'FontName','Comic Sans MS')
pause(.5)
% 标志
fill([.1,-.12,-.08],[0,0-0.05,-0.15]-1.5,[98,118,163]./255,'EdgeColor',[98,118,163]./255)
fill([-.08,-.35,.1],[-0.1,-.2,-.1]-1.6,[98,118,163]./255,'EdgeColor',[98,118,163]./255)
fill([-.08,-.08,.1,.1],[-0.1,-0.15,-.2,-.15]-1.5,[192,15,45]./255,'EdgeColor',[192,15,45]./255)
plot([-.35,-.3,-.25,-.2,-.15,-.1,-.05,.1]+.02,...
     [0,.02,.04,.06,.04,.02,0,.02]-1.82,'Color',[120,196,219]./255,'LineWidth',1.8)
plot([-.33,.05]+.02,[0,-.08]-1.82,'Color',[190,215,84]./255,'LineWidth',1.8)
plot([.05,-.2]+.02,[-.08,-.15]-1.82,'Color',[32,162,218]./255,'LineWidth',1.8)
plot([-.2,.05]+.02,[-.15,-.2]-1.82,'Color',[99,118,151]./255,'LineWidth',1.8)


% =========================================================================
    % 椭圆数据计算函数,输入协方差矩阵、中心点、半径生成椭圆数据
    function [X,Y]=getEllipse(Mu,Sigma,S,pntNum)
        % (X-Mu)*inv(Sigma)*(X-Mu)=S
        invSig=inv(Sigma);
        
        [V,D]=eig(invSig);
        aa=sqrt(S/D(1));
        bb=sqrt(S/D(4));
        
        t=linspace(0,2*pi,pntNum);
        XY=V*[aa*cos(t);bb*sin(t)];
        X=(XY(1,:)+Mu(1))';
        Y=(XY(2,:)+Mu(2))';
    end
end
----转自slandarer



二、Python绘制教程

python画冰墩墩有两种方式:画椭圆和“海龟作图”。


1. 海龟作图


“海龟作图”用的是 Python 自带的 turtle 库,说实话没什么技术含量,就是“硬肝”,不断调整曲线完善绘图。

这种方式适合身强体壮、活力旺盛的年轻人,不过为了少脱点发,可以使用 turtle 画图的小技巧:

turtle.bgpic(r'bg.png')

通过以上语句把你要参考的图先绘制在窗口中,然后再对照着进行绘制调整,就方便许多了。

完整代码在Github开源,需要可自取:

https://github.com/crossin/snippet/tree/master/BingDwenDwen

(此处感谢原作者Crossin提供开源代码)


2.画椭圆

画椭圆就是和MATLAB差不多,代码的基本思路其实很简单,就是不停地画椭圆。


这种方式非常养生,对头发也比较友好,为了简化代码,可以先写个画椭圆的函数~

# 画椭圆
def ellipse(el, edgecolor='black', facecolor='w', n=0, alpha=1):

    axs[n].add_patch(el)
    el.set_facecolor(facecolor)
    el.set_alpha(alpha)
    el.set_edgecolor(edgecolor)

在这个函数基础上画冰墩墩,附上完整代码:

# 冰墩墩(??ω??)?
def BingDwenDwen():

    # 冰外壳
    ellipse(Ellipse((0, -0.3), 6+0.3, 6.6+0.3, 0)) # 身体
    ellipse(Ellipse((1.7, 2.4), 1.2+0.3, 1.25+0.3, 0)) # 耳朵
    ellipse(Ellipse((-1.7, 2.4), 1.2+0.3, 1.25+0.3, 0))

    ellipse(Ellipse((-3, -0.9), 2.8+0.3, 1.2+0.3, 30)) # 左手臂
    ellipse(Ellipse((-3.7, -1.3), 1.16+0.3, 1.16+0.3, 0))
    ellipse(Ellipse((-3, -0.9), 2.8+0.2, 1.2+0.2, 30),'w','w')
    ellipse(Ellipse((3, 0.7), 2.8+0.3, 1.2+0.3, 45)) # 右手臂
    ellipse(Ellipse((3.6, 1.2), 1.16+0.3, 1.16+0.3, 0))
    ellipse(Ellipse((3, 0.7), 2.8+0.2, 1.2+0.2, 45),'w','w')

    ellipse(Ellipse((1.2, -3.2), 1.6+0.3, 2.4+0.3, 0)) # 右腿
    ellipse(Ellipse((1.15, -4), 1.4+0.3, 1+0.3, 0))
    ellipse(Ellipse((1.2, -3.2), 1.6+0.2, 2.4+0.2, 0), 'w', 'w')
    ellipse(Ellipse((-1.2, -3.2), 1.6+0.3, 2.4+0.3, 0)) # 左腿
    ellipse(Ellipse((-1.15, -4), 1.4+0.3, 1+0.3, 0))
    ellipse(Ellipse((-1.2, -3.2), 1.6+0.2, 2.4+0.2, 0), 'w', 'w')

    ellipse(Ellipse((0, -0.3), 6+0.2, 6.6+0.2, 0), 'w', 'w') # 身体

    # 耳朵
    ellipse(Ellipse((1.7, 2.4), 1.2, 1.25, 0), 'black','black')
    ellipse(Ellipse((-1.7, 2.4), 1.2, 1.25, 0), 'black','black')

    # 手臂
    ellipse(Ellipse((-3, -0.9), 2.8, 1.2, 30), 'black','black') # 左
    ellipse(Ellipse((-3.7, -1.3), 1.16, 1.16, 0), 'black','black')
    ellipse(Ellipse((3, 0.7), 2.8, 1.2, 45), 'black','black') # 右
    ellipse(Ellipse((3.6, 1.2), 1.16, 1.16, 0), 'black','black')

    # 腿
    ellipse(Ellipse((1.2, -3.2), 1.6, 2.4, 0), 'black','black')
    ellipse(Ellipse((1.15, -4), 1.4, 1, 0), 'black','black')
    ellipse(Ellipse((-1.2, -3.2), 1.6, 2.4, 0), 'black','black')
    ellipse(Ellipse((-1.15, -4), 1.4, 1, 0), 'black','black')

    # 身体
    ellipse(Ellipse((0, -0.3), 6, 6.6, 0), 'black')

    # 脸周围的五环
    for i in range(5):
        width = 0.06
        tt = np.linspace(0, np.pi, 100)
        x1 = (2.45-width*i) * np.cos(tt)
        y1 = (2.4-width*i) * np.sin(tt)
        x2 = (2.45-width*i) * np.cos(tt)
        y2 = -(1.7-width*i) * np.sin(tt)
        axs[0].plot(x1,y1,color=colorList[i],linewidth=1)
        axs[0].plot(x2,y2,color=colorList[i],linewidth=1)

    # 眼睛
    ellipse(Ellipse((1.1, 1), 1, 1.4, 55), 'black','black') # 右眼
    ellipse(Ellipse((0.9, 1), 0.5, 0.5, 0), 'w','black')
    ellipse(Ellipse((1, 1), 0.05, 0.05, 0), 'w')
    ellipse(Ellipse((-1.1, 1), 1, 1.4, -55), 'black','black') # 左眼
    ellipse(Ellipse((-0.9, 1), 0.5, 0.5, 0), 'w','black')
    ellipse(Ellipse((-0.8, 1), 0.05, 0.05, 0), 'w')

    # 嘴
    ellipse(Ellipse((0, -0.1), 1.2, 1, 20), 'black','black')
    ellipse(Ellipse((0, 0.4), 0.8, 0.5, 10), 'w')
    ellipse(Ellipse((0, -0.28), 0.85, 0.6, 10),'black', (180/255,39/255,45/255))

    # 鼻子
    ellipse(Ellipse((0, 0.5), 0.4, 0.2, 0), 'black','black')

    # 五环
    tt = np.linspace(0, 2*np.pi, 100)
    x = 0.2*np.sin(tt)
    y = 0.2*np.cos(tt) - 3.2
    axs[0].plot(x-0.5,y+0.15,color=colorList[0],linewidth=0.65)
    axs[0].plot(x-0.25,y,color=colorList[1],linewidth=0.65)
    axs[0].plot(x,y+0.15,color=colorList[2],linewidth=0.65)
    axs[0].plot(x+0.25,y,color=colorList[3],linewidth=0.65)
    axs[0].plot(x+0.5,y+0.15,color=colorList[4],linewidth=0.65)
    
    # 右手中的心
    tt=np.linspace(-2.9,2.9,1000)
    x=0.3*(np.sin(tt))**3
    y=0.2*(1.3*np.cos(tt)-.5*np.cos(2*tt)-.2*np.cos(3*tt)-.1*np.cos(4*tt))
    axs[0].fill(x+3.6, y+1.2, color=(180/255,39/255,45/255))

    # LOGO(因为不想画了,所以只写了个Beijing2022,大家可以自行补充完整logo)
    axs[0].text(0, -2.75, 'BEIJING 2022', ha='center', fontsize=5) 


代码收好了!

就可以随时动手画啦!

快去画自己的冰墩墩吧!



喜欢的话记得给小编点个赞

你早晚会关注我??

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言