Koch曲线的构造过程是:取一条长度为L0的直线段,将其三等分,保留两端的线段,将中间的一段改换成夹角为60度的两个等长直线;再将长度为L0/3的4个直线段分别进行三等分,并将它们中间的一段均改换成夹角为60度的两段长为L0/9的直线段;重复以上操作直至无穷,可得以一条具有自相似结构的折线,如图1所示。

图1  Koch曲线的生成

Koch曲线采用递归过程易于实现,编写如下的HTML代码。

<!DOCTYPE html>

<head>

<title>Koch曲线</title>

</head>

<body>

<canvas id="myCanvas" width="600" height="400" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

var maxdepth =5;

var curdepth = 0;

ctx.lineWidth = 2;

Koch({x:50,y:150},{x:550,y:150},Math.PI/3);

function Koch(p1,p2,angle)

{

curdepth++;

if (curdepth<=maxdepth)

{

var x1=(2*p1.x+p2.x)/3;

var y1=(2*p1.y+p2.y)/3;

var x3=(2*p2.x+p1.x)/3;

var y3=(2*p2.y+p1.y)/3;

var x2=(x3-x1)*Math.cos(angle)-(y3-y1)*Math.sin(angle)+x1;

var y2=(x3-x1)*Math.sin(angle)+(y3-y1)*Math.cos(angle)+y1;

Koch(p1,{x:x1,y:y1},Math.PI/3);

Koch({x:x1,y:y1},{x:x2,y:y2},Math.PI/3);

Koch({x:x2,y:y2},{x:x3,y:y3},Math.PI/3);

Koch({x:x3,y:y3},p2,Math.PI/3);

}

if (curdepth>maxdepth)

draw([p1,{x:x1,y:y1},{x:x2,y:y2},{x:x3,y:y3},p2]);

curdepth--;

}

function draw(points)

{

ctx.strokeStyle = "red";

ctx.beginPath()

ctx.moveTo(points[0].x,points[0].y)

for(i=1;i<points.length;i++)

{

ctx.lineTo(points[i].x,points[i].y);

}

ctx.closePath()

ctx.stroke()

}

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,可以看到在浏览器窗口中绘制出的Koch曲线,如图2所示。

图2  递归深度maxdepth =5的Koch曲线

由图1和2可知,Koch曲线的初始图元是直线,但最终结果却是一条参差不齐的曲线,很像雪花的边缘,如果将3条这样的曲线围在一起,便得到Koch雪花的图案。这样,初始图元不是一条直线,而是一个等边三角形。Koch雪花的生成示例如图3所示。

图3  Koch雪花的生成

在程序设计时,定义好等边三角形的三个顶点坐标,调用三次Koch递归过程,以实现等边三角形三条边各自的Koch曲线生成,即可得到Koch雪花图案。编写的HTML文件如下。

<!DOCTYPE html>

<head>

<title>Koch雪花</title>

</head>

<body>

<canvas id="myCanvas" width="600" height="600" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

var maxdepth =5;

var curdepth = 0;

ctx.lineWidth = 2;

Koch({x:50,y:450},{x:500,y:450},Math.PI/3);

Koch({x:275,y:450-225*Math.sqrt(3)},{x:50,y:450},Math.PI/3);

Koch({x:500,y:450},{x:275,y:450-225*Math.sqrt(3)},Math.PI/3);

function Koch(p1,p2,angle)

{

curdepth++;

if (curdepth<=maxdepth)

{

var x1=(2*p1.x+p2.x)/3;

var y1=(2*p1.y+p2.y)/3;

var x3=(2*p2.x+p1.x)/3;

var y3=(2*p2.y+p1.y)/3;

var x2=(x3-x1)*Math.cos(angle)-(y3-y1)*Math.sin(angle)+x1;

var y2=(x3-x1)*Math.sin(angle)+(y3-y1)*Math.cos(angle)+y1;

Koch(p1,{x:x1,y:y1},Math.PI/3);

Koch({x:x1,y:y1},{x:x2,y:y2},Math.PI/3);

Koch({x:x2,y:y2},{x:x3,y:y3},Math.PI/3);

Koch({x:x3,y:y3},p2,Math.PI/3);

}

if (curdepth>maxdepth)

draw([p1,{x:x1,y:y1},{x:x2,y:y2},{x:x3,y:y3},p2]);

curdepth--;

}

function draw(points)

{

ctx.strokeStyle = "red";

ctx.beginPath()

ctx.moveTo(points[0].x,points[0].y)

for(i=1;i<points.length;i++)

{

ctx.lineTo(points[i].x,points[i].y);

}

ctx.closePath()

ctx.stroke()

}

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,在浏览器窗口中可能会绘制出如图4所示的Koch雪花图案。

