C语言樱花树代码来喽~
大家之前都只看过Python的樱花树吧,今天咋们来搞个C语言的樱花树
运行效果:花束会慢慢长开
实现原理:
鼠标位置设定樱花树的高度和分散程度,鼠标右键点击设置是否显示过程动画,鼠标左键点击开始绘制。
首先学习递归的概念,实现汉诺塔问题的求解;然后学习分形的概念,并利用递归调用绘制一棵分形树;最后修改分形树的生成与绘制参数,实现了随机樱花树的绘制。
程序源码:
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define PI 3.1415926
#define WIDTH 800 // 画面宽度
#define HEIGHT 600 // 画面高度度float offsetAngle = PI/6; // 左右枝干和父枝干偏离的角度
float shortenRate = 0.65; // 子枝干比父枝干变短的倍数
int isShowAnimation = 1; // 是否显示树生成的过程动画// 把[inputMin,inputMax]范围的input变量,映射为[outputMin,outputMax]范围的output变量
float mapValue(float input,float inputMin,float inputMax,float outputMin,float outputMax)
{float output;if (abs(input-inputMin)<0.000001) // 防止除以零的bugoutput = outputMin;elseoutput = (input-inputMin)*(outputMax-outputMin)/(inputMax-inputMin) + outputMin;return output;
}// 生成[min,max]之间的随机小数
float randBetween(float min,float max)
{float t = rand()/double(RAND_MAX); // 生成[0,1]的随机小数// 调用mapValue函数,把值范围从[0,1]映射到[min,max]float r = mapValue(t,0,1,min,max);return r;
}// 枝干生成和绘制递归函数
// 输入参数:枝干起始x y坐标,枝干长度,枝干角度,枝干绘图线条宽度,第几代
void brunch(float x_start,float y_start,float length,float angle,float thickness,int generation)
{// 利用三角函数求出当前枝干的终点x,y坐标float x_end,y_end; x_end = x_start+ length* cos(angle);y_end = y_start+ length* sin(angle);// 画线条枝干setlinestyle(PS_SOLID,thickness); // 设定当前枝干线宽// 设置枝干为灰褐色,主树干最黑,子枝干逐渐变亮COLORREF color = HSVtoRGB(15,0.75,0.4+generation*0.05); setlinecolor(color); // 设定当前枝干颜色line(x_start,y_start,x_end,y_end); // 画出当前枝干(画线)// 求出子枝干的代数int childGeneration = generation + 1; // 生成左、右、中间三个子枝干的长度,逐渐变短,并有一定随机性float childLength = shortenRate*length;float leftChildLength = childLength*randBetween(0.9,1.1);float rightChildLength = childLength*randBetween(0.9,1.1);float centerChildLength = childLength*randBetween(0.8,1.1);// 当子枝干长度大于2,并且代数小于等于10,递归调用产生子枝干if (childLength>=2 && childGeneration<=9) { // 生成子枝干的粗细,逐渐变细float childThickness = thickness*0.8;if (childThickness<2) // 枝干绘图最细的线宽为2childThickness = 2;// 一定概率产生左、右、中子枝干if(randBetween(0,1)<0.95)brunch(x_end,y_end,leftChildLength,angle+offsetAngle*randBetween(0.5,1),childThickness,childGeneration);if(randBetween(0,1)<0.95)brunch(x_end,y_end,rightChildLength,angle-offsetAngle*randBetween(0.5,1),childThickness,childGeneration);if(randBetween(0,1)<0.85)brunch(x_end,y_end,centerChildLength,angle+offsetAngle/5*randBetween(-1,1),childThickness,childGeneration);}else // 最末端绘制樱花,画一个粉色填充圆{setlinestyle(PS_SOLID,1); // 线宽// 樱花粉色HSVtoRGB(325,0.3,1),有一定随机性COLORREF color = HSVtoRGB(randBetween(300,350),randBetween(0.2,0.3),1);setlinecolor(color); // 设定线条颜色setfillcolor(color); // 设定填充颜色if (childLength<=4) // 如果子枝干长度小于等于4fillcircle(x_end,y_end,2); // 圆的半径为2(再小就看不清了)elsefillcircle(x_end,y_end,childLength/2); // 画一个圆,半径为子枝干长度的一半}if (isShowAnimation) // 如果为1,绘制樱花树生成的过程动画{FlushBatchDraw(); // 批量绘制Sleep(1); // 暂停}
}void startup() // 初始化
{srand(time(0)); // 随机初始化initgraph(WIDTH,HEIGHT); // 新开一个画面setbkcolor(RGB(255,255,255)); // 白色背景cleardevice(); // 清屏BeginBatchDraw(); // 开始批量绘制brunch(WIDTH/2,HEIGHT,0.45*HEIGHT*shortenRate,-PI/2,15*shortenRate,1); // 递归函数调用FlushBatchDraw(); // 批量绘制
}void update() // 每帧更新
{MOUSEMSG m; if (MouseHit()) {m = GetMouseMsg(); if(m.uMsg == WM_MOUSEMOVE) // 当鼠标移动时,设定递归函数的参数{// 鼠标从左到右,左右子枝干偏离父枝干的角度逐渐变大offsetAngle = mapValue(m.x,0,WIDTH,PI/10,PI/4); // 鼠标从上到下,子枝干比父枝干的长度缩短的更快shortenRate = mapValue(m.y,0,HEIGHT,0.7,0.3); }if (m.uMsg == WM_LBUTTONDOWN) // 当鼠标左键点击时,以当前参数开始绘制一棵新数{cleardevice(); // 清屏brunch(WIDTH/2,HEIGHT,0.45*HEIGHT*shortenRate,-PI/2,15*shortenRate,1); // 递归调用FlushBatchDraw(); // 批量绘制}if (m.uMsg == WM_RBUTTONDOWN) // 当鼠标右键点击时,切换是否显示过程动画{if (isShowAnimation==1)isShowAnimation = 0;else if (isShowAnimation==0)isShowAnimation = 1;}}
}int main() // 主函数
{startup(); // 初始化 while (1) // 重复循环update(); // 每帧更新return 0;
}
这个漂亮的樱花树主要运用到了函数递归调用的语法知识,和分形的概念,大家可以参考这个的思路,尝试绘制其他分形图案~
END
自学编程的小伙伴们不容易,在学习编程的路上会遇到很多瓶颈,甚至会感到迷茫,为此我给大家整理了一些资源福利,都放在下方啦,还可以和群里的小伙伴们一起来学习交流嗷~
C/C++编程学习基地https://jq.qq.com/?_wv=1027&k=LA8H7KK1
C语言樱花树代码来喽~相关推荐
- R语言统计代码运行耗时实战:计算代码运行时间、使用proc.time函数计算代码运行时间
R语言统计代码运行耗时实战:计算代码运行时间.使用proc.time函数计算代码运行时间 目录
- c语言分手代码大全,C语言代码大全
从今天开始,我将C语言的代码实例从发表在博客上.供技术交流.比较基础,遵循循序渐进的原则,由简单到复杂,为以后的程序员生涯打好基础. 1.编写一个C程序输出以下信息. **************** ...
- aes算法的C语言实现代码,AES加密算法c语言实现代码
AES加密算法c语言实现代码 #include "stdio.h" #include "memory.h" #include "time.h" ...
- WPF第一章(XAML前台标记语言(Chapter02代码讲解))
XAML前台标记语言(Chapter2代码讲解) 很不好意思,工作有点忙,博客停了两天.相对于一门语言的学习,理论知识和实践必不可少,大多数时间我们要用,对于代码也是,一边不行可以看两遍,实在 ...
- python画代码-python画樱花树代码 具体代码介绍
1.python画樱花树代码为: import turtle as T import random import time 2.# 画樱花的躯干(60,t) def Tree(branch, t): ...
- C语言初学者代码中的常见错误与瑕疵(9)
题目 字母的个数 现在给你一个由小写字母组成字符串,要你找出字符串中出现次数最多的字母,如果出现次数最多字母有多个那么输出最小的那个. 输入:第一行输入一个正整数T(0<T<25) 随后T ...
- 嵌入式编程C语言提高代码效率的14种方法
嵌入式编程C语言提高代码效率的14种方法 1.在可能的情况下使用typedef替代define.当然有时候你无法避免define,但是typedef更好. typedef int* INT_PTR; ...
- C语言工程代码查看神器 SourceInsight
C语言工程代码查看神器 SourceInsight 安装 默认安装即可 链接:https://pan.baidu.com/s/14CD9RK3yXJ7e43Lf3hxe4A 提取码:12lw 安装完毕 ...
- 一些可运行的C语言数据结构代码
网上有很多C语言数据结构代码:有的不能运行:下面是一些能运行的,和运行截图:备用一下: 1 队列 #include<stdio.h> #include<stdlib.h>#de ...
最新文章
- java 1099_【LeetCode(Java) - 1099】小于 K 的两数之和
- 检索所有课程都选修的的学生的学号与姓名
- formal method lecture 2: propositional logic
- 操作系统(五)中断和异常
- 2.Idea分支的merge
- mac 下使用wireshark监听网络上的数据
- HALCON学习之旅(六)
- odoo10参考系列--视图二(表单视图)
- TFS数据服务器启动优化
- update.php,update php version to 5.6
- 新型恶意软件—— Grizzly攻击Telegram
- mac mysql read only_mac Read-Only filesystem
- 面试准备——mybatis相关
- tomcat乱码的几种解决
- 联想计算机打开盖子自动开机,联想笔记本开盖自动开机怎么关闭
- Problem D. Euler Function HDU - 6322(欧拉数,找规律)
- 15、react 的 非受控组件 和 受控组件
- Midjourney:一步一步教你如何使用 AI 绘画 MJ
- 2023秋招--梦加网络--游戏客户端--一面面经
- 左移赋值运算符 (<<=)
热门文章
- 小米13 Pro天玑版电池容量 续航怎么样小米13 Pro天玑版 性能怎么样
- c语言stand(time(0)),C语言复习0_准备工作
- 新版谷歌浏览器下载(http链接)没反应
- 刷机命令-直接命令上
- 从开发者角度解析 Android N 新特性!
- C# 远程开机,关闭简单案例
- Unity中的音效管理
- Navi title偏移问题 一般发生在模拟器
- 20 kubeadm高可用部署1.23以上k8s版本
- HTML5期末大作业:商城网站设计——防锤子手机商城官网首页模板(HTML+CSS+JavaScript ) 电商网页HTML代码