JavaScript实现曼德勃罗(Mandelbrot)集合

article/2025/9/15 18:04:24

运用知识: js线程、Mandelbrot

 

1.  js线程

 

js线程简介:

在HTML5中的线程是这样一种机制,它允许在Web程序中并发执行多个JS脚本,

每一个脚本执行流都称为一个线程,彼此间相互独立,并且有浏览器中JS引擎

负责管理。

HTML5中的Web worker可以分为两种不同线程类型,一个是专用线程DedicatedWorker,

一个是共享线程SharedWorker.

worker用法很简单,它要求将要放在子线程运行的代码独立到一个js文件,通过

new Worker("worker.js")将这个js文件运行在worker线程,通过worker.postMessage()

实现主线程向worker线程发送消息。

 

web worker总结:

我们可以做什么:

1.可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信

2.可以在worker中通过importScripts(url)加载另外的脚本文件

3.可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval()

4.可以使用XMLHttpRequest来发送请求

5.可以访问navigator的部分属性

有那些局限性:

1.不能跨域加载JS

2.worker内代码不能访问DOM

3.各个浏览器对Worker的实现不大一致,例如FF里允许worker中创建新的worker,而Chrome中就不行

4.不是每个浏览器都支持这个新特性(IE9不支持)

 

2. 曼德勃罗(Mandelbrot)集合

 

分形简介:

尽管类似于柯赫雪花这样的自相似图形早已经出现。但是真正把这些问题系统地发展成一门学问,则是在二十世纪下半页。数学家本华·曼德勃罗(Benoit B. Mandelbrot)把这些部分与整体以某种方式相似的形体称为分形(fractal)。1975年,他创立了分形几何学(Fractal Geometry)。在此基础上,形成了研究分形性质及其应用的科学,称为分形理论(Fractal Theory)。因此,曼德勃罗也被称为“分形学之父”。现在,分形理论已经发展成为一门十分风靡和活跃的新理论、新学科,特别是把分形理论和混沌理论结合之后,更是衍生出一大片广阔的研究天地。分形的世界与我们平常所研究的几何学中很多直观的常识之间具有巨大的冲突。例如,平常我们说一个几何图形的维度,那么这个维度一般都应该是整数。例如平面上一个矩形就是二维的,空间中一个球体就是三维的。但是在分析几何中,几何图形的维度都是不是整数而是分数。这个维度又称为豪斯多夫维或豪斯多夫-贝塞科维奇维(Hausdorff-Becikovich Dimesion),它是由数学家豪斯多夫于1918年引入的。通过豪斯多夫维可以给一个任意复杂的点集合比如分形赋予一个维度

 

 曼德勃罗集合(Mandelbrot Set):

曼德勃罗集合(Mandelbrot Set)或曼德勃罗复数集合,是一种在复平面上组成分形的点的集合,因由曼德勃罗提出而得名。曼德博集合可以使复二次多项式 进行迭代来获得。其中,c是一个复参数。对于每一个c,从 z = 0 开始对fc(z)进行迭代。序列 的值或者延伸到无限大,或者只停留在有限半径的圆盘内(这与不同的参数c有关)。曼德布洛特集合就是使以上序列不延伸至无限大的所有c点的集合。
 

 

下面看程序效果:

 

下面看代码部分:

fractal.html

我们使用画布来显示图案canvas的putImageData()、getImageData()绘制

<!doctype html>
<html lang="en">
<head>
<title>Fractal Explorer</title>
<meta charset="utf-8">
<link rel="stylesheet" href="fractal.css">
<script src="mandellib.js"></script>
<script src="mandel.js"></script>
</head>
<body>
<canvas id="fractal" width="800" height="600"></canvas>
</body>
</html>

 

fractal.html简单的css


html, body, canvas {width: 100%;height: 100%;margin: 0px;padding: 0px;
}canvas {display: block;
}

 

mandellib.js

根据row行数创建任务、制作调色板、绘制一行像素、设置画布等。