图4  递归深度maxdepth =5的Koch雪花图案

JavaScript图形实例:Koch曲线的更多相关文章

  1. JavaScript图形实例:线段构图

    在“JavaScript图形实例:四瓣花型图案”和“JavaScript图形实例:蝴蝶结图案”中,我们绘制图形时,主要采用的方法是先根据给定的曲线参数方程计算出两点坐标,然后将两点用线段连接起来,线段 ...

  2. JavaScript动画实例:曲线的绘制

    在“JavaScript图形实例:曲线方程”一文中,我们给出了15个曲线方程绘制图形的实例.这些曲线都是根据其曲线方程,在[0,2π]区间取一系列角度值,根据给定角度值计算对应的各点坐标,然后在计算出 ...

  3. JavaScript图形实例:再谈IFS生成图形

    在“JavaScript图形实例:迭代函数系统生成图形”一文中,我们介绍了采用迭代函数系统(Iterated Function System,IFS)创建分形图案的一些实例.在该文中,仿射变换函数W的 ...

  4. JavaScript图形实例:随机SierPinski三角形

    在“JavaScript图形实例:SierPinski三角形”中,我们介绍了SierPinski三角形的基本绘制方法,在“JavaScript图形实例:迭代函数系统生成图形”一文中,介绍了采用IFS方 ...

  5. JavaScript图形实例:Hilbert曲线

    德国数学家David Hilbert在1891年构造了一种曲线,首先把一个正方形等分成四个小正方形,依次从西北角的正方形中心出发往南到西南正方形中心,再往东到东南角的正方形中心,再往北到东北角正方形中 ...

  6. JavaScript图形实例:四瓣花型图案

    设有坐标计算公式如下: X=L*(1+SIN(4α))*COS(α) Y=L*(1+SIN(4α))*SIN(α) 用循环依次取α值为0~2π,计算出X和Y,在canvas画布中对坐标位置(X,Y)描 ...

  7. JavaScript图形实例:图形的旋转变换

    旋转变换:图形上的各点绕一固定点沿圆周路径作转动称为旋转变换.可用旋转角表示旋转量的大小. 旋转变换通常约定以逆时针方向为正方向.最简单的旋转变换是以坐标原点(0,0)为旋转中心,这时,平面上一点P( ...

  8. JavaScript图形实例:圆内螺线

    数学中有各式各样富含诗意的曲线,螺旋线就是其中比较特别的一类.螺旋线这个名词来源于希腊文,它的原意是“旋卷”或“缠卷”.例如,平面螺旋线便是以一个固定点开始向外逐圈旋绕而形成的曲线. 阿基米德螺线和黄 ...

  9. JavaScript图形实例:正多边形

    圆心位于坐标原点,半径为R的圆的参数方程为 X=R*COS(θ) Y=R*SIN(θ) 在圆上取N个等分点,将这N个点首尾连接N条边,可以得到一个正N边形. 1.正多边形阵列 构造一个8行8列的正N( ...

随机推荐

  1. Java实现 LeetCode 327 区间和的个数

    327. 区间和的个数 给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper. 区间和 S(i, j) 表示在 nums 中,位置从 i ...

  2. Java实现 蓝桥杯VIP 算法训练 入学考试

    问题描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:" ...

  3. java实现指数问题

    3^n mod 19 求n次幂,对19取模 ================ (3 * 3) * (3 * 3) * 3 public class A { // 分治 public static in ...

  4. 关于linux免密登录及ssh客户端的使用

    操作系统环境: CentOS Linux release 7.7.1908 (Core) 1.首先在linux服务器上,使用ssh-keygen命令生成密钥对文件(一直回车即可,默认使用rsa算法), ...

  5. 关于Graph Convolutional Network的初步理解

    为给之后关于图卷积网络的科研做知识积累,这里写一篇关于GCN基本理解的博客.GCN的本质是一个图网络中,特征信息的交互+与传播.这里的图指的不是图片,而是数据结构中的图,图卷积网络的应用非常广泛 ,经 ...

  6. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  7. MyBatis运行流程及入门第一个程序

    1. mybatis是什么? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并 ...

  8. laravel clone后需要做的操作

    首先 安装依赖关系 composer install 第二步 复制配置文件 cp .env.example .env 第三步 创建新的应用程序密钥 php artisan key:generate 第 ...

  9. MyISAM 和 InnoDB 索引结构及其实现原理

    数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询.更新数据库表中数据. 索引的实现通常使用B_TREE. B_TREE索引加速了数据访问,因为存储引擎不会再去扫描整张表得到需要的数据; ...

  10. flink实时数仓从入门到实战

    第一章.flink实时数仓入门 一.依赖 <!--Licensed to the Apache Software Foundation (ASF) under oneor more contri ...