这不是HTML,CANVAS问题,而是更多的一般数学问题。我在这里发布它是因为它是使用CANVAS的原型,并且仍然是我认为有人可以回答的一般编程问题。这是基本的想法:我想画一条10像素厚的线,但我不想使用标准的lineTo并设置笔画宽度。我想实际使用beginPath和lineTo绘制线条的边框。原因是这实际上是AS3项目,使用这种方法可以让我们进行线条笔划和填充。所以旋转帆布和那种性质的东西是不可能的。我只需要弄清楚如何计算线的正确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>
答案 0 :(得分: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'矩形。
必须有更多优化的方法来做到这一点(毕竟,人们可以画一条只添加的线),这个很简单并且有效,这取决于你的速度要求。一旦配方工作,您也可以优化代码。
答案 1 :(得分: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>
答案 2 :(得分:0)
在文森特和Sirisian的答案给了我一些想法后,我最终把它排除在外。我非常感谢输入的人!基本上,这两个答案让我意识到我应该像矩形一样对待片段,我需要一些额外的坐标。如果有人感兴趣,我会把一个小伙子放在一起。