问题
I want to create a quadratic bezier curve from the two end points on a arc (x1, y1, x2, y2) and either the center point (cx,cy) or radius.
At one point, I thought that I could set the two control points to the intersection of the tangents, but that does not seem to work.
While an exact answer would be nice, I can live with a reasonable approximation if required. I have limited math skills but would appreciate simple pseudo code. I have done a google search and some of the suggestions are too complex for me to follow.
The problem seems simple but I know it is not.
回答1:
For a good approximation of a circle place the Bezier Quadratic control points at
var cp = (r * 4 * (Math.sqrt( 2 ) - 1)) / 3;
Where r
is the radius of the circle at point (x,y)
. cp
is the distance along the tangent to put the control point.
ctx.moveTo(x-r,y)
ctx.quadCurve(x - r, y - pc, x + r, y - pc, x + r, y);
Will create a nice half a circle. Do the same for the bottom to get a full circle.
回答2:
There is no perfect mapping between arcs and Bezier curves due to the fact that a circle has parametric function:
fx(t) = cos(t)
fy(t) = sin(t)
which can only be represented in polynomial form as infinite sequences:
fx(t) = ∑(k=0,inf) x^(2k) * (-1)^k / (2k)!
fy(t) = ∑(k=0,inf) x^(2k+1) * (-1)^k / (2k+1)!
Obviously, any finite degree Bezier curve will always be "off", although the higher the order, the less "off" we'll be. For a cubic curve we can approximate a quarter circle arc quite reasonably, although anything more than that and it'll look pretty obviously wrong: there's a detailed writeup on what a curve looks like given an arc of angle φ over on http://pomax.github.io/bezierinfo/#circles_cubic, and it's worth reading over that section and then implementing its explanation (or "borrowing" the code from github, it's public domain code), as well as playing with the graphic to see exactly how wrong things get once you try to model more than a quarter circle.
回答3:
Quadratic Bezier curve has equation
B(t) = P0 * (1-t)^2+ 2 * P1 * t * (1-t) + P2 * t^2
For your case
P0 = (x1,y1)
P2 = (x2,y2)
To approximate an arc with Bezier, we can declare that middle point of curve must coincide with middle point of arc.
To find middle point of arc:
We have chord vector
V = (x2-x1, y2-y1)
perpendicular vector (not y sign change)
P = (y1-y2, x2-x1)
It's length
LenP = Sqrt((y1-y2)^2 + (x2-x1)^2)
unit perpendicular vector
uP = P/LenP = ( (y1-y2) / LenP, (x2-x1) / LenP)
Middle arc point
M = C + R * uP = (cx + R * (y1-y2) / LenP, cy + R * (x2-x1) / LenP)
Middle point of Bezier
B(1/2) = P0/4 + P1/2 + P2/4 = (x1/4 + px/2 + x2/4, y1/4 + py/2 + y2/4)
Now we can write equations
cx + R * (y1-y2) / LenP = x1/4 + px/2 + x2/4
cy + R * (x2-x1) / LenP = y1/4 + py/2 + y2/4
and find px
and py
- coordinates of control point.
来源:https://stackoverflow.com/questions/34460465/create-a-bezier-curve-from-arc-in-javascript