鉴于两点,我如何画一条线?

时间:2013-08-07 21:16:39

标签: math canvas vector line

假设我有{x:10,y:20}和{x:100,y:40},如果我想绘制一条从10,20开始到100,40结束的行,我会这样做:

 context.beginPath();
 context.moveTo(10, 20);
 context.lineTo(100, 40);
 context.stroke();

但如果我想通过它们划一条线,我该怎么办?那就是这条线比点之间的空间要长,但它跨越两个点?

2 个答案:

答案 0 :(得分:2)

您可以使用"反向"插值 - 我的意思是代替插入一个分数为[0.0,1.0]的行,你可以使用负值或值> 1获得"外部"这一行:

来自 this online demo

enter image description here

代码很简单,你使用x和y设置并用delta插值它们,这里是0到1之间的小数值,其中1是在其中一个点之外的双倍长度:

function extLine(x1, y1, x2, y2, delta) {

    var ox1 = x1 + (x2 - x1) * -delta,
        ox2 = x1 + (x2 - x1) * (1 + delta),
        oy1 = y1 + (y2 - y1) * -delta,
        oy2 = y1 + (y2 - y1) * (1 + delta);

    ctx.beginPath();
    ctx.moveTo(ox1, oy1);
    ctx.lineTo(ox2, oy2);

    /// for the demo a couple of markers for the original points        
    ctx.rect(x1 - 2, y1 - 2, 5, 5);
    ctx.rect(x2 - 2, y2 - 2, 5, 5);

    ctx.stroke();
}

您可以计算线条的长度,然后从该结果中获得一个分数,而不是分数作为增量,这样您就可以用像素数来扩展线条。

以下是您提供像素数的版本:

function extLine2(x1, y1, x2, y2, pixels) {

    /// calc fraction based on line length and added pixels        
    var xd = x2 - x1,
        yd = y2 - y1,
        len = Math.sqrt(xd * xd + yd * yd),
        delta = pixels / len,

        /// as before
        ox1 = x1 + (x2 - x1) * -delta,
        ox2 = x1 + (x2 - x1) * (1 + delta),
        oy1 = y1 + (y2 - y1) * -delta,
        oy2 = y1 + (y2 - y1) * (1 + delta);

    ctx.beginPath();
    ctx.moveTo(ox1, oy1);
    ctx.lineTo(ox2, oy2);

    ctx.rect(x1 - 2, y1 - 2, 5, 5);
    ctx.rect(x2 - 2, y2 - 2, 5, 5);

    ctx.stroke();
}

答案 1 :(得分:0)

使用以下几种选择之一绘制更长的行:

  1. 将线与画布的边界相交以获取端点
  2. 将线与“更正交”的画布边界相交,即如果x差的绝对值小于y差的绝对值,则与底部和顶部边界相交,否则与垂直边界线相交
  3. 通过差矢量
  4. 的固定且足够大的倍数来延伸线
  5. 通过此扩展名为固定且已知大小
  6. 的差异向量的倍数来扩展该行

    哪一项最合适取决于您的申请。你能依靠最大画布尺寸或最小点距离吗?如果没有,则交叉路口选择更加稳健,第二个路线更少工作。