2017-04-05 82 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