【MATLAB】一个宝藏博主公开的代码,给它加个速——水晶爱心模块

  • 实验结果
  • 一、原版
  • 二、优化一
  • 三、优化二
  • 四、衍生物
  • 其他

by 今天不飞了

注意!源代码来自 MATLAB专家slandarer博客
注意!源代码来自 MATLAB专家slandarer博客
注意!源代码来自 MATLAB专家slandarer博客
→→→七夕节快到了,教你用MATLAB绘制blingbling的大钻石←←←


实验结果

先看效果

提速效果可用自己电脑测试,下面出代码


一、原版

原理和原始代码可以点击上面链接去大佬博客里看。
这里调整缩进并增加过程注释,如下

主要函数

clear; close all; clc
%% {构造爱心}
% [生成爱心采样点]
sep = pi/8;
t = [0:0.2:sep,sep:0.02:pi-sep,pi-sep:0.2:pi+sep,pi+sep:0.02:2*pi-sep,2*pi-sep:0.2:2*pi];
x = 16*sin(t).^3;
y = 13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t);
z = zeros(size(t));
% [绘制爱心轮廓]
plot3(x,y,z,'Color',[186,110,64]./255,'LineWidth',1),hold on
%% {生成水晶}
tic
cnum = 6; % 每个点生长cnum个水晶
for i = 1:length(t)for j = 1:cnum% [随机形态]len = rand(1)*2+2;tempV = rand(1,3)-0.5;tempV = tempV./norm(tempV).*len;tempSpnt = [x(i),y(i),z(i)];tempEpnt = tempV+tempSpnt;% [绘制]drawCrystal(tempSpnt,tempEpnt,pi/6,0.8,0.14)enddisp(i) % 计数,可删掉
end
toc
% [调整视角]
ax=gca;
ax.XLim=[-22,22];
ax.YLim=[-20,20];
ax.ZLim=[-10,10];
grid on
ax.GridLineStyle='--';
ax.LineWidth=1.2;
ax.XColor=[1,1,1].*0.4;
ax.YColor=[1,1,1].*0.4;
ax.ZColor=[1,1,1].*0.4;
ax.DataAspectRatio=[1,1,1];
ax.DataAspectRatioMode='manual';
% -------------------function---------------------
% {绘制水晶}
function drawCrystal(Spnt,Epnt,theta,cl,w)
mainV = Epnt-Spnt;
cutPnt = cl.*(mainV)+Spnt;
cutV = [mainV(3),mainV(3),-mainV(1)-mainV(2)];
cutV = cutV./norm(cutV).*w.*norm(mainV);
cornerPnt = cutPnt+cutV;
cornerPnt = rotateAxis(Spnt,Epnt,cornerPnt,theta);
cornerPntSet(1,:) = cornerPnt';
for ii = 1:3cornerPnt = rotateAxis(Spnt,Epnt,cornerPnt,pi/2);cornerPntSet(ii+1,:) = cornerPnt';
end
for ii = 1:4jj = mod(ii,4)+1;fill33(Spnt,cornerPntSet(ii,:),cornerPntSet(jj,:))fill33(Epnt,cornerPntSet(ii,:),cornerPntSet(jj,:))
end
end
% {填充颜色}
function fill33(p1,p2,p3)
fill3([p1(1),p2(1),p3(1)],[p1(2),p2(2),p3(2)],[p1(3),p2(3),p3(3)],[0 71 177]./255.*1.03,...'FaceAlpha',0.2,'EdgeColor',[0 71 177]./255.*0.9,'EdgeAlpha',0.25,'LineWidth',0.5,...'EdgeLighting','gouraud','SpecularStrength',0.3)
end

子函数,在后续修改中该函数不会有改动,所以单独列出来

% {沿中轴旋转}
function newPnt = rotateAxis(Spnt,Epnt,cornerPnt,theta)
V = Epnt-Spnt;
V = V./norm(V);
u = V(1);
v = V(2);
w = V(3);
a = Spnt(1);
b = Spnt(2);
c = Spnt(3);
cornerPnt = [cornerPnt(:);1];
rotateMat = [u^2+(v^2+w^2)*cos(theta)       ,  u*v*(1-cos(theta))-w*sin(theta),  u*w*(1-cos(theta))+v*sin(theta),  (a*(v^2+w^2)-u*(b*v+c*w))*(1-cos(theta))+(b*w-c*v)*sin(theta);u*v*(1-cos(theta))+w*sin(theta),  v^2+(u^2+w^2)*cos(theta)       ,  v*w*(1-cos(theta))-u*sin(theta),  (b*(u^2+w^2)-v*(a*u+c*w))*(1-cos(theta))+(c*u-a*w)*sin(theta);u*w*(1-cos(theta))-v*sin(theta),  v*w*(1-cos(theta))+u*sin(theta),  w^2+(u^2+v^2)*cos(theta)       ,  (c*(u^2+v^2)-w*(a*u+b*v))*(1-cos(theta))+(a*v-b*u)*sin(theta);0                              ,  0                              ,  0                              ,  1];
newPnt = rotateMat*cornerPnt;
newPnt(4) = [];
end

