12

私は楽しい開発/数学の問題を抱えており、それを解決することができません。

下の図を参照してください。

最終結果

ドットの円が 2 つあります。小さいものと大きいもの。

したい:

  • 外側の円の任意の点から内側の円の任意の点まで線を引きます (完了)
  • 線は円弧である必要があり、内側の円の境界または外側の円の境界を越えてはなりません。(あなたの助けが必要です!)

フィドル!

RaphaelJS で書かれた jsFiddle を作成し、点を作成してその間に線を引きました。http://jsfiddle.net/KATT/xZVnx/9/を参照してください。

それは基本的にdrawLine、直線ではなく、素敵な弧を描くためにあなたの助けが必要な機能にあります。

ベクトルを操作するためのヘルパーもいくつか追加しました、 se MathHelpers.Vector

分岐を行って、線が の周りで曲がるソリューションを実装してみてください。実際に見栄えの良いベジエを使用したソリューションも高く評価されています。

そうですね、計算にはベクトル ジオメトリが最適だと思います。

どんな助けにもとても、とても、とても感謝しています。私はそれを解決するために多くの時間を費やしましたが、錆びた高校の数学のスキルだけでは十分ではありません.

4

4 に答える 4

2

らせんを区分的に描くことから始めます。

らせんの半径は開始角度から終了角度までで、らせんの半径は内側の円の半径から外側の円の半径までです。

私が何を意味するかを理解するために、ピースの数 (n) を選択してください。

var n = 20, // The number of lines in the spiral
    rStep = (outerRadius - innerRadius)/n, // the radius increase between points
    aStep = (outerAngle - innerAngle)/n,  // the angle change between points
    points = [];

// compute the cartesian coordinates (x, y) from polar coordinates (r, a)
function cartesian(r, a) {
    return [
        r * Math.cos(a),
        r * Math.sin(a)
    ];
}

for (i = 0; i <= n; i += 1) {
   points.push(cartesian(innerRadius + (i * rStep), innerAngle + (i * aStep));
}

極座標を使用して、基本的なピースワイズ スパイラルを示しました。

http://jsfiddle.net/xmDx8/

n を変更して、破片がどのように積み重なっていくかを確認してください。

drawLine(innerCircleIndex, outerCircleIndex, 1); // This is what you did

drawLine(innerCircleIndex, outerCircleIndex, 100); // 100 lines in the example

drawLine(innerCircleIndex, outerCircleIndex, n); // Choose n to see how it grows
于 2012-10-26T10:23:07.037 に答える
1

手の込んだ数学を本当に避けたい場合は、接続されている 2 点の座標と、原点に対するそれぞれの角度または原点の座標 (明らかに、一方から他方を推測できます)。内点の座標と相対角度を表す (ix,iy,i_angle) と、外点の座標と相対角度を表す (ox,oy,o_angle) を考えると、

        var generatePath = function( ix, iy, i_angle, ox, oy, o_angle )
        {
            var path = [ "M", ox, oy ];
            var slices = 100;

            var cur_angle = o_angle;
            var cur_r = cr_outer;
            var delta_r = ( cr_inner - cr_outer ) / slices;
            var delta_angle = ( i_angle - o_angle );
            if ( delta_angle > Math.PI )
                delta_angle -= Math.PI * 2;
            else if ( delta_angle < Math.PI * -1 )
                delta_angle += Math.PI * 2;
            delta_angle = delta_angle / slices;

            for ( var i = 0; i < slices; i++ )
            {
                cur_angle += delta_angle;
                cur_r += delta_r;
                path.push( "L", cx + Math.cos( cur_angle ) * cur_r, cy + Math.sin( cur_angle ) * cur_r );
            }
            return path;
        }

ロジックは非常に単純で、高解像度でも見栄えがよく、「本物の」円弧セグメントや一連の二次ベジエ曲線よりもパフォーマンスが高い可能性があります。セグメントごとのスライスの数は、おそらく長さとサイズに基づいて調整され、パフォーマンスと美学のバランスを取ることができます.

この関数を (コントロール ポイントの計算を使用して)ここにステージングしました。

于 2012-10-26T18:55:22.303 に答える
0

派手な数学なしでアプローチを試みる:

  • 接続するドットの中間にある外側のドットと内側のドットを見つけます。
  • これらの中間点で形成されたセグメントの中央を見つけます。

この点を通過する曲線を描きます。

于 2012-10-26T10:28:53.943 に答える