JavaScript图形实例:随机SierPinski三角形
在“JavaScript图形实例:SierPinski三角形”中,我们介绍了SierPinski三角形的基本绘制方法,在“JavaScript图形实例:迭代函数系统生成图形”一文中,介绍了采用IFS方法生成SierPinski三角形的方法。下面再介绍两种SierPinski三角形的构造方法,以扩展知识面。
1.随机点法
采用随机点的方法可以得到SierPinski三角形。具体过程为:
(1)任意取平面上三点A、B、C,组成一个三角形,并任意取三角形ABC内的一点P;
(2)求出P和A、B、C三个顶点中任意一个顶点的中点P1;
(3)描出该中点P1;
(4)将P1作为新的P点,转步骤(2),直到描出的点数达到规定要求(如10000个点)。
按上述思想,编写如下的HTML文件。在编程时,为简单计,不保证初始的P点一定在三角形ABC内(有可能在三角形外会描出几个散点,但不影响最后结果),也没有判断A、B、C三点可能共线的情况(此时无法构成三角形)。有兴趣的读者可以自行处理这两种情况,以完善代码。
<!DOCTYPE html>
<head>
<title>随机SierPinski三角形</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="300" style="border:3px double #996633;">
</canvas>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
function draw()
{
ctx.fillStyle="#EEEEFF";
ctx.fillRect(0,0,300,300);
ctx.fillStyle="red";
ctx.font="32px";
var ax=Math.floor(Math.random()*200+50);
var ay=Math.floor(Math.random()*200+50);
var bx=Math.floor(Math.random()*200+50);
var by=Math.floor(Math.random()*200+50);
var cx=Math.floor(Math.random()*200+50);
var cy=Math.floor(Math.random()*200+50);
var px=Math.floor(Math.random()*200+50);
var py=Math.floor(Math.random()*200+50);
var dx=0;
var dy=0;
for (i=0; i<10000; i++)
{
index =Math.floor(Math.random()*3+1);
if (index==1)
{
dx = (ax + px)/2;
dy = (ay + py)/2;
}
else if (index == 2)
{
dx = (bx + px)/2;
dy = (by + py)/2;
}
else
{
dx = (cx + px)/2;
dy = (cy + py)/2;
}
ctx.fillText('.',dx,dy);
px = dx;
py = dy;
}
}
draw();
</script>
</body>
</html>
在浏览器中打开包含这段HTML代码的html文件,可以看到在浏览器窗口中绘制出一个SierPinski三角形,如图1所示。

图1 SierPinski三角形
将程序中的调用语句“draw()”改写为“window.setInterval('draw()', 1500);”,则在浏览器窗口中会每隔1.5秒绘制一个随机SierPinski三角形,如图2所示。

图2 每隔1.5秒绘制一个随机SierPinski三角形
由图2可以看出,有些三角形太小,设置有些成一条直线,因此,可以改写上面的程序,要求随机取点A、B、C时,保证三个边长均大于100,且三点不共线。改写的HTML文件内容如下。
<!DOCTYPE html>
<head>
<title>随机SierPinski三角形</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="300" style="border:3px double #996633;">
</canvas>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
function draw()
{
ctx.fillStyle="#EEEEFF";
ctx.fillRect(0,0,300,300);
ctx.fillStyle="red";
ctx.font="32px";
while (1)
{
var ax=Math.floor(Math.random()*200+50);
var ay=Math.floor(Math.random()*200+50);
var bx=Math.floor(Math.random()*200+50);
var by=Math.floor(Math.random()*200+50);
var cx=Math.floor(Math.random()*200+50);
var cy=Math.floor(Math.random()*200+50);
ab=Math.sqrt((bx-ax)*(bx-ax)+(by-ay)*(by-ay));
ac=Math.sqrt((cx-ax)*(cx-ax)+(cy-ay)*(cy-ay));
bc=Math.sqrt((cx-bx)*(cx-bx)+(cy-by)*(cy-by));
if (ab<100 || ac<100 || bc<100) continue;
if (ab+bc==ac || ab+ac==bc || ac+bc==ab) continue;
var px=Math.floor(Math.random()*200+50);
var py=Math.floor(Math.random()*200+50);
break;
}
var dx=0;
var dy=0;
for (i=0; i<10000; i++)
{
index =Math.floor(Math.random()*3+1);
if (index==1)
{
dx = (ax + px)/2;
dy = (ay + py)/2;
}
else if (index == 2)
{
dx = (bx + px)/2;
dy = (by + py)/2;
}
else
{
dx = (cx + px)/2;
dy = (cy + py)/2;
}
ctx.fillText('.',dx,dy);
px = dx;
py = dy;
}
}
window.setInterval('draw()', 1500);
</script>
</body>
</html>
在浏览器中打开包含这段改写后的HTML代码的html文件,在浏览器窗口中也会每隔1.5秒绘制一个随机SierPinski三角形,如图3所示,此时每个随机SierPinski三角形的最小边长均会超过100,三角形不会显得较小。

