在“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三角形的更多相关文章

  1. JavaScript图形实例:SierPinski三角形

    1.SierPinski三角形 Sierpinski三角形是一种分形,由波兰数学家谢尔宾斯基在1915年提出,它是一种典型的自相似集.其生成过程为: (1)取一个三角形(多数使用等边三角形): (2) ...

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

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

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

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

  4. JavaScript图形实例:迭代函数系统生成图形

    迭代函数系统(Iterated Function System,IFS)可以用来创建分形图案,它是分形理论的重要分支,也是分形图形处理中最富生命力而且最具有广阔应用前景的领域之一.这一工作最早可以追溯 ...

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

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

  6. JavaScript图形实例:Canvas API

    1.Canvas概述 Canvas API(画布)用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitmap). 要使用HTML5在浏览器窗口中绘制 ...

  7. JavaScript图形实例:圆形图案

    在HTML5的Canvas 2D API中,可以调用arc方法绘制圆或圆弧.该方法调用格式为: context . arc(x, y, radius, startAngle, endAngle, an ...

  8. JavaScript图形实例:合成花卉图

    我们知道在直角坐标系中,圆的方程可描述为: X=R*COS(α) Y=R*SIN(α) 用循环依次取α值为0~2π,计算出X和Y,在canvas画布中将坐标点(X,Y)用线连起来,可绘制出一个圆.编写 ...

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

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

随机推荐

  1. 聊一聊高并发高可用那些事 - Kafka篇

    目录 为什么需要消息队列 1.异步 :一个下单流程,你需要扣积分,扣优惠卷,发短信等,有些耗时又不需要立即处理的事,可以丢到队列里异步处理. 2.削峰 :按平常的流量,服务器刚好可以正常负载.偶尔推出 ...

  2. Nginx思维导图

    1. Nginx简介 1.1 nginx概述 1.2 nginx的安装及程序环境 1.3 零复制&五种IO模型 1.4 nginx的基本配置 2. Nginx配置详解 2.1 main配置段详 ...

  3. CSS文本相关之水平排列[4]

    在正常流中,文本都是从左往右.自上而下排列显示,如果想要改变排列方向的话,可以通过CSS属性来改变. text-align属性 文本排列(text-align)可改变文本在水平上的方向,但不改变内部的 ...

  4. rest_framework django 简单使用(数据库创建数据, 覆盖数据, 其他的大同小异)

    事先说几个坑:数据库定义字段时候,不要定义name 要定义 username 首先, 定义model(简单定义) from django.db import models from django.co ...

  5. 11.实战交付一套dubbo微服务到k8s集群(4)之使用Jenkins进行持续构建交付dubo服务的提供者

    1.登录到jenkins,新建一个项目 2.新建流水线 3.设置保留的天数及份数 4. 添加参数 # 参数 . name: git_repo type: string description: 项目在 ...

  6. python中那些鲜为人知的功能特性

    经常逛GitHub的可能关注一个牛叉的项目,叫 What the f*ck Python! 这个项目列出了几乎所有python中那些鲜为人知的功能特性,有些功能第一次遇见时,你会冒出 what the ...

  7. Ubuntu16.06常见服务搭建

    摘要 系统环境Ubuntu 16.04 amd64 隔一段时间要配一次服务记不住,记录在这里方便以后安装. 目前更新了以下服务: ssh samba vimrc // 20200126更新 ssh 安 ...

  8. docker配置国内镜像地址,解决无法pull镜像问题docker: Error response from daemon

    问题: 执行命令 $ docker run -it --rm -p 8888:8080 tomcat:8.5.32 报错 Unable to find image 'tomcat:8.5.32' lo ...

  9. 终于搞明白Unicode,ASCII,UTF8,UCS2编码是啥了

    [本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 前言 本文起因于 ...

  10. 键盘侠Linux干货| ELK(Elasticsearch + Logstash + Kibana) 搭建教程

    前言 Elasticsearch + Logstash + Kibana(ELK)是一套开源的日志管理方案,分析网站的访问情况时我们一般会借助 Google / 百度 / CNZZ 等方式嵌入 JS ...