递归
一个函数直接或间接的调用自身的方法称为递归调用。
分形
分析图形具有如下特点:
- 从形状整体上看,物体图形处处不规则。
- 在较小的尺度上具有相似性。
樱花树
可以利用粉色填充圆代表樱花,为了使最终绘制的樱花树错落有致,可以在生成时利用随机值控制生成的过程。
// 樱花树的绘制.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <graphics.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
const double PI = 3.1415926;
const int canvas_width = 1000;
const int canvas_height = 600;
double tree_angle = PI / 6;
double tree_rate = 0.6;
//确定是否选择展示绘图过程
int if_show_animation = 1;
//将指定范围的值映射到另外一个范围中
double map_value(double input,double input_min, double input_max, double output_min, double output_max)
{
double output;
if (fabs(input - input_min) < 0.0000) output = output_min;
else output = (input - input_min) * (output_max - output_min) / (input_max - input_min) + output_min;
return output;
}
//生成随机数
double num_rand(double num_min, double num_max )
{
srand(time(NULL));
int N = 999;//确定生成随机数的精度,三位数决定随机数的精度是三位的
double t = rand() % (N + 1) / (double)(N + 1);
double num_r = map_value(t, 0, 1, num_min, num_max);
return num_r;
}
//枝干的生成和绘制函数
void brunch(double x_start, double y_start, double t_length, double t_angle, double t_thickness, double t_generation)
{
//坐标的计算
double x_end = x_start + t_length * cos(t_angle);
double y_end = y_start + t_length * sin(t_angle);
//枝干的属性设置
setlinestyle(PS_SOLID, t_thickness);
COLORREF t_color = HSVtoRGB(15, 0.75, 0.4 + t_generation * 0.05);
setlinecolor(t_color);
//绘制当前枝干
line(x_start, y_start, x_end, y_end);
//子枝干的绘制
int child_generation = t_generation + 1;//枝干代数
double child_length = tree_rate * t_length;
double left_child_length = child_length * num_rand(0.9, 1.1);
double right_child_length = child_length * num_rand(0.9, 1.1);
double center_child_length = child_length * num_rand(0.8, 1.1);
//利用递归生成子枝干
if (child_length >= 2 && child_generation < 20)
{
double child_thickness= t_thickness*0.8;
if (child_thickness < 2) child_thickness = 2;
if (num_rand(0, 1) < 0.95)
{
brunch(x_end, y_end, left_child_length, t_angle + tree_angle * num_rand(0.4, 0.9), child_thickness, child_generation);
}
if (num_rand(0, 1) < 0.95)
{
brunch(x_end, y_end, right_child_length, t_angle - tree_angle * num_rand(0.4, 0.9), child_thickness, child_generation);
}
if (num_rand(0, 1) < 0.85)
{
brunch(x_end, y_end, center_child_length, t_angle + tree_angle * num_rand(-1, 1), child_thickness, child_generation);
}
}
//绘制樱花
else
{
setlinestyle(PS_SOLID, 1);
COLORREF f_color = RGB(num_rand(0,255),num_rand(0,230), num_rand(0, 250));
setlinecolor(f_color);
setfillcolor(f_color);
if (child_length <= 4)
{
fillcircle(x_end, y_end, 2);
fillcircle(x_end, y_end, 2);
}
else
{
fillcircle(x_end, y_end, child_length / 3);
}
}
if (if_show_animation)
{
FlushBatchDraw();
//Sleep(5);
}
}
void t_initial()
{
srand(time(0));
initgraph(canvas_width, canvas_height);
setbkcolor(0xFFFFFF);
cleardevice();
BeginBatchDraw();
brunch(canvas_width / 2, canvas_height,0.5 * canvas_height * tree_rate, -PI / 2, 15 * tree_rate, 1);
FlushBatchDraw();
}
void t_update()
{
MOUSEMSG m;// 保存鼠标
if (MouseHit())//判断鼠标是否点击
{
m = GetMouseMsg();
if (m.uMsg == WM_MOUSEMOVE)
{
tree_angle = map_value(m.x, 0, canvas_width, PI / 10, PI / 4);
tree_angle = map_value(m.y, 0, canvas_height, 0.8, 0.4);
}
if (m.uMsg == WM_LBUTTONDOWN)//左键画图
{
cleardevice();
brunch(canvas_width / 2, canvas_height, 0.5 * canvas_height * tree_rate, -PI / 2, 15 * tree_rate, 1);
FlushBatchDraw();
}
if (m.uMsg == WM_RBUTTONDOWN)//右键改变是否显示过程
{
if_show_animation = -if_show_animation;
}
}
}
int main()
{
t_initial();
while (1)
{
t_update();
}
return 0;
}
当然也可以设置成自己想要的颜色