zoukankan      html  css  js  c++  java
  • 【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/xiandedanteng/20180408_17guanglan.rar

    本作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>
  • 相关阅读:
    1、编写一个简单的C++程序
    96. Unique Binary Search Trees
    python 操作redis
    json.loads的一个很有意思的现象
    No changes detected
    leetcode 127 wordladder
    django uwsgi websocket踩坑
    you need to build uWSGI with SSL support to use the websocket handshake api function !!!
    pyinstaller 出现str error
    数据库的读现象
  • 原文地址:https://www.cnblogs.com/heyang78/p/8742899.html
Copyright © 2011-2022 走看看