2

{x:10, y:20} と {x:100, y:40} があるとします。10,20 で始まり 100,40 で終わる線を描きたい場合は、次のようにします。

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

しかし、それらに線を引きたい場合はどうすればよいでしょうか? つまり、線は点間のスペースよりも長いですが、両方の点をまたいでいますか?

4

2 に答える 2

2

「逆」補間を使用できます。つまり、[0.0、1.0] の割合で線を補間する代わりに、負の値または値 > 1 を使用して、線の「外側」を取得できます。

このオンラインデモから:

ここに画像の説明を入力

コードは単純です。x と y のセットを使用し、それらをデルタで補間します。ここでは、0 と 1 の間の小数値で、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();
}
于 2013-08-07T22:02:19.363 に答える
0

いくつかの代替手段のいずれかを使用して、より長い線を描画します。

  1. 端点を取得するためにキャンバスの境界線と交差します
  2. 「より直交する」キャンバス境界線と交差します。つまり、x 差の絶対値が y 差の絶対値より小さい場合は、上下の境界線と交差し、それ以外の場合は垂直境界線と交差します。
  3. 差分ベクトルの固定された十分に大きな倍数で直線を延長します
  4. この拡張が固定された既知のサイズになるような差分ベクトルの倍数で線を拡張します

これらのうちどれが最も適切かは、アプリケーションによって異なります。最大キャンバス サイズまたは最小ポイント距離に依存できますか? そうでない場合は、交差点の代替案がより堅牢になり、2 番目の代替案の方が作業が少なくなります。

于 2013-08-07T21:46:04.910 に答える