5

画面上の2つの2D座標間でオブジェクトをアニメーション化するために線形補間を使用しています。これは私が望むものにかなり近いですが、丸みがあるため、ギザギザの動きになります。アスキーアートの場合:

ooo
  ooo
    ooo
      oo

45度回転するのではなく、マンハッタングリッドをどのように歩くかに注目してください。私が欲しいのは、ブレゼンハムのアルゴリズムが作成したであろう線に沿った線形補間です。

oo
  oo
    oo
      oo

xごとに、対応するyは1つだけです。(そしてx / yを急な線に交換します)

では、なぜブレゼンハムのアルゴリズムを使用しないのですか?確かに可能ですが、そのアルゴリズムは反復的であり、線に沿った1つの座標だけを知りたいです。

x座標を線形補間し、ピクセルグリッドに丸めて、対応するyを見つけることで、これを解決してみます。(繰り返しますが、x / yを急なラインに交換します)。しかし、その解決策がどのように機能したとしても、私は他の提案やおそらく以前の経験に興味があります。

4

3 に答える 3

6

ブレゼンハムの線のアルゴリズムは、通常のアプローチよりも少し速く完全な線を描くために導入されました。これには2つの大きな利点があります。

  • 整数変数で動作します
  • 完全な線を描くとき、​​それは繰り返し動作します、それは速いです

一部の座標のみを計算する場合、最初の利点はそれほど重要ではありません。2番目の利点は、一部の座標のみを計算する場合の欠点として判明します。したがって、結局のところ、ブレゼンハムのアルゴリズムを使用する必要はありません。

代わりに、同じ行になる別のアルゴリズムを使用できます。たとえば、DDA(デジタル微分解析機)。これは基本的に、あなたが言及したのと同じアプローチです。

最初のステップ:勾配を計算します。

m = (y_end - y_start) / (x_end - x_start)

2番目のステップ:反復ステップを計算します。これは単純です。

i = x - x_start

3番目のステップ:対応するy値を計算します。

y = y_start + i * m
  = y_start + (x - x_start) * (y_end - y_start) / (x_end - x_start)
于 2012-09-11T11:44:34.650 に答える
0

これが私が最終的に得た解決策です:

public static Vector2 BresenhamLerp(Vector2 a, Vector2 b, float percent)
{
    if (a.x == b.x || Math.Abs(a.x - b.x) < Math.Abs(a.y - b.y))
    {
        // Didn't do this part yet. Basically, we just need to recurse
        // with x/y swapped and swap result on return
    }

    Vector2 result;
    result.x = Math.Round((1-percent) * a.x + percent * b.x);

    float adjustedPercent = (result.x - a.x + 0.5f) / (b.x - a.x);
    result.y = Math.Round((1-adjustedPercent) * a.y + adjustedPercent * b.y);

    return result;
}
于 2012-09-11T11:43:19.647 に答える
0

これは私がちょうどうまくいくと思ったものです。おそらく最も美しい補間ではありませんが、1回の事前計算で、反復ごとに1〜2フロートを追加するだけです。マンハッタン行列のステップ数を計算することによって機能します。

ああ、そして線が垂直(dx = 0)の場合はまだケースをキャッチしていません

これは素朴なブレゼンハムですが、理論的には整数しか使用できません。フロートカラー値を削除したい場合は、線が色差よりも長くなる可能性があるため、状況が難しくなります。したがって、delta-color<1になります。

void Brepolate( uint8_t* pColorBuffer, uint8_t cs, float xs, float ys, float zs, uint8_t ce, float xe, float ye, float ze )
{
    float nColSteps = (xe - xs) + (ye - ys);
    float fColInc = ((float)cs - (float)ce) / nColSteps;
    float fCol = cs;

    float dx = xe - xs;
    float dy = ye - ys;

    float fCol = cs;

    if (dx > 0.5)
    {
        float de = fabs( dy / dx );
        float re = de - 0.5f;

        uint32_t iY = ys;
        uint32_t iX;

        for (   uint32_t    iX = xs;
                            iX <= xe;
                            iX++ )
        {
            uint32_t off = surf.Offset( iX, iY );
            pColorBuffer[off] = fCol;
            re += de;
            if (re >= 0.5f)
            {
                iY++;
                re -= 1.0f;
                fCol += fColInc;
            }
            fCol += fColInc;
        }
    }
}
于 2017-05-04T22:35:37.837 に答える