【问题标题】:Scalable polygon grid using for loop使用 for 循环的可缩放多边形网格
【发布时间】:2013-08-20 00:27:28
【问题描述】:

我想创建一个交互式数字画布,它将在网格中生成一系列接近正方形的多边形。下面的 jsFiddle 显示了所述多边形的 2x2 网格系统。如果您检查代码或刷新页面,您会看到中心顶点是 4 个相邻多边形共享的半随机生成点。

我想将此网格缩放到 16x16 附近的大小,每个内部顶点都是半随机生成的,但在当前状态下,完成的代码效率低下、不灵活且不可扩展。我知道那里有一个相对简单的解决方案,但考虑到我对 for 循环和数组的经验不足,目前它超出了我的范围。非常感谢任何帮助。

http://jsfiddle.net/4Qbt2/

HTML:

<body>  
    <canvas id="myCanvas" width="200" height="200"></canvas>
</body>

JS:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

var randomX = Math.floor((Math.random()-0.5)*30);
var randomY = Math.floor((Math.random()-0.5)*30);

var x1 = canvas.width/2 + randomX;
var x2 = canvas.width;
var y1 = canvas.height/2 + randomY;
var y2 = canvas.height;


//background
context.beginPath();
context.rect(0,0,canvas.height,canvas.width);
context.fillStyle = '#A3DCEE';
context.fill();


//top left polygon
context.beginPath();
context.lineTo(0,0); //top left quadrant
context.lineTo(canvas.width/2,0); //top right quadrant
context.lineTo(x1, y1); //bottom right quadrant
context.lineTo(0, canvas.width/2); //bottom left quadrant

context.closePath();
context.fillStyle = '#ABE2EF';
context.fill();


//top right polygon
context.beginPath();
context.lineTo(x2/2,0); //top left quadrant
context.lineTo(x2,0); //top right quadrant
context.lineTo(x2, y2/2); //bottom right quadrant
context.lineTo(x1, y1); //bottom left quadrant

context.closePath();
context.fillStyle = '#A3DCEE';
context.fill();


//bottom left polygon
context.beginPath();
context.lineTo(0,y2/2); //top left quadrant
context.lineTo(x1,y1); //top right quadrant
context.lineTo(x2/2, y2); //bottom right quadrant
context.lineTo(0, y2); //bottom left quadrant

context.closePath();
context.fillStyle = '#8CD6F6';
context.fill();


//bottom right polygon
context.beginPath();
context.lineTo(x1,y1); //top left quadrant
context.lineTo(x2,y2/2); //top right quadrant
context.lineTo(x2, y2); //bottom right quadrant
context.lineTo(x2/2, y2); //bottom left quadrant

context.closePath();
context.fillStyle = '#85D2ED';
context.fill();

CSS:

html, body {
    background-color: #fff;
     width:  100%;
    height: 100%;
    margin: 0px;
    padding: 0px;
    position: relative;
    }

canvas {
    margin: auto;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
    }

【问题讨论】:

    标签: arrays html canvas for-loop polygon


    【解决方案1】:

    如何绘制带有略微随机偏移交点的网格

    将网格上的每个相交点视为圆的中心点。

    然后您可以使用随机半径和随机角度计算从该中心点的偏移量。

    这将随机偏移每个相交点。

    这是一个如何计算网格点的示例,该网格点偏离其“通常”位置 0-2.5 像素“摆动”:

      // make each grid cell's side 20px 
      // (you can alter this to fit your needs)
    
      var sideLength=20;
    
    
      // allow the point to wobble up to 2.5 pixels from its "usual" position
    
      var radius=2.5*Math.random();
    
    
      // allow that point to wobble at a random angle around its "usual" position
    
      var radianAngle=2*Math.PI*Math.random();
    
    
      // do the calculation of the new wobbled intersection point
      // the x & y are the cell's horizontal(x) and vertical(y) position on the grid
    
      var cx=x*sideLength+radius*Math.cos(radianAngle);
      var cy=y*sideLength+radius*Math.sin(radianAngle);
    

    这是示例代码和小提琴:http://jsfiddle.net/m1erickson/Wqhb9/

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    
    <style>
        body{ background-color: ivory; }
        #canvas{border:1px solid red;}
    </style>
    
    <script>
    $(function(){
    
        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
    
        // declare an array
        var points=new Array(17);
        for(var i=0;i<points.length;i++){
            points[i]=new Array(17);
        }
    
        var sideLength=20;
    
        // fill the array with 
        for(var y=0;y<17;y++){
            for(var x=0;x<17;x++){
                // create a random semi-offset grid point
                var radius=2.5*Math.random();
                var radianAngle=2*Math.PI*Math.random();
                var cx=x*sideLength+radius*Math.cos(radianAngle);
                var cy=y*sideLength+radius*Math.sin(radianAngle);
                // if this is a sidepoint, don't offset (sides are straight)
                if(x==0){cx=0;}
                if(y==0){cy=0;}
                if(x==16){cx=x*sideLength;}
                if(y==16){cy=y*sideLength;}
                // add this gridpoint to the points array
                points[x][y]={x:cx+10,y:cy+10};
            }
        }
    
        // stroke the 4 sides of each cell
        for(var y=0;y<16;y++){
            for(var x=0;x<16;x++){
                strokeCell(x,y);
            }
        }
    
        // draw the 4 sides of the cell
        function strokeCell(x,y){
            var pt0=points[x][y];
            var pt1=points[x+1][y];
            var pt2=points[x+1][y+1];
            var pt3=points[x][y+1];
    
            ctx.beginPath();
            ctx.moveTo(pt0.x,pt0.y);
            ctx.lineTo(pt1.x,pt1.y);
            ctx.lineTo(pt2.x,pt2.y);
            ctx.lineTo(pt3.x,pt3.y);
            ctx.closePath();
            ctx.stroke();
        }
    
    
    }); // end $(function(){});
    </script>
    
    </head>
    
    <body>
        <canvas id="canvas" width=400 height=400></canvas>
    </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 2017-01-14
      • 1970-01-01
      • 2011-01-02
      • 2023-02-17
      • 2012-08-10
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多