4

私は現在、JavaScriptを使用してキャンバス上に標準の5点星を描画するためのソリューションに取り組んでいます。私は途中ですが、完全に理解することはできません。誰かが持っているかもしれないヒントやポインタをいただければ幸いです。

4

5 に答える 5

4

n ポイント スターの場合、ポイントは円の周りに均等に分散されます。最初の点が 0,r (上) にあり、円の中心が 0,0 であり、2π/(2n+1) だけ回転した一連の三角形から作成できると仮定します。

5 ポイント スター

回転関数を定義します。

function rotate2D(vecArr, byRads) {
    var mat = [ [Math.cos(byRads), -Math.sin(byRads)], 
                [Math.sin(byRads), Math.cos(byRads)] ];
    var result = [];
    for(var i=0; i < vecArr.length; ++i) {
        result[i] = [ mat[0][0]*vecArr[i][0] + mat[0][1]*vecArr[i][1],
                      mat[1][0]*vecArr[i][0] + mat[1][1]*vecArr[i][1] ];
    }
    return result;
}

n個の三角形を回転させて星を作る:

function generateStarTriangles(numPoints, r) {
    var triangleBase = r * Math.tan(Math.PI/numPoints);
    var triangle = [ [0,r], [triangleBase/2,0], [-triangleBase/2,0], [0,r] ];
    var result = [];
    for(var i = 0; i < numPoints; ++i) {
       result[i] = rotate2D(triangle, i*(2*Math.PI/numPoints));
    }
    return result;
}

指定された多角形の配列を描画する関数を定義します。

function drawObj(ctx, obj, offset, flipVert) {
   var sign=flipVert ? -1 : 1;
   for(var objIdx=0; objIdx < obj.length; ++objIdx) {
      var elem = obj[objIdx];
      ctx.moveTo(elem[0][0] + offset[0], sign*elem[0][1] + offset[1]);
      ctx.beginPath();
      for(var vert=1; vert < elem.length; ++vert) {
        ctx.lineTo(elem[vert][0] + offset[0], sign*elem[vert][1] + offset[1]);
      }
      ctx.fill();
   }
}

上記を使用して 5 ポイントの星を描きます。

var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext('2d');
var offset = [canvas.width/2, canvas.height/2];
ctx.fillStyle="#000000";
var penta = generateStarTriangles(5, 200);
drawObj(ctx, penta, offset, true);

ここで見るhttp://jsbin.com/oyonos/2/

于 2013-06-25T08:10:42.597 に答える
4

クリスが投稿したコードにいくつかの変更を加えたので、私にとってはうまくいくでしょう:

var alpha = (2 * Math.PI) / 10; 
var radius = 12;
var starXY = [100,100]

canvasCtx.beginPath();

for(var i = 11; i != 0; i--)
{
    var r = radius*(i % 2 + 1)/2;
    var omega = alpha * i;
    canvasCtx.lineTo((r * Math.sin(omega)) + starXY[0], (r * Math.cos(omega)) + starXY[1]);
}
canvasCtx.closePath();
canvasCtx.fillStyle = "#000";
canvasCtx.fill();

それが役に立てば幸い...

于 2013-06-24T15:34:29.360 に答える
1

内側のビットを描く必要があり、完全な円は 2 * PI ラジアンです。以下の例では、r は包囲円の半径です。以下のコードは、オープン ソース プロジェクト ( http://github.com/CIPowell/PhyloCanvas )からのものです。

var alpha = (2 * Math.PI) / 10; 
// works out the angle between each vertex (5 external + 5 internal = 10)
var r_point = r * 1.75; // r_point is the radius to the external point

for(var i = 11; i != 0; i--) // or i could = 10 and you could use closePath at the end
{
var ra = i % 2 == 1 ? rb: r;

var omega = alpha * i; //omega is the angle of the current point
    //cx and cy are the center point of the star.
node.canvas.lineTo(cx + (ra * Math.sin(omega)), cy + (ra * Math.cos(omega)));

}

//Store or fill.

注: これは、猫の皮を剥ぐ多くの方法の 1 つです。他の誰かが別の方法でそれを行うと確信しています。また、インクリメンタル ループではなくデクリメンタル ループの理由はパフォーマンスです。i != 0 は i < 10 よりも効率的であり、i-- は i++ よりも効率的です。しかし、パフォーマンスは私のコードにとって非常に重要ですが、あなたのコードにとってはそれほど重要ではないかもしれません.

于 2013-01-29T10:04:27.000 に答える