JavaScript图形实例:Koch曲线
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曲线的更多相关文章
- JavaScript图形实例:线段构图
在“JavaScript图形实例:四瓣花型图案”和“JavaScript图形实例:蝴蝶结图案”中,我们绘制图形时,主要采用的方法是先根据给定的曲线参数方程计算出两点坐标,然后将两点用线段连接起来,线段 ...
- JavaScript动画实例:曲线的绘制
在“JavaScript图形实例:曲线方程”一文中,我们给出了15个曲线方程绘制图形的实例.这些曲线都是根据其曲线方程,在[0,2π]区间取一系列角度值,根据给定角度值计算对应的各点坐标,然后在计算出 ...
- JavaScript图形实例:再谈IFS生成图形
在“JavaScript图形实例:迭代函数系统生成图形”一文中,我们介绍了采用迭代函数系统(Iterated Function System,IFS)创建分形图案的一些实例.在该文中,仿射变换函数W的 ...
- JavaScript图形实例:随机SierPinski三角形
在“JavaScript图形实例:SierPinski三角形”中,我们介绍了SierPinski三角形的基本绘制方法,在“JavaScript图形实例:迭代函数系统生成图形”一文中,介绍了采用IFS方 ...
- JavaScript图形实例:Hilbert曲线
德国数学家David Hilbert在1891年构造了一种曲线,首先把一个正方形等分成四个小正方形,依次从西北角的正方形中心出发往南到西南正方形中心,再往东到东南角的正方形中心,再往北到东北角正方形中 ...
- JavaScript图形实例:四瓣花型图案
设有坐标计算公式如下: X=L*(1+SIN(4α))*COS(α) Y=L*(1+SIN(4α))*SIN(α) 用循环依次取α值为0~2π,计算出X和Y,在canvas画布中对坐标位置(X,Y)描 ...
- JavaScript图形实例:图形的旋转变换
旋转变换:图形上的各点绕一固定点沿圆周路径作转动称为旋转变换.可用旋转角表示旋转量的大小. 旋转变换通常约定以逆时针方向为正方向.最简单的旋转变换是以坐标原点(0,0)为旋转中心,这时,平面上一点P( ...
- JavaScript图形实例:圆内螺线
数学中有各式各样富含诗意的曲线,螺旋线就是其中比较特别的一类.螺旋线这个名词来源于希腊文,它的原意是“旋卷”或“缠卷”.例如,平面螺旋线便是以一个固定点开始向外逐圈旋绕而形成的曲线. 阿基米德螺线和黄 ...
- JavaScript图形实例:正多边形
圆心位于坐标原点,半径为R的圆的参数方程为 X=R*COS(θ) Y=R*SIN(θ) 在圆上取N个等分点,将这N个点首尾连接N条边,可以得到一个正N边形. 1.正多边形阵列 构造一个8行8列的正N( ...
随机推荐
- Java实现 蓝桥杯VIP 算法提高 文化之旅
算法提高 文化之旅 时间限制:1.0s 内存限制:128.0MB 问题描述 有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一种文化超过一次(即如果他学习了某种文化,则他就不 ...
- 基于Azure IoT开发.NET物联网应用系列-全新的Azure IoT架构
物联网技术已经火了很多年了,业界各大厂商都有各自成熟的解决方案.我们公司主要搞新能源汽车充电,充电桩就是物联网技术的最大应用,车联网.物联网.互联网三网合一.2017年的时候重点研究过Azure Io ...
- [web][学习随笔]php中http post&get数据传输
GET <!--客户端发送--> <form id="form1" action="doGet.php" method="get&q ...
- v-model 指令来实现双向数据绑定
<div id="app"> <p>{{ message }}</p> <input v-model="message" ...
- cubic-bezier() 函数
2020-03-13 cubic-bezier() 函数 ubic-bezier() 函数定义了一个贝塞尔曲线(Cubic Bezier). 贝塞尔曲线曲线由四个点 P0,P1,P2 和 P3 定义. ...
- MATLAB作图之一
问题 在使用MATLAB当中的imagesc作图的时候,如果数据矩阵元素太少,得到的图看起来会很"粗糙"(图1).那么如何得到更为"圆润"的图像呢? A = r ...
- 自动完成 APP【字典树(Trie树)+dfs】
自动完成 APP 传送门 来源:upc12786 题目描述 奶牛 Bessie 很喜欢用手机上网聊天,但她的蹄子太大,经常会按到好几个键造成不必要的麻烦(丢死人了,你下辈子还是不要当奶牛了).于是 ...
- iOS/swift 单选框和复选框
/** 复选框 */ import UIKit class LYBmutipleSelectView: UIView { var selectindexs:[Int]=[]//选中的 //标题数组 v ...
- 大厂面试过程复盘(微信/阿里/头条均拿offer,附答案篇)
背景 本人前端,3年经验,由于个人的原因,决定跳槽,于是大概3月开始找工作,总历时大概2个月,面试了微信/阿里/头条,三家都拿到了offer,来分享一下面经. 问题比较多,而且很多面试题都是跟个人项目 ...
- GestureDetector手势检测
Android手势检测器GestureDetector,要创建一个GestureDetector需要传入一个监听器GestureDetector.OnGestureListener. 案例(实现手机相 ...