Sorry for my paint:
I want change bezier curve's endpoint
start from s point with control points(c1, c2) to end point
when point arrive at changepoint(pink), I want change endpoint and
get the new path for new endpoint smoothly
How ? help me..
Sorry for my paint:
I want change bezier curve's endpoint
start from s point with control points(c1, c2) to end point
when point arrive at changepoint(pink), I want change endpoint and
get the new path for new endpoint smoothly
How ? help me..
I dont understand your question but I have crated a simpl program which will let u understand bezier curves.
<html>
<head>
<title>A simple tool</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.controlButton {
border: 0;
background: #000;
border-radius: 10px;
outline: 0;
position: absolute;
margin: 1px;
font-family: monospace;
color: #fff;
}
#mainCanvas {
background: #FFF;
}
#output {
position: absolute;
top: 0;
left: 0;
background: #000;
color: #fff;
padding: 2px 7px;
border-radius: 10px;
font-family: Monospace;
}
</style>
</head>
<body>
<div class="controlWrapper">
<button class="controlButton" onclick="activePoint='sp'" id="sp">Start Point</button>
<button class="controlButton" onclick="activePoint='cp1'" id="cp1">Control Point 1</button>
<button class="controlButton" onclick="activePoint='cp2'" id="cp2">Control Point 2</button>
<button class="controlButton" onclick="activePoint='ep'" id="ep">End Point</button>
</div>
<canvas id="mainCanvas"></canvas>
<div id="output"></div>
<script type="text/javascript">
var canvas = document.getElementById("mainCanvas");
var ctx = canvas.getContext("2d");
var width = canvas.width = innerWidth;
var height = canvas.height = innerHeight;
var activeCurve = {
sp: { x: width/2, y: height/2 },
cp1: { x: width/2+50, y: height/2+100 },
cp2: { x: width/2+200, y: height/2+100 },
ep: { x: width/2+200, y: height/2+50 }
};
var activePoint = "";
addEventListener("mousemove", function(e) {
switch(activePoint) {
case "sp":
activeCurve.sp.x = e.clientX;
activeCurve.sp.y = e.clientY;
break;
case "cp1":
activeCurve.cp1.x = e.clientX;
activeCurve.cp1.y = e.clientY;
break;
case "cp2":
activeCurve.cp2.x = e.clientX;
activeCurve.cp2.y = e.clientY;
break;
case "ep":
activeCurve.ep.x = e.clientX;
activeCurve.ep.y = e.clientY;
break;
}
});
addEventListener("click", function() {
activePoint = "";
}, true)
function draw() {
var sp = document.getElementById("sp");
sp.style.top = activeCurve.sp.y + "px";
sp.style.left = activeCurve.sp.x + "px";
var cp1 = document.getElementById("cp1");
cp1.style.top = activeCurve.cp1.y + "px";
cp1.style.left = activeCurve.cp1.x + "px";
var cp2 = document.getElementById("cp2");
cp2.style.top = activeCurve.cp2.y + "px";
cp2.style.left = activeCurve.cp2.x + "px";
var ep = document.getElementById("ep");
ep.style.top = activeCurve.ep.y + "px";
ep.style.left = activeCurve.ep.x + "px";
var o = document.getElementById("output");
o.innerHTML = "<i>context</i>.moveTo(" + activeCurve.sp.x + ", " + activeCurve.sp.y +");<br/><i>context</i>.bezierCurveTo("
+ activeCurve.cp1.x + ","
+ activeCurve.cp1.y + ","
+ activeCurve.cp2.x + ","
+ activeCurve.cp2.y + ","
+ activeCurve.ep.x + ","
+ activeCurve.ep.y + ");";
ctx.fillStyle = "#FFF";
ctx.fillRect(0, 0, width, height);
ctx.beginPath();
ctx.fillStyle = "#289e82";
ctx.strokeStyle = "#16614f";
ctx.lineWidth = 5;
ctx.moveTo(activeCurve.sp.x, activeCurve.sp.y);
ctx.bezierCurveTo(
activeCurve.cp1.x, activeCurve.cp1.y,
activeCurve.cp2.x, activeCurve.cp2.y,
activeCurve.ep.x, activeCurve.ep.y);
ctx.stroke()
ctx.fill();
ctx.closePath();
ctx.save();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = "#101010";
ctx.globalAlpha = 0.2;
ctx.moveTo(activeCurve.sp.x, activeCurve.sp.y);
ctx.lineTo(activeCurve.cp1.x, activeCurve.cp1.y);
ctx.moveTo(activeCurve.ep.x, activeCurve.ep.y);
ctx.lineTo(activeCurve.cp1.x, activeCurve.cp1.y);
ctx.moveTo(activeCurve.sp.x, activeCurve.sp.y);
ctx.lineTo(activeCurve.cp2.x, activeCurve.cp2.y);
ctx.moveTo(activeCurve.ep.x, activeCurve.ep.y);
ctx.lineTo(activeCurve.cp2.x, activeCurve.cp2.y);
ctx.stroke();
ctx.closePath();
ctx.restore();
requestAnimationFrame(draw);
}
draw()
</script>
</body>
</html>
click to select a control point
So if I got it right you want to change control point E
but still want that your curve goes through the same pink point. There are several ways to achieve this. For example you could duplicate the change point as a control point. For cubics using triple control point will force the curve to go through it. for more info on stacking up cubics see:
However using approximation polynomials will be always problematic for this kind of task. Why not use interpolation polynomial instead. So convert BEZIER control points to interpolation cubic (so that change point is one of the control points) then change E
and convert back to BEZIER control points (in case you can render only BEZIER). The transformation between BEZIER and interpolation cubics is here:
Also as your change point is not one of the control points then you can make it one by: