I am using the code from the question here to create bezier curves (I didn't think it was necessary to repost the code here since I haven't made any significant changes to it yet).
I have a symmetric bezier curve (please see image) that I want to reduce till all points converge at the midpoint of the original curve. I would like to preserve it's symmetry while it moves. I would like achieve this using a float
slider (with values from 0 to 1) in editor mode.
Answer
Assuming you have a cubic Bezier curve type with control points a
, b
, c
, d
, and methods to evaluate, given a parameter 0 <= t <= 1
, both:
a position on the curve at
t
ie. \$\vec p = (1-t)^3 \vec a + 3 t (1-t)^2 \vec b + 3 t^2(1-t) \vec c + t^3 \vec d\$
the first derivative of that position with respect to the parameter
t
ie. \$\frac {\delta \vec p} {\delta t} = 3 (1-t)^2 (\vec b - \vec a) + 6 t (1-t) (\vec c - \vec b) + 3 t^2 (\vec d - \vec c)\$
Then we can choose new control points for an arbitrary interval start <= t <= end
on this curve like so:
static CubicBezier IntervalFromTo(CubicBezier curve, float start, float end) {
float scale = (end - start)/3f;
var a = curve.PositionAt(start);
var b = a + curve.DerivativeAt(start) * scale;
var d = curve.PositionAt(end);
var c = d - curve.DerivativeAt(end) * scale;
return new CubicBezier(a, b, c, d);
}
If you have a size
parameter that runs between 0
(just the midpoint) and 1
(the whole original curve), then you can compute your symmetrical subset as a special case:
subsetCurve = IntervalFromTo(originalCurve, 0.5f - 0.5f * size, 0.5f + 0.5f * size);
I recommend that you keep your originalCurve
unchanged throughout this manipulation, and make a fresh subsetCurve
from the original each time something changes, rather than overwriting your original with each change. Keeping this separation will ensure you don't get unwanted vibrations or degradation due to accumulating rounding errors.
No comments:
Post a Comment