create a bezier curve from arc in javascript

被刻印的时光 ゝ 提交于 2019-12-11 13:53:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!