【发布时间】:2021-12-19 03:38:53
【问题描述】:
我正在尝试计算点在贝塞尔曲线上的位置,并且我正在使用标准公式来计算。那就是:
x = (1 - t) * (1 - t) * x1 + 2 * (1 - t) * t * cpX + t * t * x2;
y = (1 - t) * (1 - t) * y1 + 2 * (1 - t) * t * cpY + t * t * y2;
但是,我对结果感到很困惑。我已经为我在下面谈论的内容开发了一个演示:
let c = document.querySelector("canvas");
let ctx = c.getContext("2d");
let x1 = 25;
let y1 = 25;
let cpX = 35;
let cpY = 35;
let x2 = 200;
let y2 = 25;
let f = 0;
function calcX(t) {
return (1 - t) * (1 - t) * x1 + 2 * (1 - t) * t * cpX + t * t * x2;
}
function calcY(t) {
return (1 - t) * (1 - t) * y1 + 2 * (1 - t) * t * cpY + t * t * y2;
}
function drawCurve() {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.quadraticCurveTo(cpX, cpY, x2, y2);
ctx.stroke();
}
function drawLoop(elapsed) {
c.width = 600;
c.height = 600;
let x = calcX(f);
let y = calcY(f);
drawCurve();
ctx.beginPath();
ctx.rect(x, y, 3, 3);
ctx.stroke();
f = f < 1 ? f + 0.001 : 0;
document.querySelector(".debug").innerHTML = f.toFixed(2);
requestAnimationFrame(drawLoop);
}
drawLoop(0);
.debug { position: absolute; left: 9px; top: 6px; }
<canvas></canvas>
<div class="debug"></div>
如您所见,50% 标记似乎离左边太远了:
我知道有一条曲线,但中途标记似乎仍然离左边太远。也就是说,如果你问一群人,这条曲线的中间标记在哪里,我相信他们都会说向右更远。
这可能是一个长镜头,但是否还有另一个公式可以计算贝塞尔曲线上更“接近真实世界”的点?
编辑:我只是想到了另一种更具体地表达这种现象的方法。您会注意到,如果将 cpX 和 cpY 变量值设置为任意数字,然后运行模拟,方形标记会沿着曲线的不同部分以不同的速度移动。也就是说,它可能在开始时快速移动,然后减速,然后在曲线的末端再次加速。
我正在寻找的是一个公式,这样方形标记将在整个曲线上以恒定速度进行,并且永远不会沿途加速或减速。这可能吗?
【问题讨论】:
-
在 C# 中复制但带有资源链接:stackoverflow.com/questions/23596802/…
-
哦,这只对寻找中点有用吗?我知道这是我的标题所指定的,但我想我认为解决方案将是通用的,并允许您找到曲线上的任何点,因为我最终也会需要它。
-
问题的根本原因是这样的:i.imgur.com/wDvwiQH.png - 给我几分钟,我会想出一个解决方案。
-
@ChrisG 是的,这张照片完全解释了我的意思!我很高兴你能理解我的乱码解释。
-
这是一个解决方案:jsfiddle.net/s5cp9t01(我将 100 个点的坐标保存在一个数组中,计算点之间的线段长度,然后沿着线段行走直到达到目标长度.
标签: javascript html algorithm bezier spline