Javascript在画布上绘制分形,递归保存和恢复问题

Posted

技术标签:

【中文标题】Javascript在画布上绘制分形,递归保存和恢复问题【英文标题】:Javascript drawing fractals on canvas, issue with recursive save and restore 【发布时间】:2018-02-20 08:40:02 【问题描述】:

我正在尝试在画布上绘制大约 8 个变换,我正在使用来自 "Sierpniski triangle" 的示例来绘制我自己的,但是每当我将步长增加到大于 1 时,我似乎都在挣扎。这是一个小提琴我要走了:Current code

如果您取消注释第 43 到 49 行,您会看到它是如何被破坏的,但是如果您将第 14 行中的步长减小为: 1. 然后您将获得关于它应该是什么样子的完美可视化。所以问题是我尝试了多种方法来保存画布并恢复它,但是我递归绘制的事实使事情中断了。

另一件事,如果您取消注释第 43 到 49 行以及第 40 行并保留步长: 2. 您几乎可以完美地可视化它应该是什么样子,但事实上,每行附近都有一个额外的翻转形状转型使其不“完美”。

我尝试过 html5 litten 论坛,W3S 学校,并在这里搜索过,但找不到类似的东西。

【问题讨论】:

将您的代码直接包含在问题中会很好。现在,我手头没有电脑可以为您提供更多帮助,但不要使用保存/恢复进行转换。而是使用 setTransform 方法重新/设置为绝对值。你会发现它更容易管理。经验法则:如果没有剪辑路径,不保存,如果剪辑路径,仔细检查合成不能做得更好。 嗯,如果我们放弃使用保存和恢复,这会不会让分形绘图变得太难? 所以我终于拿到了一台电脑,但没有太多时间来重构它......因为,我认为使用 @987654323 不会达到预期的结果@ 作为基础。此代码仅在最后的步骤中绘制,即仅绘制黑色小三角形,伪分形实际上是绘图中的孔。 那么指定的代码肯定是用来达到预期结果的基础,这是讲师最初提供的任务。形状被重构以匹配不同的插图Link here。它不应该是一个精确的表示,而是在形状/边界方面相似。 【参考方案1】:

我已经用下面的代码解决了这个问题:

<html>
<head>
	<script type="application/javascript">
	function draw(val=1) 
		var canvas = document.getElementById('canvas');
		if (canvas.getContext) 
			var ctx = canvas.getContext("2d");
			ctx.clearRect(0, 0, canvas.width, canvas.height);
			drawT(); //Trait around the canvas (black border)
			drawF(val); //draw Fractal
		
		function drawF(step,color=null)
		
			var toDraw=false; //Color management variable to separate 4 transformations
			if (step > 0)
			
				if(color)  toDraw=true; 
				step = step-1;
				ctx.save();
        
				ctx.transform(0.5, 0, 0, 0.5, 250,0);
				ctx.rotate(90*Math.PI/180);
				if(toDraw)  ctx.fillStyle=color; 
				else  ctx.fillStyle="#FF0000"; color="#FF0000"; 
	
				drawF(step, color);
				ctx.restore();

				ctx.save();
				ctx.transform(0.5, 0, 0, 0.5, 250, 0);
				ctx.scale(-1, 1);
				ctx.rotate(90*Math.PI/180);
				if(toDraw)  ctx.fillStyle=color; 
				else  ctx.fillStyle="#00FF00"; color="#00FF00"; 

				drawF(step, color);
				ctx.restore();
        
				ctx.save();
				ctx.transform(0.5, 0, 0, 0.5, 250, 250);
if(toDraw)  ctx.fillStyle=color; 
else  ctx.fillStyle="#0000FF"; color="#0000FF"; 
				
				drawF(step, color);
				ctx.restore();
				
				ctx.save();
				ctx.transform(0.2, 0, 0, 0.25, 250, 250);
				ctx.scale(1,1);
				ctx.rotate(90*Math.PI/180);
        if(toDraw)  ctx.fillStyle=color; 
        else  ctx.fillStyle="#FFFF00"; color="#FFFF00"; 
        
				drawF(step, color);
				ctx.restore();
			 else 
				drawShape();
			
		
		function drawT() 
			ctx.beginPath();
			ctx.moveTo(0, 0);
			ctx.lineTo(500,0);
			ctx.lineTo(500,500);
			ctx.lineTo(300,500);
			ctx.lineTo(300,400);
			ctx.lineTo(150,400);
			ctx.lineTo(150,250);
			ctx.lineTo(0, 250);
			ctx.closePath();
			ctx.stroke();
		

		function drawShape() 
			ctx.beginPath();
			ctx.moveTo(0,0);
			ctx.lineTo(500,0);
			ctx.lineTo(500,500);
			ctx.lineTo(300,500);
			ctx.lineTo(300,400);
			ctx.lineTo(150,400);
			ctx.lineTo(150,250);
			ctx.lineTo(0, 250);
			ctx.closePath();
			ctx.fill();
		
	
	function showVal(newVal)
		draw(newVal);
	
	</script>
</head>
	<body onload="draw();">
	   <canvas id="canvas"  ></canvas>
	</body>
	<input type="range" min="1" max="7" step="1" value="1"
	oninput="showVal(this.value)" onchange="showVal(this.value)">
</html>

使用滑块进行转换过程。

【讨论】:

以上是关于Javascript在画布上绘制分形,递归保存和恢复问题的主要内容,如果未能解决你的问题,请参考以下文章

视觉基础篇11 # 图案生成:如何生成重复图案分形图案以及随机效果?

无法在javascript中将图像绘制到画布

Javascript:在画布上绘制图像时,图像大小变为两倍

JavaScript图形实例:H分形

使用 JavaScript 在 HTML 画布上绘制螺旋

在画布上绘制背景图像并保存图像