2011-11-18 83 views
2

這是更小的HTML,帆布問題並且更一般的數學問題。我在這裏發佈它是因爲它使用CANVAS原型,並且仍然是我認爲有人可以回答的一般編程問題。這裏是基本的想法:我想繪製一個10像素厚的線,但我不想使用標準lineTo並設置筆觸寬度。我想要使​​用beginPath和lineTo實際繪製線條的邊框。原因在於,這實際上是針對AS3項目的,並且使用這種方法可以讓我們有一個行筆劃和填充。所以旋轉畫布和那種性質的東西是不可能的。我只需要弄清楚如何計算線的正確的x,y座標。計算的x,旋轉線段的y座標繪製在畫布

在下面的代碼爲線的頂部座標。我基本上想要取這個座標,每個座標增加10到y軸,這將給我這條線的底部的返回座標。當然,線條的每一部分都是旋轉的,因此計算線條底部的座標已證明非常棘手。我希望有人能幫忙。

一旦運行示例代碼,這個問題應該是顯而易見的。該行不正確。對於相對較小的線段旋轉,似乎可行,但隨着旋轉角度變得更加嚴重,x,y座標計算不正確。

<!doctype html> 
<html> 
<body> 
<canvas id="canvas" width="800" height="600"> 
</canvas> 
<script type="text/javascript"> 
var coords = [ 
    {x:78,y:183}, 
    {x:130,y:183}, 
    {x:237,y:212}, 
    {x:450,y:213}, 
    {x:517,y:25}, 
    {x:664,y:212}, 
    {x:716,y:212} 
]; 

var coordsBck = []; 

for(i = 0; i < coords.length; i++) { 
    var c1, c2, r; 
    c1 = coords[i]; 

    if(i < coords.length - 1) { 
     c2 = coords[i + 1]; 
     r = Math.atan2((c2.y - c1.y),(c2.x - c1.x)); 
     console.log(c1.x, c1.y, c2.x, c2.y, (r * 180/Math.PI)); 
    } 
    else 
    { 
     r = 00; 
    } 
    var d = r * 180/Math.PI;  
    var cos = Math.cos(r); 
    var sin = Math.sin(r); 

    var x = cos * 0 - sin * 10; 
    var y = sin * 0 + cos * 10; 
    coordsBck.push({x: c1.x + x, y: c1.y + y}); 
} 

while(coordsBck.length > 0) 
{ 
    coords.push(coordsBck.pop()); 
} 

var ctx = document.getElementById("canvas").getContext("2d"); 
ctx.beginPath(); 
for(i = 0; i < coords.length; i++) { 
    var line = coords[i]; 
    console.log(i, line.x, line.y); 
    if(i == 0) 
    { 
     ctx.moveTo(line.x, line.y); 
    } 
    else 
    { 
     ctx.lineTo(line.x, line.y); 
    } 
} 
ctx.fill(); 

function t(o) { 
    return "x: " + o.x + ", y: " + o.y; 
} 
</script> 
</body> 
</html> 

回答

1

如果您不需要端蓋。 http://jsfiddle.net/xA6kB/1/

<doctype !html> 
<html> 
<body> 
<canvas id="canvas" width="800" height="600"> 
</canvas> 
<script type="text/javascript"> 
var points = 
[ 
    {x: 78, y: 183}, 
    {x: 130, y: 183}, 
    {x: 237, y: 212}, 
    {x: 450, y: 213}, 
    {x: 517, y: 25}, 
    {x: 664, y: 212}, 
    {x: 716, y: 212} 
]; 

var quads = []; 
var lineThickness = 10; 

// Remove the -1 to create a loop 
for (var i = 0; i < points.length - 1; ++i) 
{ 
    var point = points[i]; 
    var nextPoint = points[(i + 1) % points.length]; 
    // Right hand normal with x positive to the right and y positive down 
    var normal = {x: -(nextPoint.y - point.y), y: nextPoint.x - point.x}; 
    // Normalize normal 
    var normalLength = Math.sqrt(normal.x * normal.x + normal.y * normal.y); 
    normal.x /= normalLength; 
    normal.y /= normalLength; 

    // A quad has 4 points 
    quads.push({x: point.x - lineThickness/2 * normal.x, y: point.y - lineThickness/2 * normal.y}); 
    quads.push({x: nextPoint.x - lineThickness/2 * normal.x, y: nextPoint.y - lineThickness/2 * normal.y}); 
    quads.push({x: nextPoint.x + lineThickness/2 * normal.x, y: nextPoint.y + lineThickness/2 * normal.y}); 
    quads.push({x: point.x + lineThickness/2 * normal.x, y: point.y + lineThickness/2 * normal.y}); 
} 

var context = document.getElementById("canvas").getContext("2d"); 

context.beginPath(); 
for(var i = 0; i < quads.length; i += 4) 
{ 
    context.moveTo(quads[i].x, quads[i].y); 
    context.lineTo(quads[i + 1].x, quads[i + 1].y); 
    context.lineTo(quads[i + 2].x, quads[i + 2].y); 
    context.lineTo(quads[i + 3].x, quads[i + 3].y); 
} 
context.fill(); 
</script> 
</body> 
</html> 
+0

我的確需要端蓋,但是看着你的答案被讓我幫了我不少意識到我需要把線段更有點像長方形,這有助於確定我最終需要的附加座標。所以謝謝。:) – WesleyJohnson

+0

我沒有最終使用這個,但它確實幫助我到達我需要的地方,所以我選擇這個作爲答案。爲了看看我想出了什麼,我在下面回答了我自己的問題。或者你可以查看jsfiddle:http://jsfiddle.net/WesleyJohnson/sAaM9/1/ – WesleyJohnson

+0

ho,並且由於我正在研究那些時間,你想知道如何做一個光滑的關節?因爲你可能已經注意到兩個沒有相同斜率的線段有一個可怕的關節,只有矩形圖(PS1的樣子是=)) – GameAlchemist

1

當我有這樣的問題時,我通常會計算歸一化向量,並與他們「玩」。 假設你畫一條從A到B的線,計算AB向量(ABx = Bx-Ax; ABy = By-Ay),然後我將它歸一化(...)得到ABN。

然後我計算ABNR,ABN的90度旋轉(ABNR.x = -ABN.y; ABNR.y = ABN.x)

在你的例子

然後,說A」和A '' 是在A周圍的點,我們有簡單的A'= A + 5 * ABNR和A''= A-5 * ABNR,以及B'= B + 5 * ABNR和B「= B-5 * ABNR。 要繪製的矩形是A'A''B''B'矩形。

必須有更優化的方式來做到這一點(畢竟,一個可以借鑑,只有增加一條線),這是一個簡單的作品,這取決於你的速度rquirements。一旦你的配方工作,你也可以優化代碼。

+0

我明白了嗎? – GameAlchemist

+0

嗨文森特!我很感謝你的回答,並且我很瞭解你在做什麼,但是數學有點超出我的想象。我認爲西里西亞人基本上做了你暗示的事情,但他實際上寫了代碼。用你的答案來解釋這個概念,並把他的答案寫出來,這對我幫助很大。謝謝! – WesleyJohnson

+1

太糟糕了,我無法畫畫,因爲繪畫太明顯了。 很高興我能幫助反正:=) – GameAlchemist

0

我結束了整理了這一點後,文森特和Sirisian的回答給了我一些想法。我真的很感謝輸入的人!基本上,這兩個答案讓我意識到我應該把這些片段看成矩形,並且我需要一些額外的座標。如果有人對此感興趣,我會拼湊一個jsfiddle。

http://jsfiddle.net/WesleyJohnson/sAaM9/1/