13

我正在编写一个音乐显示程序,需要在两个音符之间画一个“连线”。连线是连接两个音符的曲线——为了清楚起见。

在此处输入图像描述

我知道音符位置并计算曲线的起点和终点应该在哪里 - 起点A和终点B

给定所需的距离,我现在需要获得偏移量C,以便在二次曲线中使用。这就是我对数学公式的知识和理解非常有限的地方。

我确实在 SO 中查看了我的答案,但是提出的解决方案要么不起作用,要么我太有限而无法正确编码。

有人可以用非数学形式帮我计算吗?

4

3 回答 3

27

给定线段 AB,您可以使用著名的中点公式找到中点,例如M。(A + B)/2现在计算从BA的向量:

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的方向)找到任意数量的点。t是获得的点CM的距离。当 时t = 0,你得到M回来,当 时,你得到沿nt = 1距离M 1 个单位的点,依此类推。这也适用于 的负值,其中获得的点将位于 AB 的另一侧,即朝向音符。由于可以是十进制数,因此您可以通过更改其值来使用它,以获得从M获得的点的所需距离和方向。tt

代码,因为你说你对数学术语不感兴趣;)

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));
}

这只是伪代码,因为我不确定您用于项目的向量数学库。

上面的粗体变量是二维向量;大写字母表示点,小写字母表示没有位置的向量

于 2013-06-19T15:31:46.177 回答
3

我采用了 legends2k 出色的答案并在 Android 上转换为 Java。这可能会帮助某人节省一些时间。

private PointF getPerpendicularPoint(int startX, int startY, int stopX, int stopY, float distance)
{
    PointF M = new PointF((startX + stopX) / 2, (startY + stopY) / 2);
    PointF p = new PointF(startX - stopX, startY - stopY);
    PointF n = new PointF(-p.y, p.x);
    int norm_length = (int) Math.sqrt((n.x * n.x) + (n.y * n.y));
    n.x /= norm_length;
    n.y /= norm_length;
    return new PointF(M.x + (distance * n.x), M.y + (distance * n.y));
}
于 2015-03-30T00:00:10.577 回答
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 回答