我想改变贝塞尔曲线的终点

时间:2017-06-05 02:42:19

标签: javascript math graphics bezier

抱歉我的油漆:

img

我想改变贝塞尔曲线的终点

从s点开始,控制点(c1,c2)到终点

当点到达变化点(粉红色)时,我想要更改端点和

顺利获取新端点的新路径

怎么样?帮帮我......

2 个答案:

答案 0 :(得分:0)

我不明白你的问题,但我已经创建了一个简单的程序,让你理解贝塞尔曲线。

<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>

单击以选择控制点

答案 1 :(得分:0)

所以,如果我做对了你想要改变控制点E,但仍然希望你的曲线经过相同的粉红点。有几种方法可以实现这一目标。例如,您可以将更改点复制为控制点。对于使用三重控制点的立方体,将强制曲线通过它。有关堆积立方体的更多信息,请参阅:

然而,使用近似多项式对于这种任务总是有问题的。为什么不使用插值多项式。因此,将 BEZIER 控制点转换为插值三次方(以便更改点是控制点之一),然后更改E并转换回 BEZIER 控制点(在例如,您只能渲染 BEZIER )。 BEZIER 和插值立方体之间的转换如下:

此外,由于您的更改点不是控制点之一,因此您可以通过以下方式创建一个控制点: