2017-04-05 103 views
1

我对JavaScript比较陌生,想要掌握它我一直在研究3D引擎,并且偶然发现了一些奇怪的东西。 当我渲染一个禁用线框的填充网格时,我的三角形之间会出现间隙。JavaScript - 删除线框时三角形之间的差距

下面是一个例子:

// vertices 
 
var v1 = [40,20]; 
 
var v2 = [125,35]; 
 
var v3 = [165,105]; 
 
var v4 = [35,95]; 
 

 
// draw on screen 1 
 
var canvas = document.getElementById("screen"); 
 
var context = canvas.getContext("2d"); 
 
triangle(v1,v2,v3,context,true); 
 
triangle(v3,v4,v1,context,true); 
 

 
// draw on screen 2 
 
var canvas = document.getElementById("screen2"); 
 
var context = canvas.getContext("2d"); 
 
triangle(v1,v2,v3,context,false); 
 
triangle(v3,v4,v1,context,false); 
 

 
// draw triangle method 
 
function triangle(v1,v2,v3, context,wireframe) 
 
{ 
 
    context.beginPath(); 
 
    context.moveTo(v1[0],v1[1]); 
 
    context.lineTo(v2[0],v2[1]); 
 
    context.lineTo(v3[0],v3[1]); 
 
    context.lineTo(v1[0],v1[1]); 
 
    context.closePath(); 
 
    context.fillStyle = "#333"; 
 
    context.fill(); 
 
    if (wireframe) 
 
    { 
 
    context.strokeStyle = "#0f3"; 
 
    context.stroke(); 
 
    } 
 
}
body 
 
{ 
 
\t background-color: #ddd; 
 
} 
 
canvas 
 
{ 
 
    border:2px solid #000; 
 
}
<canvas id="screen" width="200" height="150" ></canvas> 
 
<canvas id="screen2" width="200" height="150"></canvas>

在本质上,这两个多边形似乎并不正确连接。

  • 使线框与三角形相同的颜色不是解决方案。我想应用纹理而不看边缘。
  • 绘制连接的多边形不是一个解决方案,每个三角形都可能有自己的纹理转换。
  • 我应该重叠三角形以缩小差距吗?
  • 这是一个反锯齿问题吗?

在此先感谢。

enter image description here 上图:显示三角形之间的差距时,线框已被禁用

UPDATE 9-APR-2017

我已经考虑了各种方案来解决我的问题,包括写三角形例程。下面的图片。然而,绘制两个三角形坦克我的FPS相当多。我需要一种更快的方式将像素放在画布上,但这是另一篇文章,因为它不在话题中。

但是,我认为扩大三角形半个像素是一个更好/更快的解决方案,因为fill()方法由浏览器在内部而不是JavaScript执行。

enter image description here

+0

谢谢为编辑,gman。我仍然在搞清楚StackOverflow是如何工作的。 – Miekpeeps

回答

1

一种解决方案是将三角形膨胀一点以填补空白。此代码膨胀1%。

我认为更理想的情况是代码0.5个像素膨胀,但是,该代码将是一个小更昂贵,因为它会涉及计算矢量lenghts ...

// vertices 
 
var v1 = [80,40]; 
 
var v2 = [250,70]; 
 
var v3 = [230,210]; 
 
var v4 = [70,190]; 
 

 
// draw on screen 1 
 
var canvas = document.getElementById("screen"); 
 
var context = canvas.getContext("2d"); 
 
triangle(v1,v2,v3,context,true); 
 
triangle(v3,v4,v1,context,true); 
 

 
// draw on screen 2 
 
var canvas = document.getElementById("screen2"); 
 
var context = canvas.getContext("2d"); 
 
inflateTriangle(v1,v2,v3,context,false); 
 
inflateTriangle(v3,v4,v1,context,false); 
 

 
// draw triangle method 
 
function inflateTriangle(v1,v2,v3, context,wireframe) 
 
{ 
 
\t //centre of tri 
 
    xc=(v1[0]+v2[0]+v3[0])/3; 
 
    yc=(v1[1]+v2[1]+v3[1])/3; 
 
    
 
    //inflate tri by 1% 
 
    x1= xc+(v1[0]-xc)*1.01; 
 
    x2= xc+(v2[0]-xc)*1.01; 
 
    x3= xc+(v3[0]-xc)*1.01; 
 
    y1= yc+(v1[1]-yc)*1.01; 
 
    y2= yc+(v2[1]-yc)*1.01; 
 
    y3= yc+(v3[1]-yc)*1.01; 
 
    
 

 

 
    context.beginPath(); 
 
    context.moveTo(x1,y1); 
 
    context.lineTo(x2,y2); 
 
    context.lineTo(x3,y3); 
 
    
 
    context.closePath(); 
 
    context.fillStyle = "#333"; 
 
    context.fill(); 
 
    if (wireframe) 
 
    { 
 
    context.strokeStyle = "#0f3"; 
 
    context.stroke(); 
 
    } 
 
}
<body> 
 

 
<canvas id="screen" width="400" height="300" style="border:2px solid #000;"></canvas> 
 
<canvas id="screen2" width="400" height="300" style="border:2px solid #000;"></canvas> 
 

 
</body>

+0

谢谢。我也考虑过这个问题。计算矢量长度是没有问题的。引擎在内部使用矢量,因此将矢量投影到幅度以外不成问题。这是最后的手段。你会认为浏览器会有适当填充三角形的代码。 – Miekpeeps

+0

我接受这个解决方案。你可以在我原来的问题更新中看到我的推理。如果你有新的建议,我很乐意听到他们。谢谢。 – Miekpeeps