二、优化一

用patch替换fill3函数,提速。仅修改drawCrystal函数里面的绘制部分。

该方式下,一次绘制整颗水晶(依赖这个特性有了 本文第四节)

clear; close all; clc
%% {构造爱心}
% [生成爱心采样点]
sep = pi/8;
t = [0:0.2:sep,sep:0.02:pi-sep,pi-sep:0.2:pi+sep,pi+sep:0.02:2*pi-sep,2*pi-sep:0.2:2*pi];
x = 16*sin(t).^3;
y = 13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t);
z = zeros(size(t));
% [绘制爱心轮廓]
plot3(x,y,z,'Color',[186,110,64]./255,'LineWidth',1),hold on
%% {生成水晶}
tic
cnum = 6; % 每个点生长cnum个水晶
for i = 1:length(t)for j = 1:cnum% [随机形态]len = rand(1)*2+2;tempV = rand(1,3)-0.5;tempV = tempV./norm(tempV).*len;tempSpnt = [x(i),y(i),z(i)];tempEpnt = tempV+tempSpnt;% [绘制]drawCrystal(tempSpnt,tempEpnt,pi/6,0.8,0.14)enddisp(i) % 计数,可删掉
end
toc
% [调整]
ax = gca;
ax.XLim = [-22,22];
ax.YLim = [-20,20];
ax.ZLim = [-10,10];
grid on
ax.GridLineStyle = '--';
ax.LineWidth = 1.2;
ax.XColor = [1,1,1].*0.4;
ax.YColor = [1,1,1].*0.4;
ax.ZColor = [1,1,1].*0.4;
ax.DataAspectRatio = [1,1,1];
ax.DataAspectRatioMode = 'manual';
% -------------------function---------------------
% {绘制水晶}
function drawCrystal(Spnt,Epnt,theta,cl,w)
mainV = Epnt-Spnt;
cutPnt = cl.*(mainV)+Spnt;
cutV = [mainV(3),mainV(3),-mainV(1)-mainV(2)];
cutV = cutV./norm(cutV).*w.*norm(mainV);
cornerPnt = cutPnt+cutV;
cornerPnt = rotateAxis(Spnt,Epnt,cornerPnt,theta);
cornerPntSet(1,:) = cornerPnt';
for ii = 1:3cornerPnt = rotateAxis(Spnt,Epnt,cornerPnt,pi/2);cornerPntSet(ii+1,:) = cornerPnt';
end
% 修改部分
F = [1,3,4;1,4,5;1,5,6;1,6,3;...2,3,4;2,4,5;2,5,6;2,6,3];
V = [Spnt;Epnt;cornerPntSet];
patch('Faces',F,'Vertices',V,'FaceColor',[1 0 0],...'FaceAlpha',0.2,'EdgeColor',[1 0 0]*0.9,...'EdgeAlpha',0.25,'LineWidth',0.5,'EdgeLighting',...'gouraud','SpecularStrength',0.3)
end

三、优化二

将绘制部分提到主函数执行。

一次性绘制整个图形(整体化,就不方便独立修改)

