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)描 ...
随机推荐
- 深入浅出-iOS Block原理和内存中位置
Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 #简介 今天回顾一下blcok,基本 ...
- js防抖函数
一.什么是函数防抖 概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间. 举个栗子,坐电梯的时候,如 ...
- VMware15 镜像Centos7修改静态IP
VMware15 镜像Centos7修改静态IP * 我的网卡名称为ens33: * 配置IP在 /etc/sysconfig/network-scripts/ifcfg-ens33 目录下: * D ...
- Verifying dml pool data
数据出错 ,硬件变动 解决方案: 1.移除外接设备 2.bios还原
- Springboot拦截器实现IP黑名单
Springboot拦截器实现IP黑名单 一·业务场景和需要实现的功能 以redis作为IP存储地址实现. 业务场景:针对秒杀活动或者常规电商业务场景等,防止恶意脚本不停的刷接口. 实现功能:写一个拦 ...
- (七)MySQL常见的数据类型、约束和标识列
一.MySQL常见数据类型 1.数值型: ①整型:tinyint.smllint.mediumint.int/integer.bigint 图源:尚硅谷李玉婷 案例1:关键表格teacher,分别添加 ...
- selenium(3)-针对鼠标的操作
背景 用selenium做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击.双击.点击鼠标右键.拖拽等等. 而selenium给我们提供了一个类来处理这类事件-----------Acti ...
- 004.OpenShift命令及故障排查
一 CLI访问OpenShift资源 1.1 资源操作 OCP将OpenShift集群中的为由主节点管理的对象统称为资源,如:node.service.pod.project.deployment.u ...
- 大型ECShop安装搬家升级错误问题最全攻略
[引子] 最近将ECShop框架网站从租用服务器搬家至阿里云,虽然模块及功能上已经被修改的面目全非了,但基础部分还在. 在这个过程中遇到了很多的WARNING与ERROR,解决方案如下. [环境] 服 ...
- Java对MongoDB的CRUD
https://blog.51cto.com/aiilive/1339058 MongoDB提供的Java操作API可以说是对Mongo数据库命令的Java翻译,熟悉Mongo命令,熟悉Java操作数 ...