【Canvas】动态正17边光阑 向高斯致敬
【背景知识】
公元前三世纪,欧几里得在《几何原本》中记载了正方形,正五边形,正六边形的做法,后来人们也掌握了正十五边形作图,但之后两千多年,人们没有在更高阶边形上取得突破。
1796年,19岁的高斯证明了正17边形可以由尺规作图作出,但没有给出具体做法;
1825年Johanes Erchinger发表了第一个正十七边形尺规作图法;
1898年,高斯的孙子发现了高斯在1796年3月30日关于正17边形作图的手稿,可以推断,高斯至少在当时在草稿纸上完成了作图分析过程。
1832年,里奇罗特发表了正257边形尺规作图法,手稿长达80页。
1894年,德国数学家Johann Gustav Hermes发表了正65537边形尺规作图法,这是目前人类最复杂的尺规作图,手稿保存在德国哥廷根大学。
我用canvas制作了正十七边形光阑,此种类型光阑多用于显微镜采光口。借此向伟大数学家高斯致敬。
代码没有经过大改变,只是在 http://www.cnblogs.com/xiandedanteng/p/8735444.html 的基础上把angleCount改成了17,另外优化了getColor函数。
效果见下面五个图形,想看动画效果请自行下载代码然后用chrome浏览器打开。或者从 https://files.cnblogs.com/files/xiandedanteng/17%E5%85%89%E9%98%91.rar 下载录像观看。
代码下载地址:https://files.cnblogs.com/files/heyang78/iris-aperture-master.zip
本作Github url:https://github.com/horn19782016/iris-aperture
代码如下:
<!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <head> <title>17角光阑 2018年4月8日 向高斯致敬</title> </head> <body onload="draw()"> <canvas id="myCanvus" width="400px" height="400px" style="border:1px dashed black;"> 出现文字表示你的浏览器不支持HTML5 </canvas> </body> </html> <script type="text/javascript"> <!-- function draw(){ var canvas=document.getElementById('myCanvus'); canvas.width=400; canvas.height=400; context=canvas.getContext('2d'); context.translate(200,200); slot=new Slot(); animate(); }; var delta=0; // 旋转角 var radius=0; // 旋转半径 var outerRad=200;// 外径 var context; // 绘画上下文 var slot; // 光阑对象 var angleCount=17;// 三角光阑为3,四角光阑为4,六角光阑为6 function animate(){ context.clearRect(-200,-200,400,400);// 清屏 slot.update(radius,delta,outerRad); slot.paintBg(context); slot.paint(context); slot.paintBase(context); delta+=0.5; radius+=1; if(radius<outerRad*0.9){ window.requestAnimationFrame(animate);// 让浏览器自行决定帧速率 } } function Slot(){ var obj=new Object; obj.ax=0; obj.ay=0; obj.bx=0; obj.by=0; obj.cx=0; obj.cy=0; obj.angleA=0; obj.angleB=0; obj.angleC=0; obj.radius=0; obj.outerRad=0; obj.img=new Image(); obj.img.src="earth.jpg"; // 计算 obj.update=function(radius,theta,outerRad){ this.radius=radius; this.outerRad=outerRad; var alpha=Math.acos(radius/outerRad); this.angleA=getRad(theta)+alpha; this.ax=outerRad*Math.cos(this.angleA); this.ay=outerRad*Math.sin(this.angleA); var R=radius/Math.cos(Math.PI/angleCount); this.angleB=getRad(theta)-Math.PI/angleCount; this.bx=R*Math.cos(this.angleB); this.by=R*Math.sin(this.angleB); this.angleC=this.angleA-2*Math.PI/angleCount; this.cx=outerRad*Math.cos(this.angleC); this.cy=outerRad*Math.sin(this.angleC); }; // 画背景 obj.paintBg=function(ctx){ context.drawImage(this.img,0,0,800,800,-200,-200,400,400); }; // 描光阑 obj.paint=function(ctx){ for(var i=0;i<angleCount;i++){ ctx.save(); ctx.fillStyle = getColor(i % 9); ctx.rotate(2*Math.PI/angleCount*i); ctx.beginPath(); ctx.moveTo(this.ax,this.ay); ctx.lineTo(this.bx,this.by); ctx.lineTo(this.cx,this.cy); ctx.arc(0,0,this.outerRad,this.angleC,this.angleA,false); ctx.closePath(); ctx.fill(); ctx.restore(); } }; // 描基座 obj.paintBase=function(ctx){ ctx.strokeStyle = "black"; for(var i=0;i<4;i++){ ctx.save(); ctx.fillStyle = getColor(13); ctx.rotate(Math.PI/2*i); ctx.beginPath(); ctx.arc(0,0,this.outerRad,0,Math.PI/2,false); ctx.lineTo(this.outerRad,this.outerRad); ctx.lineTo(this.outerRad,0); ctx.closePath(); ctx.fill(); ctx.restore(); } }; return obj; } // 角度得到弧度 function getRad(degree){ return degree/180*Math.PI; } // 得到颜色 function getColor(index){ var arr=["green","silver","lime","gray", "white","yellow","maroon","navy", "red","blue","purple","teal","fuchsia", "aqua","black"]; if(index>arr.length){ index=index % arr.length; } return arr[index]; } //--> </script>