科赫雪花c语言程序设计,用 C 语言画科赫雪花

article/2025/9/13 14:04:11

作者:Milo Yip

链接:https://zhuanlan.zhihu.com/p/24688522

1. 科赫雪花和科赫曲线

科赫曲线(Koch curve)是一个简单的分形(fractal)图形。瑞典数学家海里格·冯·科赫(Helge von Koch:https://en.wikipedia.org/wiki/Helge_von_Koch)于 1904 年的论文 [1] 中提及科赫曲线的构造方法。

给定一直线线段,把它等分三段,加入一个等边三角形,以三段的中间一段为底对齐,再去除该段线段。然后,对每个新线段重复进行上述步骤,就能形成科赫曲线:

dec268b5eed935126a049da8f02e4b95.png

fc1de9013c7df8207c84a0850a4eb1e3.png

,科赫曲线的长度也是无穷的。

如果画 3 条科赫曲线,每次旋转 120 度,就能得到科赫雪花(Koch snowflake:https://en.wikipedia.org/wiki/Koch_snowflake):

8751cca7b3e8a0ab9e12bf93c976cba8.png

2. 用 ASCII 字符绘画

我们可以用斜线 /、反斜线 \、下划线 _ 和空格这 4 个 ASCII 字符来绘画这个图形:

n=0

__

n=1

__/\__

n=2

__/\__

\    /

__/\__/    \__/\__

但有些情况我们需要在一个字符中画下划线和斜线,例如 n = 3 的时候:

n=3

__/\__

\    /

__/\__/    \__/\__

\                /

这里 -> /_              _\

这时候我们可以选择只画斜线、反斜线。

3. 用 C 语言实现科赫曲线

我们创建一个字符数组 image 作为画布,用于存储绘画的中间结果,最后再把数组打印出来。数组的大小为画布宽长之积 w * h。

设坐标系统是 x 向右、y 向下,并定义字符的左下角为坐标。例如,画笔从 (x, y) 之处往右画,便赋值 image[y * w + x] = '_' ,并把 x 增 1。

我们也定义 6 个方向,0 代表向右,1代表右上,2 代表左上等。注意水平方向(0 和 3)需要画两个下划线,其他方向只画一个字符。

每次调用 KochCurve(n, dir) 函数,表示我们要从当前位置 (x, y) 向 dir 方向绘画一条 n 阶科赫曲线。那么要画一条 n 阶科赫曲线,其实就只需要根据所需方向画 4 条 n - 1 阶科赫曲线。直到 n = 0,一条 0 阶科赫曲线就是一条直线,我们届时只需按 dir 用字符画一条直线。

完整代码如下:

#include #include static char* image;static int x, y, w, h;static void Put(int i, int j, char c) {

char *p = image + j * w + i;

if (*p == ' ' || *p == '_') // _ can be overridden by / or \.

*p = c;}static void KochCurve(int n, int dir) {

if (n == 0)

switch (dir % 6) {

case 0: Put(x++, y  , '_' );

Put(x++, y,   '_' ); break;

case 1: Put(x++, y--, '/' ); break;

case 2: Put(--x, y--, '\\'); break;

case 3: Put(--x,   y, '_' );

Put(--x,   y, '_' ); break;

case 4: Put(--x, ++y, '/' ); break;

case 5: Put(x++, ++y, '\\'); break;

}

else {

KochCurve(n - 1, dir    );

KochCurve(n - 1, dir + 1);

KochCurve(n - 1, dir + 5);

KochCurve(n - 1, dir    );

}}int main() {

w = 2;

h = 1;

for (int n = 0; n < 4; n++) {

char b[w * h];

image = b;

memset(image, ' ', w * h);

x = 0;

y = h - 1;

KochCurve(n, 0);

printf("\nn=%d\n\n", n);

for (int j = 0; j < h; j++) {

for (int i = 0; i < w; i++)

putchar(image[j * w + i]);

putchar('\n');

}

w *= 3;

h = n == 0 ? 1 : h * 3;

}}

main() 中使用了 C99 的 VLA 分配 image 数组,如用 C89 可改为 malloc()/free()。

4. 实现科赫雪花

科赫雪花仅仅是由 3 科赫曲线组成。我们只需改一下 main(),把画布变大一点,以及在合适的起始坐标画 3 条科赫曲线:

int main() {

w = 2;

h = 4;

for (int n = 0; n < 4; n++) {

char b[w * h];

image = b;

memset(image, ' ', w * h);

x = 0;

y = h / 4 - 1;

KochCurve(n, 0);

KochCurve(n, 4);

KochCurve(n, 2);

printf("\nn=%d\n\n", n);

for (int j = 0; j < h; j++) {

for (int i = 0; i < w; i++)

putchar(image[j * w + i]);

putchar('\n');

}

w *= 3;

h = n == 0 ? 4 : h * 3;

}}

输出(只展示 n = 3):

31f23c2cf6c89a80003b4b7a6653b5c0.png

5. 总结与扩展

分形图形可以用极简单的定义,生成复杂的图形。在本文中,展示如何用 C 语言中,利用递归和 ASCII 字符绘画出科赫曲线和科赫雪花。

你还可以简单地改变 KochCurve() 中的实现,产生不同的变种,如The Root 9 Triangle Grid Family展示的:

99d5935780d948a4b2cd36e08f343887.png

你还可以尝试一下,不使用画布,而是用《如何用 C 语言画这个图:https://zhuanlan.zhihu.com/p/23692828》的框架来绘画,但这样需要在每个字符格子绘画整条曲线,性能较差。要提升性能,可使用每阶科赫曲线的包围盒( bounding box)作剔除──如果现时的坐标不在包围盒之内,也毋须递归到低一阶的科赫曲线了。

参考

[1] Von Koch, Helge. "Sur une courbe continue sans tangente, obtenue par une construction géométrique élémentaire."Arkiv för Matematik1 (1904): 681-704.

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。

-END-


http://chatgpt.dhexx.cn/article/LI1GaLle.shtml

相关文章

科赫雪花绘制

绘制单边科赫雪花 效果图 代码 from turtle import * def koch(size,n): if n0: fd(size) else: for angle in [0,60,-120,60]: left(angle) koch (size/3,n-1) def main(): setup(800,400) penup() goto(-300,…

python的科赫雪花

科赫曲线是一种像雪花的几何曲线&#xff0c;所以又称为雪花曲线&#xff0c;它是de Rham曲线的特例。科赫曲线是出现在海里格冯科赫的论文中&#xff0c;是分形曲线中的一种。其形态似雪花&#xff0c;又称科赫雪花、雪花曲线。 #科赫雪花#递归函数 import turtle def koch(si…

python绘制科赫雪花and科赫雪花进阶版

首先我们来绘制一个基本的3阶科赫雪花&#xff0c;由于和课上用的软件不一样&#xff0c;所以在课上看的代码只能当参考&#xff0c;实际比较繁琐。 代码如下 import turtle # 引入决解问题需要的工具——turtle作图包# 定义turtle画笔和画布的参数…

科赫雪花

科赫曲线 一个过程进行不断地迭代 使用递归和海龟 科赫曲线的绘制&#xff08;做一条直线&#xff0c;将中间的一段去掉&#xff0c;然后做一个凸起&#xff0c;形成科赫曲线&#xff09; 递归思想&#xff1a;函数分支 递归链条:线段的组合 递归基例&#xff1a;初识线段 im…

Python实例8:科赫雪花小包裹(函数递归)

科赫曲线&#xff0c;也叫雪花曲线。绘制科赫曲线。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬…

科赫雪花小包裹实例详解

高大上的分形几何 分形几何是一种迭代的几何图形&#xff0c;广泛存在于自然界中&#xff08;树叶&#xff0c;菜花&#xff09;&#xff08;这个东西的整体与他的局部具有很相似的特点&#xff09; 分形几何中有一种特殊的曲线叫做科赫曲线&#xff0c;也叫雪花曲线 科赫曲…

分形之科赫(Koch)雪花

科赫曲线是一种分形。其形态似雪花&#xff0c;又称科赫雪花、雪花曲线.瑞典人科赫于1904年提出了著名的“雪花”曲线&#xff0c;这种曲线的作法是&#xff0c;从一个正三角形开始&#xff0c;把每条边分成三等份&#xff0c;然后以各边的中间长度为底边。分别向外作正三角形&…

用Python画科赫雪花

文章目录 科赫曲线飘雪三维飘雪 科赫曲线 科赫曲线因为十分像雪花&#xff0c;所以被成为雪花曲线&#xff0c;生成方式十分简单&#xff0c;总共分两步 画一个正三角形将正三角形的每个边三等分&#xff0c;然后以中间的那份为边&#xff0c;再画出个三角形。重复第二步。 …

关于科赫曲线和科赫雪花的讲解

这是我的第2篇文章。在讲新内容之前&#xff0c;我先要把以前递归函数没讲完的继续讲解&#xff1a; &#xff08;recursion&#xff09;就是在运行的时候调用自己&#xff0c;构成递归需具备的两个条件&#xff1a;一个就是调用自己&#xff0c;一个是有终止的条件。这两个条…

sql中的函数取余数

整数中取余数 前言取余数向上取整算法&#xff08;此非彼&#xff09;函数 sql语句 前言 向上取整&#xff0c;向下取整&#xff0c;或者换句话说 &#xff1a;有余数就1 &#xff0c;没有就直接输出整数。 举个例子&#xff1a; 就比如一页10个&#xff0c;我21个数据&#x…

取模和求余运算

文章目录 背景探究总结 被除数 dividend 用 a 表示&#xff1b; 除数 divisor 用 b 表示&#xff1b; 商 quotient 用 q 表示&#xff1b; 余 remainder 用 rem 表示&#xff1b; 模 modulo 用 mod 表示。 背景 最近在一道 Java 习题中&#xff0c;看到这样的一道题&#xff1…

求任意整数模3的余数

在回答这个问题之前&#xff0c;首先思考另一个问题&#xff1a;为什么是模3的余数&#xff0c;而不是2或5&#xff1f; 那是因为3很特殊&#xff0c;求一个数模3的余数时&#xff0c;有一种巧妙地解法。 算法 算法是将这个数的各位数字加起来&#xff0c;重复这一过程&…

大数求余数

问题 提供两个数据 a&#xff0c;b&#xff0c;计算 a%b 的余数。 你可能会觉得这个问题很简单。我们用 C 为例&#xff0c;如果 a 和 b 可以在 long long 表示范围&#xff0c;那么这个问题非常简单。但是如果 a 超过了 C 中 long long 都超过的数据&#xff0c;我们要如何求…

求余数联系和赋值运算

算术和赋值运算符 算术运算符&#xff1a; (加)、 -(减)、 *(乘)、 /(除)、 %(求余) 赋值运算符&#xff1a;、 、 -、 *、 /、 % 加法运算代码及效果 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title&…

怎么用计算机做求余,怎样用计算器求余数

这样用计算器求余数&#xff1a; 假设是求10825的余数&#xff0c;计算器的的计算步骤如下&#xff1a; 步骤1、用计算器的数字键输入108&#xff0c;如下图&#xff1a; 步骤2、按计算器上的红框这个符号&#xff0c;如下图&#xff1a; 步骤3、用计算器的数字键输入25&#x…

余数取余定理

一&#xff1a;前言 今天我们课上学习了余数的定理&#xff0c;最早好像是出自于孙子的《中华剩余定理》。今天我们讲的就是关于余数的一些操作。 二&#xff1a;加法 (ab)%m;(m是除数&#xff0c;%是取余的意思)。 有些题目就是让我们求几个数的和去除以某些数的余数。如果把…

【Java编程进阶】Java语言基础入门篇

前言 你好&#xff0c;欢迎你阅读 Java 编程基础教程系列专栏。每个技术人都有个大厂梦&#xff0c;我觉得这很正常&#xff0c;并不是饭后的谈资&#xff0c;而是每个技术人的追求。像百度&#xff0c;阿里&#xff0c;腾讯这样的大厂技术氛围和技术规范度一定是优于一些创业…

Java基础入门(一)----基本语言

目录 1. 标识符 2.关键字 3.注释 4.数据类型 5.运算符 5.1 常用运算符 5.1 运算符优先级 1. 标识符 在Java语言中&#xff0c;对于变量&#xff0c;常量&#xff0c;函数&#xff0c;语句块和命名的统称为Java标识符。Java标识符是由数字&#xff0c;字母&#xff0c;下…

ICCV 2019 | VIPL实验室5篇录取论文详解

上月&#xff0c;两年一度的国际计算机视觉大会ICCV 2019 公布了论文接收结果。今年投稿数量高达4303篇&#xff0c;与上一届 2143 篇相比&#xff0c;数量多出了将近一倍。最终全球仅1077篇论文被录取&#xff0c;录取率25.02%。中国科学院计算技术研究所视觉信息处理与学习研…