I'm relatively new to JavaScript and to get a grip on it I've been working on a 3D engine and I stumbled on something odd. When I render a filled mesh with wire-frame disabled, a gap shows up between my triangles.
Here's an example:
// 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>
In essence, the two polygons don't seem to connect properly.
Thanks in advance.
Above: Shows gap between triangles when the wire-frame has been disabled
UPDATE 9-apr-2017
I've considered various options to solve my issue, including writing a triangle routine. Picture down below. However, drawing two triangles tanks my FPS quite a lot. I need a faster way to put pixels on the canvas, but that's for another post since it's off topic.
However, I think that expanding the triangle half a pixel is a better/faster solution since the fill() method is executed by the browser internally instead of JavaScript.
One solution would be to inflate the triangles by a little bit to fill the gaps. This code inflates by 1%.
I think more ideal would be code that inflates by 0.5 pixels, however, that code would be a little more expensive as it would involve calculating vector 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)
{
//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>