【问题标题】:I want change bezier curve's endpoint我想改变贝塞尔曲线的端点
【发布时间】:2017-06-05 02:42:18
【问题描述】:

对不起我的油漆:

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

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

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

顺利获取新端点的新路径

如何?帮帮我。。

【问题讨论】:

  • 嗨,你试过什么?
  • @AnindyaDutta 我不明白你在说什么......
  • 너 뭐 해봤 니? 당신이 직면 한 문제는 무엇입니까?

标签: javascript math graphics bezier


【解决方案1】:

我不明白你的问题,但我编写了一个简单的程序,可以让你理解贝塞尔曲线。

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

点击选择控制点

【讨论】:

    【解决方案2】:

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

    但是,对于此类任务,使用近似多项式总是有问题的。为什么不使用插值多项式。所以将 BEZIER 控制点转换为插值三次(这样变化点就是控制点之一)然后更改 E 并转换回 BEZIER 控制点(如果你只能渲染 BEZIER)。 BEZIER 和插值三次的转换在这里:

    此外,由于您的更改点不是控制点之一,那么您可以通过以下方式将其变为一个:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2014-11-01
      • 2017-11-20
      • 2018-03-10
      • 2011-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多