clear; close all; clc
%% {构造爱心}
% [生成爱心采样点]
sep = pi/8;
t = [0:0.2:sep,sep:0.02:pi-sep,pi-sep:0.2:pi+sep,pi+sep:0.02:2*pi-sep,2*pi-sep:0.2:2*pi];
x = 16*sin(t).^3;
y = 13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t);
z = zeros(size(t));
y = -y-15;
% [绘制爱心轮廓]
plot3(x,y,z,'Color',[186,110,64]./255,'LineWidth',1),hold on
%% {生成水晶}
tic
Flist = [];
Vlist = [];
idx = 0;
cnum = 6; % 每个点生长cnum个水晶
for i = 1:length(t)for j = 1:cnum% [随机形态]len = rand(1)*2+2;tempV = rand(1,3)-0.5;tempV = tempV./norm(tempV).*len;tempSpnt = [x(i),y(i),z(i)];tempEpnt = tempV+tempSpnt;% [绘制][f,v] = drawCrystal(tempSpnt,tempEpnt,pi/6,0.8,0.14);Flist = [Flist;f+idx];idx = idx+size(v,1);Vlist = [Vlist;v];enddisp(i) % 计数,可删掉
end
toc
% [绘制]
% figure
patch('Faces',Flist,'Vertices',Vlist,'FaceColor',[1 0 0],...'FaceAlpha',0.35,'EdgeColor',[1 0 0]*0.9,...'EdgeAlpha',0.20,'LineWidth',0.5,'EdgeLighting',...'gouraud','SpecularStrength',0.3)
% [调整]
ax = gca;
ax.XLim = [-22,22];
ax.YLim = [-20,20];
ax.ZLim = [-10,10];
grid on
hold off
ax.GridLineStyle = '--';
ax.LineWidth = 1.2;
ax.XColor = [1,1,1].*0.4;
ax.YColor = [1,1,1].*0.4;
ax.ZColor = [1,1,1].*0.4;
ax.DataAspectRatio = [1,1,1];
ax.DataAspectRatioMode = 'manual';
light
axis off
% -------------------function---------------------
% {绘制水晶}
function [F,V] = drawCrystal(Spnt,Epnt,theta,cl,w)
mainV = Epnt-Spnt;
cutPnt = cl.*(mainV)+Spnt;
cutV = [mainV(3),mainV(3),-mainV(1)-mainV(2)];
cutV = cutV./norm(cutV).*w.*norm(mainV);
cornerPnt = cutPnt+cutV;
cornerPnt = rotateAxis(Spnt,Epnt,cornerPnt,theta);
cornerPntSet(1,:) = cornerPnt';
for ii = 1:3cornerPnt = rotateAxis(Spnt,Epnt,cornerPnt,pi/2);cornerPntSet(ii+1,:) = cornerPnt';
end
% 修改部分
F = [1,3,4;1,4,5;1,5,6;1,6,3;...2,3,4;2,4,5;2,5,6;2,6,3];
V = [Spnt;Epnt;cornerPntSet];
end

四、衍生物

上接第二节,既然可以单独绘制一颗,那么就可以给每一颗不一样的颜色

clear; close all; clc
%% {构造爱心}
% [生成爱心采样点]
sep = pi/8;
t = [0:0.2:sep,sep:0.02:pi-sep,pi-sep:0.2:pi+sep,pi+sep:0.02:2*pi-sep,2*pi-sep:0.2:2*pi];
x = 16*sin(t).^3;
y = 13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t);
z = zeros(size(t));
% [绘制爱心轮廓]
plot3(x,y,z,'Color',[186,110,64]./255,'LineWidth',1),hold on
%% {生成水晶}
tic
cnum = 6; % 每个点生长cnum个水晶
for i = 1:length(t)for j = 1:cnum% [随机形态]len = rand(1)*2+2;tempV = rand(1,3)-0.5;tempV = tempV./norm(tempV).*len;tempSpnt = [x(i),y(i),z(i)];tempEpnt = tempV+tempSpnt;% [绘制]color = rand(1,3)*0.5+0.5;drawCrystal(tempSpnt,tempEpnt,pi/6,0.8,0.14,color)enddisp(i) % 计数,可删掉
end
toc
% [调整]
ax = gca;
ax.XLim = [-22,22];
ax.YLim = [-20,20];
ax.ZLim = [-10,10];
grid on
ax.GridLineStyle = '--';
ax.LineWidth = 1.2;
ax.XColor = [1,1,1].*0.4;
ax.YColor = [1,1,1].*0.4;
ax.ZColor = [1,1,1].*0.4;
ax.DataAspectRatio = [1,1,1];
ax.DataAspectRatioMode = 'manual';
axis off
% -------------------function---------------------
% {绘制水晶}
function drawCrystal(Spnt,Epnt,theta,cl,w,color)
mainV = Epnt-Spnt;
cutPnt = cl.*(mainV)+Spnt;
cutV = [mainV(3),mainV(3),-mainV(1)-mainV(2)];
cutV = cutV./norm(cutV).*w.*norm(mainV);
cornerPnt = cutPnt+cutV;
cornerPnt = rotateAxis(Spnt,Epnt,cornerPnt,theta);
cornerPntSet(1,:) = cornerPnt';
for ii = 1:3cornerPnt = rotateAxis(Spnt,Epnt,cornerPnt,pi/2);cornerPntSet(ii+1,:) = cornerPnt';
end
% 修改部分
F = [1,3,4;1,4,5;1,5,6;1,6,3;...2,3,4;2,4,5;2,5,6;2,6,3];
V = [Spnt;Epnt;cornerPntSet];
patch('Faces',F,'Vertices',V,'FaceColor',color,...'FaceAlpha',0.52,'EdgeColor',color*0.9,...'EdgeAlpha',0.6,'LineWidth',0.5,'EdgeLighting',...'gouraud','SpecularStrength',0.3)
end

其他

1、基本原理就是在规定的位置,随机生成多个水晶簇。所以根据选定的位置不同,就能绘制出各种有趣的东西。下面抛出一种思路

在网上下载免费的STL文件(3D打印用的),比如下载一个奥特曼的模型。
然后提取里面的顶点信息,然后调用上面的方法,就能得到一个水晶奥特曼

2、哔哩哔哩讲解与测试

