14

細い線から始まり、最後まで徐々に広がる線を引こうとしています。半滑らかな曲線(いくつかの直線から合成)を描く必要があり、このタスクを解決する方法を見つけるのに問題があります。

このフィドルは私の問題を示しています:

http://jsfiddle.net/ZvuQG/1/

stroke()を呼び出すと、現在設定されているlineWidthを使用して行全体がストロークされます。私が最初に考えたのは、各線の部分を個別に描くことでしたが、もちろん、これにより、コーナーの線に目立ったギャップが残ります。

ここでの私の最善の選択肢は何ですか?角を正しくするためにポリゴン(台形)を描くことに頼るべきですか?

もっと簡単な方法はありますか?

(編集:実際に楕円やその他の基本的な形状を描画しようとしているのではなく、線の太さを使用して速度を表す数学関数をプロットしようとしていることに注意してください)

4

3 に答える 3

8

興味のある方のために、私の問題に対する 2 つの解決策を考え出しました。

最初のアイデアは、キャンバスを使用してきちんとした角度を描いて、実際に各点を角として描くことでした。デモは次の場所で見ることができます。

http://jsfiddle.net/7BkyK/2/

var ctx = document.getElementById('canvas1').getContext('2d');
var points = [null, null, null];

for(var i=0; i<24; i++)
{
    var width = 0.5 + i/2;

    var m = 200;

    var x = Math.cos(i/4) * 180;
    var y = Math.sin(i/4) * 140;

    points[0] = points[1];
    points[1] = points[2];
    points[2] = { X:x, Y:y};

    if(points[0] == null)
        continue;

    var px0 = (points[0].X + points[1].X) / 2;
    var py0 = (points[0].Y + points[1].Y) / 2;

    var px1 = (points[1].X + points[2].X) / 2;
    var py1 = (points[1].Y + points[2].Y) / 2;

    ctx.beginPath();
    ctx.lineWidth = width;
    ctx.strokeStyle = "rgba(0,0,0,0.5)";
    ctx.moveTo(m+px0,m+py0);
    ctx.lineTo(m+points[1].X,m+points[1].Y);
    ctx.lineTo(m+px1,m+py1);
    ctx.stroke();
}
​

Shmiddty によって提案された 2 番目のより優れた解決策は、ベジエ曲線を使用することです。これは優れたソリューションであることが証明されました。

http://jsfiddle.net/Ssrv9/1/

// 1.
// Varying line width, stroking each piece of line separately
var ctx = document.getElementById('canvas1').getContext('2d');
var points = [null, null, null, null];

for(var i=-1; i<25; i = i +1)
{
    var width = 0.5 + i/2;

    var m = 200;


    var x = Math.cos(i/4) * 180;
    var y = Math.sin(i/4) * 140;

    points[0] = points[1];
    points[1] = points[2];
    points[2] = { X:x, Y:y};

    if(points[0] == null)
        continue;


    var p0 = points[0];
    var p1 = points[1];
    var p2 = points[2];

    var x0 = (p0.X + p1.X) / 2;
    var y0 = (p0.Y + p1.Y) / 2;

    var x1 = (p1.X + p2.X) / 2;
    var y1 = (p1.Y + p2.Y) / 2;

    ctx.beginPath();
    ctx.lineWidth = width;
    ctx.strokeStyle = "black";

    ctx.moveTo(m+x0, m+y0);
    ctx.quadraticCurveTo(m+p1.X, m+p1.Y, m+x1, m+y1);
    ctx.stroke();
}

</p>

于 2012-10-19T13:59:06.477 に答える
0

これを解決する別の方法は、各プロット ポイントを速度によって決定される半径の円と見なすことです。

これらの円 (直線または曲線、任意の選択) のプロファイル エッジを結合するパスをプロットします。次に、最後にパスを埋めます。

これにより、プロットポイント「円」に近づくにつれて、滑らかな線が拡大および縮小するはずです。

于 2012-10-12T09:22:25.403 に答える