main(){rose=new rose();rose.render(); } class rose{render(){for(int i=0;i<this.petal_num;i++){petal=new petal();petal.render();}} } class petal{render(){points=get_points();surf(points);} }
123456789101112131415161718抗锯齿算法:
% 核心原理:用三角形填充锯齿的缝隙,使边缘由锯齿状变为多边形状; % 实现方式:将原本锯齿外应该删掉的点不要删掉,而是修改他们的坐标,将他们平移到锯齿边缘 for(int i=0;i<points.column_num;i++){pocessing_column=points[][i];longer_column=longer(points[][i-1],points[][i+1]);for(int j=pocessing_column.row_num;j<longer_column.row_num;j++){pocessing_column[j]=pocessing_column[row_num];} } 123456789
母线曲线算法:
% 输入一系列点的坐标; % 以这些点为拐点,用分段三角函数连接每两个点;% 如y=sin(x)连接了[-pi/2,-1],[pi/2,1]...这一系列点; % 将每段放缩至y=0-1的范围,然后apply幂函数运算,y=y^a,调整曲线凹凸性,运算完了再放缩回原y范围。 % 备注:由于更换此函数即可改变花瓣形状,且此函数具有一定的通用性,所以做成外置独立函数。 12345
对切割圆柱,母线弯曲的优化:
% 实际代码中自始至终都没有,先调用cylinder()函数生成完整的圆柱,再切割变弯。 % 而是首先生成母线和圆弧,之后直接利用矩阵叉乘生成曲面。 12
随机化算法:
% 将花瓣参数按花瓣序号做一定的处理,使其不完全一样,具有一定的波动,从而使花朵看上去更自然。 % 如花瓣的起始角度,大小,高度,等等。 12
图像描边算法:
% 刚开始画出来的图像效果不好,后来借用绘画中描边的思想,用较边缘颜色稍浅的颜色描一圈,效果更好。 % 该部分代码较为生硬,未优化,且逻辑上属于主过程之外的附属过程。 12
多类型花瓣算法:
% 由于花瓣的参数由花朵类负责生成,所以在花朵类中将函数“花瓣参数(花瓣序号)”改为分段函数,即可实现一朵花中有多种花瓣 % 可用于实现花萼,花蕊,复杂的花朵等等。 12
class Rose{% 属性:Flower_Attribute;% 花朵通用参数,构造时输入Rose_Attribute;% 玫瑰特征参数,预先指定Petals_Attribute;% 花瓣控制参数,构造时计算% 方法: Render(){}% 在画板上画出本玫瑰Get_Petal(){}% 返回第i个花瓣Get_Petal_Attribute(){}% 返回所有花瓣的对应属性 } 12345678910
class Petal{% 属性:Petal_Attribute;% 花瓣参数,构造时输入% 方法: Render(){}% 在画板上画出本花瓣 Get_Matrix(){}% 返回像素点阵的坐标 Get_Color(){}% 返回每个像素点颜色Get_Cylinder(){}% 生成基础花瓣胚TrimFillet(){}% 将花瓣修剪圆角ApplySize(){}% 将花瓣拉伸大小 } 1234567891011
"Draw_Rose.m"文件:
% 清空窗口 clf; clear; clc; % 环境准备 axis equal; hold on; xlabel('x'); ylabel('y'); zlabel('z'); % 参数准备 fineness=1; % 渲染精细度 flower_position=[1,2,3]; % 花托位置 flower_size=1; % 放大倍数 petal_number=8; % 花瓣数量 % 画出玫瑰 rose=Rose(fineness,flower_position,flower_size,petal_number); rose.Render();
123456789101112131415161718"Rose.m"文件:
classdef Rose properties % 花朵控制参数 fineness=1;% 渲染精细度 flower_position=[0,0,0];% 花托位置 flower_size=1;% 放大倍数 petal_number=8;% 花瓣数量 % 花瓣控制参数 petal_size;% [size_x,size_y,size_z;...] petal_pixel;% [pixel_xy,pixel_z;...] petal_theta;% [theta_start,theta_range;...] petal_radius_z;% radius_z[][] petal_fillet;% fillet[][] petal_color;% [red,green,blue,dark;...] petal_line_c;% [red,green,blue;...] end properties(Hidden) petal_ratio=[1,1,1];% 花瓣大小比例 petal_theta_range=270;% 花瓣角度大小 petal_inflexion_point=[% 花瓣竖向曲线拐点 0,0.32,0.6,1; 0,1,0.85,1.15]; petal_inflexion_power=[1/4;1;1];% 花瓣径向凹凸程度(凹nan——0凸) end methods % 构造函数 function this=Rose(fineness,flower_position,flower_size,petal_number) % 参数录入 this.fineness=fineness; this.flower_position=flower_position; this.flower_size=flower_size; this.petal_number=max(0,round(petal_number)); % 参数计算 this.petal_size=this.Get_Petal_Size(); this.petal_pixel=this.Get_Petal_PixelNum(); this.petal_theta=this.Get_Petal_Theta(); this.petal_radius_z=this.Get_Petal_Radius_z(); this.petal_fillet=this.Get_Petal_Fillet(); this.petal_color=this.Get_Petal_Color(); this.petal_line_c=this.Get_Petal_Line_C(); end % 渲染图像 function Render(this) % 渲染花朵 for petal_sequence=1:this.petal_number % 生成并渲染花瓣 petal_rose=this.Get_Petal(petal_sequence); petal_rose.Render(); end % 关闭网格 shading interp; end % 花瓣生成 function petal_rose=Get_Petal(this,petal_sequence) % 数据准备 size=this.petal_size(petal_sequence,:); pixel=this.petal_pixel(petal_sequence,:); theta=this.petal_theta(petal_sequence,:); radius_z=this.petal_radius_z(petal_sequence,:); fillet=this.petal_fillet(petal_sequence,:); color=this.petal_color(petal_sequence,:); line_c=this.petal_line_c(petal_sequence,:); % 花瓣生成 petal_rose=Petal(size,pixel,theta,radius_z,fillet,color,line_c); end % 花瓣大小计算 function petal_size=Get_Petal_Size(this) petal_size=zeros(this.petal_number,3); for petal_sequence=1:this.petal_number(1) size_x=this.petal_ratio(1)*this.flower_size*sin(petal_sequence/this.petal_number(1))/sin(1); size_y=this.petal_ratio(2)*this.flower_size*sin(petal_sequence/this.petal_number(1))/sin(1); A=0.15; size_z=this.flower_size*(1-A+A*(sin((petal_sequence/this.petal_number(1))*pi)+petal_sequence/this.petal_number(1))); % 集成输出 petal_size(petal_sequence,:)=[size_x,size_y,size_z]; end end % 花瓣像素数计算 function petal_pixel=Get_Petal_PixelNum(this) petal_pixel=zeros(this.petal_number,2); for petal_sequence=1:this.petal_number(1) % 数据运算 pixel_xy=16*(this.petal_theta_range/180)*this.fineness; A=0.2; pixel_xy=pixel_xy*(A+(1-A)*petal_sequence/this.petal_number(1))+1; pixel_z=16*this.petal_ratio(3)*this.fineness+1; % 数据规范 pixel_xy=max(3,round(pixel_xy)); pixel_z=max(2,round(pixel_z)); % 集成输出 petal_pixel(petal_sequence,:)=[pixel_xy,pixel_z]; end end % 花瓣角度计算 function petal_theta=Get_Petal_Theta(this) petal_theta=zeros(this.petal_number,2); theta_start_random=32; theta_range_random=32; for petal_sequence=1:this.petal_number(1) theta_start=150*petal_sequence+unifrnd(-theta_start_random,theta_start_random); theta_start=rem(theta_start,360); theta_range=this.petal_theta_range+unifrnd(-theta_range_random,theta_range_random); % 集成输出 petal_theta(petal_sequence,:)=[theta_start,theta_range]; end end % 花瓣半径计算 function petal_radius_z=Get_Petal_Radius_z(this) pixel_z=max(this.petal_pixel(:,2)); petal_radius_z=zeros(this.petal_number,pixel_z); points=this.petal_inflexion_point; num=size(points,2); start=points(1,1); ends=points(1,num); points(:,1)=2.*points(:,1)-points(:,2); points(:,num)=2.*points(:,num)-points(:,num-1); for petal_sequence=1:this.petal_number(1) pixel_z=this.petal_pixel(petal_sequence,2); r_z=Curve_cos_power(points,this.petal_inflexion_power,start,ends,pixel_z); % 集成输出 petal_radius_z(petal_sequence,1:pixel_z)=r_z; end end % 花瓣圆角计算 function petal_fillet=Get_Petal_Fillet(this) pixel_xy=max(this.petal_pixel(:,1)); petal_fillet=zeros(this.petal_number,pixel_xy); for petal_sequence=1:this.petal_number(1) pixel_xy=this.petal_pixel(petal_sequence,1); xy=linspace(-1,1,pixel_xy+2); fillet_=1-xy.^4; fillet_=fillet_(2:pixel_xy+1); % 集成输出 petal_fillet(petal_sequence,1:pixel_xy)=fillet_; end end % 花瓣颜色计算 function petal_color=Get_Petal_Color(this) petal_color=zeros(this.petal_number,4); % color_=[0.35,0,0.5,0.36]; color_=[0.64,0,0,0.36]; for petal_sequence=1:this.petal_number(1) petal_color(petal_sequence,:)=color_; end end % 花瓣边色计算 function petal_line_color=Get_Petal_Line_C(this) petal_line_color=zeros(this.petal_number,3); % color_=[245,215,0]./255; color_=[0.64,0,0]; for petal_sequence=1:this.petal_number(1) % 集成输出 petal_line_color(petal_sequence,:)=color_; end end end end
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169"Petal.m"文件:
classdef Petal properties size;% 花瓣大小[size_x,size_y,size_z] pixel;% 像素点数[pixel_xy,pixel_z] theta;% 角度起止[theta_start,theta_end] radius_z;% 母线函数radius_z[] fillet;% 圆角函数fillet[] color;% 花瓣颜色[color_x,color_y,color_z] line_c;% 描边颜色[linec_x,linec_y,linec_z] end methods % 构造函数 function this=Petal(size,pixel,theta,radius_z,fillet,color,line_c) this.size=size; this.pixel=pixel; this.theta=theta; this.radius_z=radius_z; this.fillet=fillet; this.color=color; this.line_c=line_c; end % 渲染图像 function Render(this) [x,y,z]=this.Get_Matrix(); c=this.Get_Color(z); surf(x,y,z,c); % 勾勒边缘 m=this.pixel(2); n=this.pixel(1); lx=ones(1,n); ly=ones(1,n); lz=ones(1,n); for j=1:n i=2; while i<=m&&~isnan(z(i,j)) i=i+1; end lx(j)=x(i-1,j); ly(j)=y(i-1,j); lz(j)=z(i-1,j); end plot3(lx,ly,lz,'Color',this.line_c); % 描侧边 % 备注:可优化。 plot3(x(:,1),y(:,1),z(:,1),'Color',this.line_c); plot3(x(:,n),y(:,n),z(:,n),'Color',this.line_c); end % 矩阵生成 function [x,y,z]=Get_Matrix(this) % 获取基本矩阵 [x,y,z]=this.Get_Cylinder(); % 剪裁圆角 [x,y,z]=this.TrimFillet(x,y,z); % 调节比例 [x,y,z]=this.ApplySize(x,y,z); end % 颜色生成 function c=Get_Color(this,z) m=this.pixel(1); n=this.pixel(2); % 颜色矩阵 color_0=ones(size(z,1),size(z,2)); % 渐变优化 for j=1:m % 边缘渐变 hard_xy=0.35; hard_xy=hard_xy*this.color(4)*(((j-0.5*(1+m))^2)/((1-0.5*(1+m))^2)); dark_hard=this.color(4)-hard_xy; for i=1:n % 上下渐变 color_=z(i,j)/(this.fillet(j)*this.size(3)); % 暗度调整 color_=dark_hard*color_; % 输出颜色 color_0(i,j)=1-color_; end end % RGB上色 c(:,:,1)=this.color(1)*color_0; c(:,:,2)=this.color(2)*color_0; c(:,:,3)=this.color(3)*color_0; end % 基本柱面生成 function [x,y,z]=Get_Cylinder(this) % 曲柱面生成 r=this.radius_z(1:this.pixel(2)); theta=linspace(this.theta(1),this.theta(2),this.pixel(1)); x=r'*cos(theta); y=r'*sin(theta); z=(0:length(r)-1)'/(length(r)-1)*ones(1,this.pixel(1)); end % 剪裁圆角 function [x,y,z]=TrimFillet(this,x,y,z) m=this.pixel(2); n=this.pixel(1); % 精准点校准 lambd=0; edge_z=0; for j=1:n edge_z=this.fillet(j); for k=1:m if (z(k,j)==edge_z) break; elseif (z(k,j)>edge_z) lambd=(edge_z-z(k-1,j))/(z(k,j)-z(k-1,j)); x(k,j)=x(k-1,j)+lambd*(x(k,j)-x(k-1,j)); y(k,j)=y(k-1,j)+lambd*(y(k,j)-y(k-1,j)); z(k,j)=edge_z; break; end end end % 逐列镂空 for j=1:n edge_z=this.fillet(j); for k=1:m if (z(k,j)>edge_z) x(k,j)=nan; y(k,j)=nan; z(k,j)=nan; end end end % 三角填充 % 从左侧向中心 left_begin=1; left_end=floor(n/2); for j=left_begin:1:left_end for k=1:m if (isnan(z(k,j))&&~isnan(z(k,j+1))) x(k,j)=x(k-1,j); y(k,j)=y(k-1,j); z(k,j)=z(k-1,j); end end end % 从右侧向中心 right_begin=n; right_end=left_end+1; for j=right_begin:-1:right_end for k=1:m if (isnan(z(k,j))&&~isnan(z(k,j-1))) x(k,j)=x(k-1,j); y(k,j)=y(k-1,j); z(k,j)=z(k-1,j); end end end end % 调整大小 function [x,y,z]=ApplySize(this,x,y,z) x=0.5*this.size(1)*x; y=0.5*this.size(2)*y; z=this.size(3)*z; end end end
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157"Curve_cos_power.m"文件:
function line_y=Curve_cos_power(point,power,x_begin,x_end,pixel_num) % 曲线生成函数 % 算法: % 1.以三角函数连接所有点 % 2.以幂函数分段调整曲线 % IO: % 1.输入多个坐标点 % 2.输出曲线列向量 % 3.输入参数的格式说明: % point=[% 极值点 % x1,x2,...; % y1,y2,...] % power=[% 凹凸性 % power12; % power23;...] % 曲线定义域= % linspace(x_start,x_end,pixel_num) % 4.输出参数的格式说明: % 曲线值域: % line_y=zeros(1,pixel_num); % 数据准备 line_x=linspace(x_begin,x_end,pixel_num); line_y=zeros(1,pixel_num); point_num=size(point,2); point_x=point(1,:); point_y=point(2,:); % 针对逐点处理的时间优化 flag_start=1; % 从左到右逐单调区间处理 for i=1:point_num-1 % 计算三角函数参数 omega=pi/(point_x(i+1)-point_x(i)); phi=point_x(i)*pi/(point_x(i)-point_x(i+1)); A=0.5*(point_y(i)-point_y(i+1)); y0=point_y(i)-A; % 从左到右逐点处理 for j=flag_start:pixel_num % 如果点在定义域内 if point_x(i)<=line_x(j) && line_x(j)<=point_x(i+1) % apply_cos if mod(omega*line_x(j)+phi,pi)==pi/2 % 零点精确值 line_y(j)=y0; else line_y(j)=A*cos(omega*line_x(j)+phi)+y0; end end % 定义域外侧点舍弃 if point_x(i+1)<=line_x(j) % 计算0-1放缩参数 % y=(x-b)/a a=line_y(j-1)-line_y(flag_start); b=line_y(flag_start); for k=flag_start:j-1 % apply_power line_y(k)=(line_y(k)-b)/a;% 放缩to0-1 % 分正负处理 if line_y(k)>=0 line_y(k)=line_y(k)^power(i); else % 避免虚数 line_y(k)=-(-line_y(k))^power(i); end line_y(k)=a*line_y(k)+b;% 放缩from0-1 end flag_start=j; break; end end end end
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869702020-07-22:修复了“Curve_cos_power”函数的已知bug,包括0-1放缩以及边界判定。
相关知识
基于颜色特征的农作物病虫害检测(MATLAB程序+word报告)
树叶图像特征分类识别MATLAB程序
matlab玫瑰花球
matlab 玫瑰花
【优化求解】基于matlab遗传算法求解红绿灯管理优化问题【含Matlab源码262期】.md资源
改进的花朵授粉算法程序(Matlab)资源
情人节玫瑰资源
matlab输出一朵玫瑰花
520还在画玫瑰?教你用MATLAB画个玫瑰花球
使用Matlab对HDF5卫星图像数据进行可视化及地表温度分析
网址: Matlab程序——3d玫瑰 https://m.huajiangbk.com/newsview594775.html
上一篇: 用 R 中 echarts4r |
下一篇: 普洱生茶可以和玫瑰花一起泡吗,普 |