【MATLAB】一个宝藏博主公开的代码,给它加个速——水晶爱心模块相关推荐

  1. 不会代码,如何搭建一个个人博客?

    本科的时候不是计算机专业,学的自动化,也不太上进,尽顾着玩游戏了.那会一直觉得那些写博客的人超级牛逼,能够搭建自己个人博客的人更是牛逼哄哄的啊~ 前段时间,研究生课题没那么忙的时候,折腾着搭建了一个自 ...

  2. 像写博客一样写代码,laf导致一个部门被裁

    云开发中的战斗机 Laf,让你像写博客一样写代码 各位云原生搬砖师 and PPT 架构师,你们有没有想过像写文章一样方便地写代码呢? 怎样才能像写文章一样写代码? 理想的需求应该是可以在线编写.调试 ...

  3. 写一个分析双色球历史开奖趋势的代码

    以下是一个分析双色球历史开奖趋势的 Python 代码示例: import pandas as pd import matplotlib.pyplot as plt# 读取历史双色球数据 data = ...

  4. 如何从零搭建一个hexo博客网站01

    title: 如何从零搭建一个hexo博客网站01 #文章標題 categories: "Hexo教程" #文章分類目錄 可以省略 categories: "Hexo教程 ...

  5. 《数字图像处理原理与实践(MATLAB版)》一书之代码Part3

    本文系<数字图像处理原理与实践(MATLAB版)>一书之代码系列的Part3,辑录该书第135至第184页之代码,供有需要读者下载研究使用.代码执行结果请参见原书配图. --------- ...

  6. 一个宝藏开源软件,跨平台终端神器 Tabby

    点击"终码一生",关注,置顶公众号 每日技术干货,第一时间送达! 自从在Win10上使用了Windows Terminal,对Windows下命令行终端一直挺满意的,直到最近发现了 ...

  7. 如何搭建一个独立博客——简明Github Pages与Hexo教程

    (?)[-] http://cnfeat.com/2014/05/10/2014-05-11-how-to-build-a-blog/ 摘要:这是一篇很详尽的独立博客搭建教程,里面介绍了域名注册.DN ...

  8. 在Matlab实现Kmeans算法(每行代码带注释)

    目录 一.前言 二.VQ概述 三.Kmeans算法 K-means 的算法步骤为: 四.Matlab代码实现过程 五. 一点点可选改动(个人看法) 参考链接: 一.前言 本人对机器学习.人工智能算法方 ...

  9. matlab lisp,LISP-12953284-51CTO博客

    Lisp,最初被拼为LISP,一个历史悠久的电脑编程语言家族.最早由约翰·麦卡锡在1958年基于λ演算创造,演化至今,是历史第二悠久的高级语言,仅次于Fortran,也是第一个函数式编程语言. 其名称 ...

最新文章

  1. 多解决些问题,少谈些框架和流程
  2. Py之demjson:Python库之demjson的简介、安装、使用方法详细攻略
  3. 文娱倍受青睐,可是网文为啥不香了?
  4. 纪中B组模拟赛总结(2020.2.09)
  5. 有一种陪伴不在身边,却在心间
  6. python中isort的使用
  7. mysql 事务 innodb 锁表_MySQL性能优化之Innodb事务系统,值得收藏
  8. java的jtextarea_java中怎么在JTextArea中添加图片?
  9. ubuntu下OpenPose的安装、使用、初步介绍
  10. 2021数学建模B题 空气质量二次模型
  11. 春雷视频添加投屏功能解惑
  12. ZN200以太网转串口TTL(1)
  13. 模型转换:pth转onnx
  14. OpenStack入门到实战视频教程全集下载(罗勇老师经典教程系列)
  15. vue中注释里@xxx是什么意思呢???
  16. java+英尺英寸,身高英寸换算(身高换算成英尺英寸)
  17. x的y次方python表达式怎么写_x 的 y 次方(xy) 以下表达式正确的是________
  18. 迁移学习和模型的微调
  19. 一篇文让你秒懂CDN
  20. SQL 7种SQL JOINS的实现

热门文章

  1. 区块链发展前景究竟怎么样?——三分钟看懂区块链的未来
  2. 大数据实际案例系列一
  3. 远程链接linux桌面的软件,远程linux桌面软件
  4. 微信气泡主题设置_微信猫和老鼠主题皮肤怎么设置 华为手机设置气泡主题方法...
  5. 街头立体画的创作过程
  6. MP条件构造器Wrapper
  7. skyeye linux qt,Ubuntu 16.04上安装SkyEye及测试
  8. 条件运算符与条件if的姻缘,打擂台算法和大小写字母转换,if逻辑避坑
  9. 一文讲解电源技术中的安森美深力科NCP1680AAD1R2G CrM PFC控制器IC 详情讲解
  10. 学WORD-替换换行符