4
votes

I have a vector drawing app where users can draw lines using multiple quadratic bezier curves. A curve, for example, could have 5 points - points 0-2 for a quadratic bezier curve, and points 2-4 form another. If the slope @ the end of the first bezier curve doesn't equal the slope at the beginning of the 2nd bezier curve, the curve isn't smooth.

I want to include a "smooth" button, which users can click to smooth the lines automatically. I want to keep the overall MSE between original and smoothed curves small, as opposed to making the slopes match perfectly. However, 100% accuracy isn't necessary as it's a drawing program - speed is more important. Are there any good algorithms that can do this? I can't seem to find any references for this.

1
The answer doesn't really apply. Those solutions are more for fitting bezier curves to a set of raw points. I'm looking to smooth an already existing curve.Charles L.
I modified the answer to best match what you describe.AturSams

1 Answers

5
votes

If you want to maintain the overall shape of the line and make the corners round you could: Create new points around each corner :

for instance in the case you describe there will be one corner at P2

We could use any epsilon < 0.5 for this purpose Lets use 0.1 So we have P1.9, P2.1.

P1.9.x = (9 * P2.x + P1.x)/10
P1.9.y = (9 * P2.y + P1.y)/10

P2.1.x = (9 * P2.x + P3.x)/10
P2.1.y = (9 * P2.y + P3.y)/10

You could do:

Bezier(P0, P1, P1.9);
Bezier(P1.9, P2, P2.1);
Bezier(P2.1, P3, P4);

instead of doing:

Bezier(P0, P1, P2);
Bezier(P2, P3, P4);

I hope this new answer helps.. otherwise I would like to see an image describing the kind of line you have, and the result you would like to see.(this would help filter out answers that do not match the criteria)

Old answer: The users input 3 points for each bezier curve?

If you wish to make a smooth line you could do the following :

1.Create new interpolated points :

p0.5[x] = (p0[x] + p1[x]) / 2;
p0.5[y] = (p0[y] + p1[y]) / 2;

1.b do the same for p1.5, p2.5... where p(N.5) uses p(N) and p(N+1)

2.Instead of drawing:

Bezier(p0, p1, p2);
Bezier(p2, p3, p4);

Draw

Line(p0, 0.5);
Bezier(p0.5, p1, p1.5);
Bezier(p1.5, p2, p2.5);
Bezier(p2.5, p3, p3.5);
Line(p3.5, p4);

I hope this is easy to understand and helpful.