问题
I do have a bezier curve, and at a certain point, I want a second bezier curve "branching off" the first curve in a smooth manner. Together with calculating the intersection point (with a percentage following the Bezier curve), I need also the control point (the tangent and weight). The intersection point is calculated with the following piece of javascript:
getBezier = function getBez(percent,p1,cp1,cp2,p2) {
function b1(t) { return t*t*t }
function b2(t) { return 3*t*t*(1-t) }
function b3(t) { return 3*t*(1-t)*(1-t) }
function b4(t) { return (1-t)*(1-t)*(1-t) }
var pos = {x:0,y:0};
pos.x = p1.x*b1(percent) + cp1.x*b2(percent) + cp2.x*b3(percent) + p2.x*b4(percent);
pos.y = p1.y*b1(percent) + cp1.y*b2(percent) + cp2.y*b3(percent) + p2.y*b4(percent);
return pos;
}
(Non IE browsers can see it in action at http://www.iscriptdesign.com -> Tutorial -> Groups & Paths). All I need now is the controlpoint or (tangent and weight) for the branchpoint ( I don't have a clue where to start, and I hope somebody can point to some code, or mathematical equation, if possible as function from the same parameters as the getBezier function above).
回答1:
Found and implemented it: de-Casteljau
algorithm turned out to be the fastest implementable solution. It is currently present under:
iScriptDesign (Tutorial ->Spit Bezier).
回答2:
Example usage (I think, i need help from @drjerry)
I have a css3 timing function, this is called ease-in-out: cubic-bezier(.42,0,.58,1)
. Graphically this looks like: http://cubic-bezier.com/#.42,0,.58,1
I want to make a new timing function that is just the bottom half and then top half of this graph.
So the bottom half is ease-in
: cubic-bezier(.42,0,1,1)
. Graphically: http://cubic-bezier.com/#.42,0,1,1
And the top half is ease-out
: cubic-bezier(0,0,.58,1)
. Graphically: http://cubic-bezier.com/#0,0,.58,1
So now what confuses me is that according to the script at iScriptDesign it tells me they are different.
iScriptDeisgn says the starting half of ease-in-out
is (which is ease-in
) is: cubic-bezier(.21, 0, .355, .25)
. Graphically: http://cubic-bezier.com/#.21,0,.35,.25
iScriptDeisgn says the ending half of ease-in-out
is (which is ease-out
) is: cubic-bezier(.145, .25, .29, .5)
. Graphically: http://cubic-bezier.com/#.14,.25,.29,.5
Why is the ease-in
and ease-out
returned by the iScriptDesign split function different from the real ease-in
and real ease-out
? I don't get it.
Code for this example.
//////////////////START FROM ISCRIPTDESIGN
var splitBezier = function(array, perc) {
array.unshift({x:0, y:0});
var coll = [];
while (array.length > 0) {
for (var i = 0;i < array.length-1; i++) {
coll.unshift(array[i]);
array[i] = interpolate(array[i], array[i+1], perc);
}
coll.unshift(array.pop());
}
return {b1: [{x:coll[5].x, y:coll[5].y}, {x:coll[2].x, y:coll[2].y},{x:coll[0].x, y:coll[0].y}]
, b2: [{x:coll[1].x - coll[0].x,y:coll[1].y-coll[0].y}, {x:coll[3].x - coll[0].x,y:coll[3].y-coll[0].y}, {x:coll[6].x - coll[0].x,y:coll[6].y-coll[0].y}]};
}
var interpolate = function (p0, p1, percent) {
if (typeof percent === 'undefined') percent = 0.5;
return {x: p0.x + (p1.x - p0.x) * percent
, y: p0.y + (p1.y - p0.y) * percent};
}
//////////////////END FROM ISCRIPTDESIGN
var coord = function (x,y) {
if(!x) var x=0;
if(!y) var y=0;
return {x: x, y: y};
}
var easeInOut = [new coord(.42,0), new coord(.58,1), new coord(1,1)];
var split50percent = splitBezier(easeInOut.slice(), .5);
So split50percent
is set to:
({
b1: [{
x: 0.21,
y: 0
}, {
x: 0.355,
y: 0.25
}, {
x: 0.5,
y: 0.5
}],
b2: [{
x: 0.14500000000000002,
y: 0.25
}, {
x: 0.29000000000000004,
y: 0.5
}, {
x: 0.5,
y: 0.5
}]
})
Same thing with easeInOutSine
easeInOutSine
:.44,.05,.55,.95- REAL
easeInSine
:0.47, 0, 0.745, 0.715easeOutSine
:0.39, 0.575, 0.565, 1
- iScriptDesign
easeInSine
:.22,.03,.36,.26easeOutSine
:.14,.24,.28,.48
来源:https://stackoverflow.com/questions/3958257/how-to-calculate-control-points-on-a-bezier-curve