/* * mandellib.js*** ------ Ready Bake Globals ---- */
var canvas;
var ctx;var i_max = 1.5;
var i_min = -1.5;
var r_min = -2.5;
var r_max = 1.5;var max_iter = 1024;
var escape = 100;
var palette = [];/* * ------- Ready Bake Code --------**///
// packages up the data we need to send to the worker
//
function createTask(row) {var task = {row: row,				// row number we're working onwidth: rowData.width,   // width of the ImageData object to fillgeneration: generation, // how far in we arer_min: r_min,r_max: r_max,i: i_max + (i_min - i_max) * row / canvas.height,max_iter: max_iter,escape: escape};return task;
}
//
// This function maps the numbers 0 to max_iter to 
// 256 and then fills the palette with (r, g, b) values
// so that the colors next to each other in the array
// are relatively close to each other in color, and
// by increasing each of r, g, b at a different rate this 
// works well to fill the spectrum for max_iter > 256.
//
//
function makePalette() {function wrap(x) {x = ((x + 256) & 0x1ff) - 256;if (x < 0) x = -x;return x;}for (i = 0; i <= this.max_iter; i++) {palette.push([wrap(7*i), wrap(5*i), wrap(11*i)]);}
}//
// drawRow gets maps the values in the array returned from a worker
// 	for one row to a color using the palette.
//
function drawRow(workerResults) {var values = workerResults.values;	// The values array the worker sends backvar pixelData = rowData.data;		// The actual pixels in the ImageData obj// The pixelData is a *reference* to the// 	rowData.data! so changing pixelData// 	changes the rowData.data!!!for (var i = 0; i < rowData.width; i++) {  // for each pixel in the rowvar red = i * 4;var green = i * 4 + 1;var blue = i * 4 + 2;var alpha = i * 4 + 3;pixelData[alpha] = 255; // set alpha to opaque// if the values array has a neg number, set the color to blackif (values[i] < 0) {pixelData[red] = pixelData[green] = pixelData[blue] = 0;} else {//// map the number from the values array returned by the worker// to a color from the palette//var color = this.palette[values[i]];//// each color has an rgb component, so set the rgb of// the pixel we're working on to r,g,b.//pixelData[red] = color[0];pixelData[green] = color[1];pixelData[blue] = color[2];}}//// paint the row back into the canvas// workerData.row is the row number we're working on// rowData contains the data we just updated!// we start at column 0, so x, y = 0, row//ctx.putImageData(this.rowData, 0, workerResults.row);
}//
// setupGraphics sets up some of the initial values for the variables used in
// 	 the Mandelbrot computation, and sets the canvas width and height
//	 to the width and height of the window.
//
function setupGraphics() {canvas = document.getElementById("fractal");ctx = canvas.getContext("2d");canvas.width = window.innerWidth;canvas.height = window.innerHeight;var width = ((i_max - i_min) * canvas.width / canvas.height);var r_mid = (r_max + r_min) / 2;r_min = r_mid - width/2;r_max = r_mid + width/2;rowData = ctx.createImageData(canvas.width, 1);makePalette();
}

 

workerlib.js 子线程使用的函数computeRow(),计算ImageData每行的像素对应的调色板值

//
// Computes a row of the fractal
// The values array returned to the manager code contains a 
//	number for each pixel in the row
// 
function computeRow(task) {var iter = 0;var c_i = task.i;var max_iter = task.max_iter;var escape = task.escape * task.escape;task.values = [];for (var i = 0; i < task.width; i++) {var c_r = task.r_min + (task.r_max - task.r_min) * i / task.width;var z_r = 0, z_i = 0;for (iter = 0; z_r*z_r + z_i*z_i < escape && iter < max_iter; iter++) {// z -> z^2 + cvar tmp = z_r*z_r - z_i*z_i + c_r;z_i = 2 * z_r * z_i + c_i;z_r = tmp;}if (iter == max_iter) {iter = -1;}task.values.push(iter);}return task;
}

 

worker.js 后台子线程,我们创建八个,负责计算工作,返回给主线程

importScripts("workerlib.js");
onmessage = function(task) {var workerResult = computeRow(task.data);postMessage(workerResult);
}

 

mandel.js 主要是将画布中每行的任务分发给8个线程,监听canvas点击事件响应重新绘制等。

/* * mandel.js*/var numberOfWorkers = 8;
var workers = [];
var rowData;
var nextRow = 0;
var generation = 0;window.onload = init;function init() {setupGraphics();//// When you click on the canvas, the handler is called.// An event object is passed in that contains the//  x, y position of the mouse click. We pass those//  values to the click handler.//canvas.onclick = function(event) {handleClick(event.clientX, event.clientY);};//// When you resize the browser window, we need//	to resize the canvas and restart the workers.//window.onresize = function() {resizeToWindow();};//// Create all the workers and set up the message handler.  // 	Add each worker to the workers array.//for (var i = 0; i < numberOfWorkers; i++) {var worker = new Worker("worker.js");worker.onmessage = function(event) {processWork(event.target, event.data)}worker.idle = true;workers.push(worker);}//// Start the workers//startWorkers();}//
// startWorkers
//	This function resets the workers to start them working
//		at the top of the fractal (row 0). It loops through
//		all the workers in the workers array and assigns
//		each worker a task to compute a row.
//	By posting a message with the task, we start the
//		worker's computation.
//
function startWorkers() {generation++;nextRow = 0;for (var i = 0; i < workers.length; i++) {var worker = workers[i];if (worker.idle) {var task = createTask(nextRow);worker.idle = false;worker.postMessage(task);nextRow++;}}
} //
// processWork
// 	This is the function we call when the worker posts
//		back a message with the results.
//	If the worker is working on the current fractal
//		generation, we draw the row of data, otherwise
//		we just throw the data away.
//	Once we've used the results, we assign the worker to
//		start computing another row.
//    
function processWork(worker, workerResults) {if (workerResults.generation == generation) {drawRow(workerResults);}reassignWorker(worker);
}//
// reassignWorker
//	This function gives an idle worker its next task.
//
function reassignWorker(worker) {var row = nextRow++;if (row >= canvas.height) {worker.idle = true;} else {var task = createTask(row);worker.idle = false;worker.postMessage(task);}
}// handleClick
//	This function takes the x, y position where the user
//		clicked and sets the parameters for the new
//		fractal. The zoom factor sets the new extent
//		of the bounds of the Mandelbrot set to the
//		zoomed in size. The new fractal maintains
//		the aspect ratio of the current canvas size.
//	We start the workers over on the new zoomed in
//		fractal.
//
function handleClick(x, y) {var width = r_max - r_min;var height = i_min - i_max;var click_r = r_min + ((width * x) / canvas.width);var click_i = i_max + ((height * y) / canvas.height);var zoom = 8;r_min = click_r - width/zoom;r_max = click_r + width/zoom;i_max = click_i - height/zoom;i_min = click_i + height/zoom;startWorkers();
}//
// resizeToWindow
//	When the user resizes the browser window,
//		this function is called to resize the canvas,
//		and reset the fractal parameters (changing the
//		extent of the boundary and maintaining the new
//		aspect ratio of the window).
//	We restart the workers to compute the new fractal
//		based on the new size.
//
function resizeToWindow() {canvas.width = window.innerWidth;canvas.height = window.innerHeight;var width = ((i_max - i_min) * canvas.width / canvas.height);var r_mid = (r_max + r_min) / 2;r_min = r_mid - width/2;r_max = r_mid + width/2;rowData = ctx.createImageData(canvas.width, 1);startWorkers();
}

 


http://chatgpt.dhexx.cn/article/fMRJYUlv.shtml

相关文章

神奇的分形图像(一)-Fractal Image-Mandelbrot And Julia

分析学原理不做过多阐述&#xff1a;这里以举例子的方式加以阐述&#xff0c;更能通俗的理解其概念。 分形几何学是一门以不规则几何形态为研究对象的几何学 从上图&#xff0c;你能很清晰的回答出它们是直线、矩形、长方体、维度分别是1、2、3维 但是如下图形呢我们通常引入…

先睹为快_Mandelbrot集

本文引用自作者编写的下述图书; 本文允许以个人学习、教学等目的引用、讲授或转载&#xff0c;但需要注明原作者"海洋饼干叔 叔"&#xff1b;本文不允许以纸质及电子出版为目的进行抄摘或改编。 1.《Python编程基础及应用》&#xff0c;陈波&#xff0c;刘慧君&#…

用Python画Mandelbrot集

Mandelbrot Set&#xff08;曼德勃罗集&#xff09;可能是分形 图形中最有名的图形&#xff0c;关于它的介绍我就不多写了&#xff0c;有兴趣的可以参考这个链接 。下面是关于如何使用Python来画这个图形的尝试。 由于Python标准库中还没有对图形处理的支持&#xff0c;在此我使…

Mandelbrot Set (曼德布洛特集) VC 源代码

关于 Mandelbrot Set (曼德布洛特集) 的介绍什么的我就不多说了&#xff0c;网上一大堆。唯独清晰的代码不好找&#xff0c;所以我就贴代码吧&#xff1a; // 需要安装 EasyX 库&#xff0c;Visual C 6.0 下编译通过 #include <graphics.h> #include <conio.h> / /…

Bellman-ford算法详解

什么是Bellman-ford算法 贝尔曼-福特算法&#xff08;Bellman-Ford&#xff09;是由理查德贝尔曼&#xff08;Richard Bellman&#xff09;和莱斯特福特创立的&#xff0c;求解单源最短路径问题的一种算法。其优于Dijkstra的方面是边的权值可以为负数、实现简单&#xff0c;缺…

分形(Fractal)及分形维数(Fractal dimension)

文章目录 1. 分形介绍2. 分形的定义3. 分形维数介绍4. 历史5. 缩放的作用&#xff08;Role of scaling&#xff09;6. D 不是唯一描述符7. 分形表面结构8. 例子8.8 Hausdorff dimension8.8.1 直观概念8.8.2 正式定义8.8.2.1 Hausdorff dimension8.8.2.2 Hausdorff content 8.8.…

Mandelbrot集的最新变化形态一览——MandelBox,Mandelbulb,Burning Ship,NebulaBrot

二维Mandelbrot集——Burning Ship 采用以下迭代公式 (x4-6*x2*y2y4, 4*|x|3*|y|-4*|y|3*|x|) 看不懂的&#xff0c;可以去学习深造了。。。 Mandelbulb 这个3D的Mandelbrot集采用的是以下公式&#xff0c;这应该算是超复数的一种&#xff0c;人称“triplex”&#xff0c;三…

Mandelbrot集Julia集分形的MATLAB实现(分形艺术)

Mandelbrot集Julia集分形的MATLAB实现&#xff08;分形艺术&#xff09; 1 简单Julia集的实现1.1 如何实现更光滑的展示效果&#xff1f; 2 Mandelbrot集的实现3 永恒的细节 本文首发于 matlab爱好者 微信公众号&#xff0c;欢迎关注。 惯例声明&#xff1a;本人没有相关的工程…

神奇的分形艺术: Mandelbrot集和Julia集

前言 这段时间看了一个关于维度的视频介绍&#xff0c;叹于其惊艳的多维几何体和分形的视觉动画效果。其实关于分形&#xff0c;已经有很成熟的分形软件和应用场景&#xff0c;可以参看目前流行的分形软件一览&#xff0c;不过没有及时更新&#xff0c;有些链接已经进不了&…

MATLAB | 分形的艺术——(Mandelbrot)曼德勃罗特集合

PART.0 Mandelbrot 介绍 “无规则的碎片” “魔鬼的聚合物” “上帝的指纹” Mandelbrot集合有着多种称谓&#xff0c;那么什么是曼德勃罗特集&#xff1f;Mandelbrot集合可以用复二次多项式&#xff1a; f c ( z ) z 2 c f_c(z)z^2c fc​(z)z2c 来表示&#xff0c;其中c是…

神奇的Python-实现曼德布洛特(Mandelbrot)集合(一行代码,matplotlib numpy,tensorflow)分别实现

神奇的Python-实现曼德布洛特(Mandelbrot)集合(一行代码&#xff0c;matplotlib numpy&#xff0c;tensorflow)分别实现 Mandelbrot图实际上是由Mandelbrot集合构成的图像。 Mandelbrot集合的定义如下&#xff1a; z n 1 z n 2 c z_{n1}z^2_nc zn1​zn2​c 其中&#xff…

曼德勃罗集(Mandelbrot Set)

先来膜拜一下大神&#xff01; 曼德勃罗(Benoit B. Mandelbrot)&#xff0c;数学家、经济学家&#xff0c;分形理论的创始人。1924年生于波兰华沙&#xff1b;1936年随全家移居法国巴黎&#xff0c;在那里经历了动荡的二战时期&#xff1b;1948年在帕萨迪纳获得航空硕士学位&am…

用matlab画Mandelbrot(曼德布罗特)图

Mandelbrot图实际上是由Mandelbrot集合构成的图像。 Mandelbrot集合的定义如下&#xff1a; zn1z2nc 其中&#xff0c;c是一个复数。加入给定一个复数 z0 &#xff0c;比如 z00 &#xff0c;那么这个递推式会生成一个序列&#xff1a; [z0,z1,z2,z3,...] 。如果这个序列收敛…

Mandelbrot 并行实现

最近要交并行计算的作业了,这周终于把作业写了个大概,这期间感觉学了不少东西,总结一下。 Mandelbrot Set 背景 前几天逛维基百科的时候看到了如下的消息:著名数学家、分形之父Benot B. Mandelbrot(中文名本华曼德博)美国时间10月15日辞世,享年85岁。 “1979年,在哈…

Mastering Qt 5 学习笔记-Mandelbrot

是一个 Mandelbrot 分形的多线程计算。 用户将看到分形&#xff0c;并能够在该窗口中平移和缩放。Mandelbrot 分形是一个处理复数 (a bi) 的数值集&#xff0c;该图像中的每个黑色像素都趋向于发散到一个无限值&#xff0c;&#xff0c;而绿色像素则有界于一个有限值。绿色像素…

Mandelbrot集合及其渲染

什么是Mandelbrot集合&#xff1f; Mandelbrot集合是在复数平面上组成分形的点的集合&#xff0c;它正是以数学家Mandelbrot命名。 Mandelbrot集合可以用复二次多项式\[ f_c(z)z^2c \] 来定义 其中c是一个复数。对于每一个c&#xff0c;从\(z 0\),开始对\(f_c(z)\)进行迭代。 …

分形之父 Mandelbrot

著名数学家&#xff0c;被誉为分形之父的Mandelbrot先生&#xff0c;美国时间10月15日在马萨诸塞州剑桥辞世&#xff0c;享年85岁。他用“美丽”改变了我们的世界观&#xff0c;他被认为是20世纪后半叶少有的影响深远而且广泛的科学伟人之一&#xff0c;1993年他获得沃尔夫物理…

Ettercap系列 II:基于命令行界面(结合driftnet截获目标机器正在浏览的图片)

相信跟着这个系列走&#xff0c;一直看到这篇文章的读者已经了解了基于图形化Ettercap的操作&#xff0c;并对Arp欺骗和Ettercap相关的术语有所了解。本篇就如何在命令行界面下操作ettercap&#xff0c;以实现与图形化界面相同的效果展开讨论。可能你会不解&#xff1a;既然我已…

无线局域网的嗅探攻击和防御——ettercap+driftnet

&#xfeff;&#xfeff; 无线局域网的嗅探攻击和防御 -----ettercapdriftnet 1 实验要求和目的 ●了解局域网转发数据的规则与协议 ●了解抓包软件的原理与操作流程 ●对网络中数据传输的协议有更深层次的认识 2 实验原理和背景知识 2.1 抓包软件与分析软件 本次嗅探试验所…

python实现图片嗅探工具——自编driftnet

python实现图片嗅探工具——自编driftnet 前言一、数据包嗅探二、图片捕获三、图片显示及主函数写在最后 前言 想必尝试过中间人攻击&#xff08;MITM)的小伙伴&#xff0c;大概率是知道driftnet的。这是一款简单使用的图片捕获工具&#xff0c;可以很方便的从网络数据包中抓取…