{x:10, y:20} と {x:100, y:40} があるとします。10,20 で始まり 100,40 で終わる線を描きたい場合は、次のようにします。
context.beginPath();
context.moveTo(10, 20);
context.lineTo(100, 40);
context.stroke();
しかし、それらに線を引きたい場合はどうすればよいでしょうか? つまり、線は点間のスペースよりも長いですが、両方の点をまたいでいますか?
「逆」補間を使用できます。つまり、[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();
}
いくつかの代替手段のいずれかを使用して、より長い線を描画します。
これらのうちどれが最も適切かは、アプリケーションによって異なります。最大キャンバス サイズまたは最小ポイント距離に依存できますか? そうでない場合は、交差点の代替案がより堅牢になり、2 番目の代替案の方が作業が少なくなります。