2014-09-23 18 views
1

该程序运行。但是,正如你所看到的那样,当广场翻转时,看到有一个神器。矩阵值必须被表示,并且这个表示也应该根据角度来看。有什么办法可以实现良好的可视化。为什么这发生在我的代码中?html5画布中的图形:奇怪和不期望的光学效果

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

    var x=100; 
    var y=100; 
    var width=200; 
    var height=200; 
    var radianAngle=0; 


    Rotar(); 


    var array = new Array2D(200,200); 


    function Array2D(NumOfRows,NumOfCols) 
    { 
    var k=new Array(NumOfRows); 
    for (i = 0; i < k.length; ++i) 
    k[i] = new Array(NumOfCols); 
    return k; 
    } 

    function Rotar(){ 
    //Borramos 
    ctx.clearRect(0,0,canvas.width,canvas.height); 
    //Salvamos el estado 
    ctx.save(); 
    // Transladamos su centro de gravedad 
    ctx.translate(x+width/2,y+height/2); 
    //Otra mⳍ 
    ctx.rotate(radianAngle);  



    var array = new Array2D(200,200); 
    for(i=0; i<200; i++) 
    { 
     for(j=0;j<200; j++) 
     { 
     array[i][j]=i+j; 
     var r,g,b; 
     r = array[i][j]; 
     g=50; 
     b=50; 
     //La parte de dibujo 
     ctx.fillStyle = "rgba("+r+","+g+","+b+",100)"; 
     ctx.fillRect(i, j, 1, 1); 



    } 
    } 

    ctx.restore();  
     } 

    $("#test").click(function(){ 

    radianAngle+=Math.PI/60; 


    // call rotateSquare 
    Rotar(); 
}); 
body { 
      background: #dddddd; 
     } 

     #canvas { 
      background: #eeeeee; 
      border: thin solid #aaaaaa; 
     } 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<canvas id="canvas" height="500" width="500"></canvas> 
<button id="test">Rotate</button><br> 

ROTAR(); });

+0

任何人都知道如何解决这个神器? – heptagono 2014-09-24 13:22:25

+0

你能从所有评论的东西中清除你的代码并直接指向这一点吗?谢谢。 – GameAlchemist 2014-09-25 01:23:36

回答

2

这是一个典型的取整问题:旋转上下文,然后在[0,199]中迭代(x,y)。但是在绘制小的一个像素宽的矩形时,它们不能完美地适合一个像素,所以渲染器必须在多个实际设备像素上“扩散”颜色,并且由于r,g,b仅为舍入误差存储在8位上。再加上这个小矩形的坐标上的错误 - 它将被光栅化到最多4个像素,并且你有你正在拼的栅格。

当做这样的转换时,规则是栅格化:迭代目标的像素,并找到它们源于源的位置,而不是相反。
所以一个简单的方法:找到旋转矩形的边界框,在这个BBox中迭代,如果一个点在矩形中计算它的颜色。
或建立栅格化矩形的算法(最简单的办法是使用三角形,在这里看到一个三角形光栅我打了一个例子:http://jsfiddle.net/gamealchemist/5cnkr2s5/

可是......你绘制这里什么最简单更快的方法是构建一个线性渐变,将其用作fillStyle,然后在单个fillRect调用中绘制整个矩形。换句话说:让画布(以及幕后的GPU)为你做数学。

var grad = ctx.createLinearGradient(0,0,200,200); 
grad.addColorStop(0,'#000'); 
grad.addColorStop(1,'#F00'); 
ctx.fillStyle = grad; 

// 
ctx.save(); 
ctx.clearRect(...); 
ctx.translate (the upper left point) ; 
ctx.rotate (some angle); 
ctx.fillRect(0, 0, 200, 200); 
ctx.restore(); 

最简单的例子在这里(点击“跑”了几次,角是随机的):

http://jsfiddle.net/gamealchemist/j57msxr5/11/

(RQ:您可以使用context2D通过的加快的想法比较我上面提到的三角形光栅化与context2D完成的相同工作:http://jsfiddle.net/gamealchemist/zch3gdrx/