Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

math - calculate a perpendicular offset from a diagonal line

I am writing a music display program and need to draw a 'slur' between two notes. A slur is a curved line linking two notes - just to be clear.

enter image description here

I know the note positions and calculate where the start and end points of the curve should be - Start point A and End point B.

I now need to obtain the offset C, given the distance required, for use within a quadratic curve. This is where my, very, limited knowledge and understanding of maths formulae comes in.

I have indeed looked here in SO for my answer, but the solutions proposed either do not work or I am too limited to code them correctly.

Can someone help me with the calculation, in a NON mathematical form ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Given the line segment AB, you can find the midpoint, say M, using the famous midpoint formula (A + B)/2. Now calculate the vector from B to A:

p = <p.x, p.y> = A ? B

Rotate it about the origin by 90° counter-clockwise to get the perpendicular vector

n = <n.x, n.y> = < ? p.y, p.x >

Normalise it:

n = <n.x, n.y> / ‖n‖ where ‖n‖ = √(n.x2 + n.y2) is the Euclidean Norm or length

C = L(t) = M + t n

Using this equation -- parametric form of a line -- you can find any number of points along the perpendicular line (in the direction of n). t is the distance of the obtained point, C, from M. When t = 0, you get M back, when t = 1, you get a point 1 unit away from M along n and so on. This also works for negative values of t, where the points obtained will be on the opposite side of AB i.e. towards the note. Since t can be a decimal number, you can play with it by changing its values to get the desired distance and direction of the obtained point from M.

Code, since you said you're not interested in the math jargon ;)

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

This is just pseudo code, since I'm not sure of the vector math library you are using for your project.

Boldface variables above are 2-d vectors; uppercase letters denote points and lowercase ones are vectors with no position


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...