2011-11-18 84 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/