13

私は音楽表示プログラムを書いていて、2 つの音符の間に「スラー」を描く必要があります。スラーは 2 つの音符を結ぶ曲線です。念のために言っておきます。

ここに画像の説明を入力

私は音符の位置を知っており、曲線の始点と終点がどこにあるべきかを計算します - 始点Aと終点B

2 次曲線内で使用するために、必要な距離を考慮して、オフセットCを取得する必要があります。ここで、数学の公式に関する私の非常に限られた知識と理解の出番です。

私は確かに私の答えをここで見ましたが、提案された解決策は機能しないか、正しくコーディングするにはあまりにも制限されています。

非数学的形式で、誰かが計算を手伝ってくれますか?

4

3 に答える 3

27

線分 AB が与えられると、有名な中点の公式 を使用して中点、たとえばM(A + B)/2を見つけることができます。BからAへのベクトルを計算します。

p = <px, py> = AB

原点を中心に反時計回りに 90° 回転させて垂直ベクトルを取得します。

n = <nx, ny> = < ‒ py, px >

それを正規化します。

n = <nx, ny> / ‖n‖ ここで、‖n‖ = √(n.x² + n.y²) はユークリッド ノルムまたは長さです。

C = L(t) = M + t n

この方程式 (線のパラメトリック形式) を使用すると、垂線に沿って ( nの方向に) 任意の数の点を見つけることができます。は、取得したポイントCのMからtの距離です。の場合、Mが返され、 の場合、 nに沿ってMから 1 単位離れた点が得られます。これは の負の値に対しても機能し、得られるポイントは AB の反対側、つまり音符の方向になります。は 10 進数になる可能性があるため、その値を変更してMから取得したポイントの目的の距離と方向を取得することで、それを操作できます。t = 0t = 1tt

コード、数学の専門用語には興味がないと言ったので ;)

vec2d calculate_perp_point(vec2d A, vec2d B, float distance)
{
   vec2d M = (A + B) / 2;
   vec2d p = A - B;
   vec2d n = (-p.y, p.x);
   int norm_length = sqrt((n.x * n.x) + (n.y * n.y));
   n.x /= norm_length;
   n.y /= norm_length;
   return (M + (distance * n));
}

プロジェクトで使用しているベクトル数学ライブラリがわからないため、これは単なる疑似コードです。

上記の太字の変数は 2 次元ベクトルです。大文字は点を表し、小文字は位置のないベクトルを表します

于 2013-06-19T15:31:46.177 に答える
2

そして、これがSwiftバージョンです:

func pointNormalToLine(startPoint: CGPoint, endPoint: CGPoint, distance: CGFloat) -> CGPoint {

    let midpoint = CGPoint(x: (startPoint.x + endPoint.x) / 2, y: (startPoint.y + endPoint.y) / 2)
    let p = CGPoint(x: startPoint.x - endPoint.x, y: startPoint.y - endPoint.y)
    var n = CGPoint(x: -p.y, y: p.x)
    let norm_length = sqrt((n.x * n.x) + (n.y * n.y))
    n.x /= norm_length
    n.y /= norm_length
    return CGPoint(x: midpoint.x + (distance * n.x), y: midpoint.y + (distance * n.y))
}
于 2016-06-20T23:15:40.287 に答える