2

ポイントのパスを定義しようとしています。各ポイントには、x、y、および時間が含まれます。次に、このパスを照会して、その時点での現在の位置を取得します。いくつかの疑似コードを共有しましょう。

point {x, y, time}


function initialisePath(point[] path) {
    ... // Create Bezier Path
}

function getXYAtTime(time) {
    return ... // Get interpolated point along the bezier path at the specified time
}

canvas タグを使用して JavaScript でこれを実装しようとしています。ただし、どの言語のサンプルでも構いません。この種のクエリ可能なパスを作成するオープンソース ライブラリ (任意の言語) を知っている人はいますか??

注: 私はこのサンプルとDynApi プロジェクトのコードについて理解を深めようとしましたが、このサンプルから時間を意識したパスに移行することは、私の貧弱なアニメーション スキルにとっては大変なことです。

ありがとう

グイド

4

2 に答える 2

6

ベジエ曲線には、開始点と終了点だけでなく、曲線の形状をガイドする制御点もありますリンクした DynApi デモでは、エンド ポイントは黄色でマークされ、コントロール ポイントは赤色でマークされます。

パスは、エンドツーエンドで接続された一連のベジエ曲線になります。

それでは、疑似コードを見てみましょう。ただし、.time プロパティを持たないすべてのポイントをコントロール ポイントとして扱います。

function Path(points) {
    this.points = points;

    // Sanity check.
    if (points[0].time == undefined || points[points.length - 1].time == undefined)
        throw new Error("all control points must be between two real points");
}

Path.prototype.getXYAtTime = function (t) {
    var points = this.points;

    // First, see if t is out of range.
    if (t < points[0].time)
        return points[0];
    if (t > points[points.length - 1].time)
        return points[points.length - 1];

    // OK, t is in range. Find out which Bezier curve we're in.
    //
    // Specifically we want 'start' and 'stop' to be the indexes of two points
    // that each have a .time property, bracketing the current time t; and
    // all the points in between 'start' and 'stop' should be control points.
    //
    var start = 0, stop = points.length - 1;
    for (var i = 1; i < points.length; i++) {
        var p = points[i];
        if (t < p.time) {
            stop = i;
            break;
        }
        if (p.time != undefined)
            start = i;
    }
    var n = stop - start;

    // Adjust t to be in the range [0, 1).
    var t0 = points[start].time, t1 = points[stop].time;
    t = (t - t0) / (t1 - t0);
    var tInv = 1 - t;

    // Now calculate the current position in the curve.
    // Wikipedia says this is:
    //   sum for i = 0 to n of (n C i * (1 - t) ^ (n - i) * t ^ i * P[i])
    // 
    var x = 0, y = 0;
    for (var i = 0; i <= n; i++) {
        var p = points[start + i];
        var c = nCr(n, i) * Math.pow(1 - t, n - i) * Math.pow(t, i);
        x += c * p.x;
        y += c * p.y;
    }
    return {x: x, y: y};
}

// The number of k-combinations of a set of size n.
function nCr(n, k) {
    var z = 1;
    for (var i = 1; i <= k; i++)
        z *= (n + 1 - i) / i;
    return z;
}

これで数学の部分は完了です。それをキャンバスに接続して実行するのはあなた次第です。

そのメソッドを呼び出す方法は次のとおりです。

// Here's a Path consisting of a single Bezier curve.
var path = new Path([
    {x: 200, y: 150, time: 0},  // start point
    {x: 200, y: 500},           // 2 control points
    {x: 250, y: 100},
    {x: 500, y: 300, time: 50}  // end point
  ]);

var p = path.getXYAtTime(2.718);
alert(p.x + ", " + p.y);
于 2009-11-20T05:40:57.960 に答える