【问题标题】:JavaScript - Gap between triangles when wire-frame is removedJavaScript - 删除线框时三角形之间的间隙
【发布时间】:2017-08-31 08:51:22
【问题描述】:

我对 JavaScript 比较陌生,为了掌握它,我一直在研究 3D 引擎,但偶然发现了一些奇怪的东西。 当我在禁用线框的情况下渲染填充网格时,三角形之间会出现间隙。

这是一个例子:

// 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
{
	background-color: #ddd;
}
canvas 
{
  border:2px solid #000;
}
<canvas id="screen" width="200" height="150" ></canvas>
<canvas id="screen2" width="200" height="150"></canvas>

本质上,这两个多边形似乎没有正确连接。

  • 使线框与三角形颜色相同不是解决方案。我想在没有看到边缘的情况下应用纹理。
  • 绘制连通多边形不是解决方案,每个三角形都可能有自己的纹理变换。
  • 是否应该过度绘制三角形来填补空白?
  • 这是抗锯齿问题吗?

提前致谢。

上图:当线框被禁用时显示三角形之间的间隙

2017 年 4 月 9 日更新

我已经考虑了各种解决我的问题的方法,包括编写一个三角形例程。下图。但是,绘制两个三角形会大大降低我的 FPS。我需要一种更快的方法将像素放在画布上,但这是另一篇文章,因为它不在主题范围内。

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

【问题讨论】:

  • 感谢编辑,gman。我仍在弄清楚 StackOverflow 的工作原理。

标签: javascript canvas polygon wireframe


【解决方案1】:

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

我认为更理想的是膨胀 0.5 像素的代码,但是,该代码会稍微贵一些,因为它涉及计算矢量长度...

// 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)
{
	//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>

【讨论】:

  • 谢谢。我也想过这个。计算向量长度是没有问题的。引擎在内部使用矢量,因此将矢量投影到超出其大小的位置是没有问题的。虽然这是最后的手段。你会认为浏览器会有正确填充三角形的代码。
  • 我接受这个作为解决方案。您可以在我原来的问题的更新中看到我的推理。如果你有新的建议,我很想听听。谢谢。
猜你喜欢
  • 2017-12-16
  • 1970-01-01
  • 2019-06-06
  • 2022-01-10
  • 2020-03-14
  • 1970-01-01
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多