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实现第三届蓝桥杯填算式

    ** 填算式** [结果填空] (满分11分) 看这个算式: ☆☆☆ + ☆☆☆ = ☆☆☆ 如果每个五角星代表 1 ~ 9 的不同的数字. 这个算式有多少种可能的正确填写方法? 173 + 286 ...

  2. PAT 科学计数法

    科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指 ...

  3. requireJS模块化

    1. JavaScript里面js代码的写法:目标是解决冲突和依赖 函数式编程,全局函数和变量--很容易覆盖 对象的写法--也会从外面改变 命名空间:利用名称不同缓冲js代码的冲突---名称太长,不方 ...

  4. Java基础(八)

    一.Java集合框架 Java集合类库也将接口与实现分离. 队列接口指出可以在队列的尾部添加元素,在队列的头部删除元素,并且可以查找队列中元素的个数. 队列通常有两种实现方式:一种是使用循环数组:另一 ...

  5. 【Spring注解驱动开发】使用@Scope注解设置组件的作用域

    写在前面 Spring容器中的组件默认是单例的,在Spring启动时就会实例化并初始化这些对象,将其放到Spring容器中,之后,每次获取对象时,直接从Spring容器中获取,而不再创建对象.如果每次 ...

  6. 实验五shell脚本编程

    项目 内容 这个作业属于哪个课程 <班级课程的主页链接> 这个作业的要求在哪里 作业要求链接地址 学号-姓名 17043220-万文文 作业学习目标 1)了解shell脚本的概念及使用.2 ...

  7. Cypress系列(17)- 查找页面元素的辅助方法

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 前言 单一的基础定位元素方法并不一定能满 ...

  8. AttributeError: 'PyQt5.QtCore.pyqtSignal' object has no attribute 'connect'

    pyqt5信号要定义为类属性 #!/usr/bin/python3 # -*- coding: utf-8 -*- from PyQt5.Qt import * import sys class Wi ...

  9. 在CentOS7上源码安装OpenResty

    您必须将这些库perl 5.6.1+libreadlinelibpcrelibssl安装在您的电脑之中. 对于 Linux来说, 您需要确认使用 ldconfig 命令,让其在您的系统环境路径中能找到 ...

  10. 东方步进电机马达驱动板CVK系列说明书

    东方步进电机马达驱动板CVK系列说明书