图3 每隔1.5秒绘制一个较大的随机SierPinski三角形
上面程序中随机点法构造SierPinski三角形是描点10000个得到的。为展示描点过程,编写如下的HTML文件。
<!DOCTYPE html>
<head>
<title>随机SierPinski三角形</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="400" style="border:3px double #996633;">
</canvas>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
ctx.fillStyle="#EEEEFF";
ctx.fillRect(0,0,400,400);
ctx.fillStyle="red";
ctx.font="32px";
while (1)
{
var ax=Math.floor(Math.random()*400);
var ay=Math.floor(Math.random()*400);
var bx=Math.floor(Math.random()*400);
var by=Math.floor(Math.random()*400);
var cx=Math.floor(Math.random()*400);
var cy=Math.floor(Math.random()*400);
ab=Math.sqrt((bx-ax)*(bx-ax)+(by-ay)*(by-ay));
ac=Math.sqrt((cx-ax)*(cx-ax)+(cy-ay)*(cy-ay));
bc=Math.sqrt((cx-bx)*(cx-bx)+(cy-by)*(cy-by));
if (ab<200 || ac<200 || bc<200) continue;
if (ab+bc==ac || ab+ac==bc || ac+bc==ab) continue;
var px=Math.floor(Math.random()*400);
var py=Math.floor(Math.random()*400);
break;
}
var i=0;
function draw()
{
index =Math.floor(Math.random()*3+1);
if (index==1)
{
dx = (ax + px)/2;
dy = (ay + py)/2;
}
else if (index == 2)
{
dx = (bx + px)/2;
dy = (by + py)/2;
}
else
{
dx = (cx + px)/2;
dy = (cy + py)/2;
}
ctx.fillText('.',dx,dy);
px = dx;
py = dy;
i++;
if (i>=10000)
{
ctx.fillStyle="#EEEEFF";
ctx.fillRect(0,0,400,400);
ctx.fillStyle="red";
i=0;
}
}
window.setInterval('draw()',1);
</script>
</body>
</html>
在浏览器中打开包含这段HTML代码的html文件,在浏览器窗口中呈现出一个随机SierPinski三角形的喷出过程,如图4所示。

图4 随机SierPinski三角形的喷出过程
2.按组合数的奇偶性直接描点构造SierPinski三角形
设有如下的杨辉三角形,若将杨辉三角形的奇数处画圆点,偶数处留空,则会得到SierPinski三角形。

由于杨辉三角中第i行第j列的数字正是组合数C(i,j)的结果。因此,对杨辉三角形中各行各列数字的讨论转化为对组合数C(n,m)的讨论。
组合数的奇偶性判定方法为:
对于C(n,m),若n&m == m 则C(n,m)为奇数,否则为偶数。
根据这个结论,直接编写如下的HTML文件。
<!DOCTYPE html>
<head>
<title>按组合数奇偶性构造SierPinski三角形</title>
<script type="text/javascript">
function draw(id)
{
var canvas=document.getElementById(id);
if (canvas==null)
return false;
var ctx=canvas.getContext('2d');
ctx.fillStyle="#EEEEFF";
ctx.fillRect(0,0,300,300);
ctx.fillStyle="red";
for (i=0;i<256;i++)
{
for (j=0;j<=i;j++)
if ((i&j)==j)
ctx.fillText('.',j+30,i+30);
}
}
</script>
</head>
<body onload="draw('myCanvas');">
<canvas id="myCanvas" width="300" height="300" style="border:3px double #996633;">
</canvas>
</body>
</html>
在浏览器中打开包含这段HTML代码的html文件,可以看到在浏览器窗口中绘制出如图5所示的SierPinski三角形。

