慢羊羊的空间

无为,无我,无欲,居下,清虚,自然

[分形学] 基于 L 系统绘制 Hilbert (希尔伯特) 曲线

德国数学家 David Hilbert 发现了这样一种可以填满整个单位正方形的分形曲线,称它为 Hilbert 曲线。具体的我就不多做介绍了,相关内容请自己搜索。这里只说程序。

程序执行后,按数字键 1~8 可以显示相应阶数的 Hilbert (希尔伯特) 曲线,按 ESC 退出。

五阶 Hilbert (希尔伯特) 曲线的执行效果如下:

代码如下: 

// 程序名称:Hilbert (希尔伯特)曲线 (基于 L 系统绘制)
// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版
// 最后修改:2011-3-7
//
#include <graphics.h>
#include <conio.h>

int g_len;	// Hilbert 曲线的单位长度

// 递归绘制 Hilbert 曲线
void hilbert(LPCTSTR 
...

吸顶灯上的一个图案,由若干圆弧组成

也不知道这个程序该叫什么名字,是我最早学编程的时候写的。那时候看见什么东西都想用程序画出来,然后偶然间在一个吸顶灯的灯罩上看到了这样的图案,于是就写了一个程序来生成。

执行效果如下:

代码如下:

// 程序名称:圆弧组成的图案
// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版
// 最后修改:2011-3-7
//
#include <graphics.h>
#include <conio.h>
#include <math.h>

#define PI	3.1415926536
#define R	200

// 四舍五入
int Round(double x)
{
	return (int)(x < 0 ? x - 0.5 : x + 0.5);
}

// 主函数
void main()
{
	// 变量定义
	in
...

万花尺(又叫万花规)模拟程序

万花尺相信很多人小时候都玩过吧,将一个满是齿牙的小圆套在一个大圆里面,用笔放进小圆的洞里,然后转圈圈画,就可以画出很多美丽有趣的图案。这个程序就是万花尺的模拟程序。

下面是几组数据和执行效果的抓图:

代码如下:

////////////////////////////////////////////
// 程序名称:万花尺(又名万花规)模拟程序
// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版
// 程序编写:yangw80 <yw80@qq.com>
// 最后更新:2011-2-26
//
#include <graphics.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define PI 3.1415926536

void main()
...

[分形学] 谢宾斯基 (Sierpinski) 三角形,也叫垫片

先说一个程序的实现过程:

  1. 随机生成 3 个点 P[0]、P[1]、P[2];
  2. 随机生成 1 个点 P;
  3. 绘制点 P;
  4. 随机生成 [0, 2] 内的整数 n;
  5. 令 P = P 与 P[n] 的中点;
  6. 重复执行步骤 3~5 三万次。

这个程序很简单,虽然随机性很大,但是结果几乎是完全相似的,会是一个很有趣的图案,也就是传说中的谢宾斯基三角形。以上步骤就是生成谢宾斯基三角形的随机迭代法。

程序代码如下:
(注:为了效果,将步骤(1)的三个点手动指定了。喜欢的话,可以将其修改为随机产生)。

// 程序名称:谢宾斯基(Sierpinski)三角形,也叫垫片
// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版
// 最后更新:2010-11-16
//
#include <graphics.h>

...

用多个圆形组合形成的心形图案

这个程序在很多书上都有写过,以下是运行效果截图:

代码如下:

// 程序名称:圆形组合而成的心形图案
// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版
// 最后更新:2010-10-28
//
#include <graphics.h>
#include <conio.h>
#include <math.h>

#define	PI	3.1415926536

void main()
{
	int x, y, y1, r = 50, r1;

	// 初始化图形模式
	initgraph(640, 480);
	// 设置原点为屏幕中央
	setorigin(320, 240);
	// 设置绘图颜色为红色
	setcolor(RED);

	// 用数学方法,用多个圆形组合形成心形图案
	y1 = 240 - r;
	for(doubl
...

[分形学] 可以无穷放大的 Mandelbrot Set (曼德布洛特集) VC 源代码

基于上篇文章 Mandelbrot Set (曼德布洛特集) 的源代码:
https://www.codebus.cn/yangw/post/mandelbrot-set

我修改了几个地方:

1. 修改了颜色,使用黑->蓝->白->棕->黑这样的渐变颜色方案(当然,可以修改 InitColor() 函数改变配色方案)

2. 增加了放大鼠标选中区域的功能。按鼠标中键可以恢复原尺寸。

3. 将迭代次数提了出来,定义了常量。如果需要绘制更精细的图,请加大常量 ITERATIONS。不过越大绘制的越慢。精细程度开始看不出来,放大次数多了就明显了。

4. 理论上是可以无穷放大,但实际受 double 类型精度的影响,放大到一定程度就会是马赛克了。

先看看逐步放大的效果吧:

另一个位置的逐步放大效果:

...

[分形学] Julia Set (茱莉亚集) VC 源代码

关于 Julia Set (茱莉亚集) 的介绍什么的我就不多说了,网上一大堆。执行效果如图:

关于 Julia Set,可以通过设置复数 c 的初值,显示出不同的图案,比如,大家可以试试以下几组:

c.re = 0.45, c.im = -0.1428;
c.re = 0.285, c.im = 0.01;
c.re = 0.285, c.im = 0;
c.re = -0.8, c.im = 0.156;
c.re = -0.835, c.im = -0.2321;
c.re = -0.70176, c.im = -0.3842;

随便用哪行替换掉源程序中的“c.re = -0.75, c.im = 0;”都可以看到不同的精美图案。循环变量 k 是迭代次数,在某些参数下需要高一些会更精细。

为了美观,还需要修改一下颜色部分,目前代码中的颜

...

[分形学] Mandelbrot Set (曼德布洛特集) VC 源代码

关于 Mandelbrot Set (曼德布洛特集) 的介绍什么的我就不多说了,网上一大堆。执行效果如图:

为了美观,可以修改一下颜色部分,目前代码中的颜色是这样的:

HSLtoRGB((float)((k<<5) % 360), 1.0, 0.5)

这行代码中的 k 的取值范围是 0~180,将其映射到 HSL 颜色空间中的色相上(360 度)。

全部代码如下:

// 程序名称:分形学 - Mandelbrot Set (曼德布洛特集)
// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版
// 最后更新:2010-9-9
//
#include <graphics.h>
#include <conio.h>

/////////////////////////////
...

打字母游戏

某天突然来兴趣了,就写了这么个打字母的小程序,就是以前学习机上那种字母往下掉,然后按相应键字母消失的游戏。

程序不长,尤其很大篇幅都是开始和结束的文字绘制,除去这些没几行代码了,感觉做个范例还是很有用的。

又补了个小特效,加了点注释。。。
一看,整100行,呵呵。

////////////////////////////////////////////
// 程序名称:打字母游戏
// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版
// 程序编写:yangw80 <yw80@qq.com>
// 最后更新:2010-8-26
//
#include <graphics.h>
#include <conio.h>
#include <time.h>

// 欢迎界面
void welcome()
{
	// 输出屏幕提示
	cleardevice();
	setcolo

...

彩虹

该程序是 EasyX 帮助中带的范例程序。

执行效果如下:

完整源代码如下:

// 程序名称:彩虹
// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版
// 最后更新:2010-8-25
//
#include <graphics.h>
#include <conio.h>

void main()
{
	float H, S, L;

	initgraph(640, 480);

	// 画渐变的天空(通过亮度逐渐增加)
	H = 190;	// 色相
	S = 1;		// 饱和度
	L = 0.7f;	// 亮度
	for(int y = 0; y < 480; y++)
	{
		L += 0.0005f;
		setcolor( HSLtoRGB(H, S, L) );
		line(0, y, 639, y);
	}

...