图5 SierPinski三角形
JavaScript图形实例:随机SierPinski三角形的更多相关文章
- JavaScript图形实例:SierPinski三角形
1.SierPinski三角形 Sierpinski三角形是一种分形,由波兰数学家谢尔宾斯基在1915年提出,它是一种典型的自相似集.其生成过程为: (1)取一个三角形(多数使用等边三角形): (2) ...
- JavaScript图形实例:线段构图
在“JavaScript图形实例:四瓣花型图案”和“JavaScript图形实例:蝴蝶结图案”中,我们绘制图形时,主要采用的方法是先根据给定的曲线参数方程计算出两点坐标,然后将两点用线段连接起来,线段 ...
- JavaScript图形实例:再谈IFS生成图形
在“JavaScript图形实例:迭代函数系统生成图形”一文中,我们介绍了采用迭代函数系统(Iterated Function System,IFS)创建分形图案的一些实例.在该文中,仿射变换函数W的 ...
- JavaScript图形实例:迭代函数系统生成图形
迭代函数系统(Iterated Function System,IFS)可以用来创建分形图案,它是分形理论的重要分支,也是分形图形处理中最富生命力而且最具有广阔应用前景的领域之一.这一工作最早可以追溯 ...
- JavaScript图形实例:图形的旋转变换
旋转变换:图形上的各点绕一固定点沿圆周路径作转动称为旋转变换.可用旋转角表示旋转量的大小. 旋转变换通常约定以逆时针方向为正方向.最简单的旋转变换是以坐标原点(0,0)为旋转中心,这时,平面上一点P( ...
- JavaScript图形实例:Canvas API
1.Canvas概述 Canvas API(画布)用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitmap). 要使用HTML5在浏览器窗口中绘制 ...
- JavaScript图形实例:圆形图案
在HTML5的Canvas 2D API中,可以调用arc方法绘制圆或圆弧.该方法调用格式为: context . arc(x, y, radius, startAngle, endAngle, an ...
- JavaScript图形实例:合成花卉图
我们知道在直角坐标系中,圆的方程可描述为: X=R*COS(α) Y=R*SIN(α) 用循环依次取α值为0~2π,计算出X和Y,在canvas画布中将坐标点(X,Y)用线连起来,可绘制出一个圆.编写 ...
- JavaScript图形实例:四瓣花型图案
设有坐标计算公式如下: X=L*(1+SIN(4α))*COS(α) Y=L*(1+SIN(4α))*SIN(α) 用循环依次取α值为0~2π,计算出X和Y,在canvas画布中对坐标位置(X,Y)描 ...
随机推荐
- jsp页面用DBHelper实现简单的登陆验证
首先我们需要写一个简单的登陆页面login.jsp,然后用from表单提交给index.jsp页面.在index.jsp页面通过DBHelper连接数据库判断账号和密码,如果密码正确则显示登陆成功. ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- Mini2440上的第一个程序——点亮Led
手头的Mini2440搁置了两年半之后,我再次决定拿出它,重新尝试嵌入式Linux的学习. 我使用的是友善之臂的Mini2440开发板.韦东山的<嵌入式Linux应用开发完成手册>及其视频 ...
- @font-face规则指定字体
兼容性写法: @font-face { font-family: '字体名'; src: url('字体名.eot'); /* IE9 兼容模式 */ src: url('字体名.eot?#iefix ...
- tp6 路由匹配参数获取问题
tp6是一个封装度很高的框架,在大部分场景下都能做到开箱即用 本次遇到情况为,当请求消息体为索引数组时,路由参数无法正常获取 首先看正常路由匹配 路由定义 Route::post('test/:a/: ...
- laravel查询常用的方式含义.
find($id) 传值并返回一个模型.如果不存在匹配的模型,则返回null.findOrFail($id) 传值并返回一个模型.如果不存在匹配的模型, 它会抛出异常.first() 返回在数据库中找 ...
- 鼠标悬停,使用css切换图片
鼠标悬停,使用css切换图片 当鼠标悬停在li上面切换另一张图片,只需添加下述css样式即可
- jmeter正则提取器提取一个值或多个值
[安装Dummy插件] 这个插件可以模拟服务器返回,相当于一个mockserver了. 首先安装Dummy,选项--插件管理--可选插件--Dummy. [模拟响应] 添加线程组,在线程组下添加Dum ...
- WireShark——IP协议包分析(Ping分析IP协议包)
互联网协议 IP 是 Internet Protocol 的缩写,中文缩写为“网协”.IP 协议是位于 OSI 模型中第三层的协议,其主要目的就是使得网络间能够互联通信.前面介绍了 ARP 协议, 该 ...
- mongoDB的基本使用方法
MongoDB 安装(乌班图系统) apt install mongodb mongoDB与sql的对比 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数 ...