Javascript 尝试查找具有4个点的bezier曲线的长度
对于这个问题,我已经找到了大约1000个答案,但没有一个我可以使用,因为我在曲线上使用了4个控制点 也就是说,我偶然发现了这个家伙: 看起来这是一个完美的解决方案,但开头的部分让我完全困惑:Javascript 尝试查找具有4个点的bezier曲线的长度,javascript,math,canvas,bezier,Javascript,Math,Canvas,Bezier,对于这个问题,我已经找到了大约1000个答案,但没有一个我可以使用,因为我在曲线上使用了4个控制点 也就是说,我偶然发现了这个家伙: 看起来这是一个完美的解决方案,但开头的部分让我完全困惑: k1 = -p1 + 3*(p2 - p3) + p4; k2 = 3*(p1 + p3) - 6*p2; k3 = 3*(p2 - p1); k4 = p1; 我究竟应该如何在二维对象上进行加法、减法和乘法之类的操作(我假设point2d是一种类似{x:0,y:0}的对象结构)?我觉得自己很蠢,但这是唯
k1 = -p1 + 3*(p2 - p3) + p4;
k2 = 3*(p1 + p3) - 6*p2;
k3 = 3*(p2 - p1);
k4 = p1;
我究竟应该如何在二维对象上进行加法、减法和乘法之类的操作(我假设point2d是一种类似{x:0,y:0}
的对象结构)?我觉得自己很蠢,但这是唯一阻止我真正实现这个怪物的东西
FWIW,我用这个方程来规范一个实体在游戏中穿越曲线时的速度。如果你知道一个更好的方法,我洗耳恭听。一个二维物体,或点2D,只是一个向量,在数学上有很好的定义。例如:
k*(x,y) = (k*x, k*y)
-(x,y) = (-1)*(x,y)
(x1,y1) + (x2,y2) = (x1+x2, y1+y2)
这些都是计算
k1
,k2
,k3
,和k4
以下是如何匀速通过三次贝塞尔曲线的公式
没有一个简单的公式可以获得沿三次贝塞尔曲线的偶数长度线段(表示偶数弧长线段)。所涉及的是沿曲线计算多个点,然后使用插值将每个点“推”成大致等距
你不用拿到数学博士学位,我就能让你几乎达到目标
首先,使用通用公式计算从t=0到t=1的曲线上的x/y点,其中t=0表示曲线的起点,t=1表示曲线的终点。这是常见的公式:
// calc the x/y point at t interval
// t=0 at startPt, t=1 at endPt
var x=CubicN(t,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(t,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
// cubic helper formula at t interval
function CubicN(t, a,b,c,d) {
var t2 = t * t;
var t3 = t2 * t;
return a + (-a * 3 + t * (3 * a - a * t)) * t
+ (3 * b + t * (-6 * b + b * 3 * t)) * t
+ (c * 3 - c * 3 * t) * t2
+ d * t3;
}
如果你计算了足够的间隔,比如说100个间隔(每个循环t+=0.01),那么你将得到一个非常好的曲线近似值
这意味着如果你用线连接100个点,结果会非常像一条三次贝塞尔曲线
但你还没做完
上述计算的x/y点系列彼此之间的弧距离不一致。
有些相邻点靠得很近,有些相邻点相距较远
要计算均匀分布的点,请执行以下操作:
额外的改进:这将导致沿贝塞尔路径的视觉平滑移动。但是如果你想要更平滑,只需计算100多个点——更多点==更平滑。这不是TS提出的问题。这是他的问题的一部分,“我到底应该如何在二维物体上做加法、减法和乘法?”问题:我到底应该如何做加法、减法和乘法等运算,在二维对象上进行减法和乘法?回答:你一次在一个坐标(x或y)上做这些,只是为了尝试扩展第4点,让其他任何人(像我一样)都难以理解。在我的例子中,我从不同的时间间隔中抽取了10个样本(在上面的例子中,用“t”表示)。当我得到“SL”时,我不是将每个样本除以10,而是将其除以区间平均长度的结果。方程类似于
区间(t)/(区间长度/所有区间的平均长度)
。您可能还需要调整十的幂,但我不确定这是肯定的还是仅限于我的情况。
// calc the x/y point at t interval
// t=0 at startPt, t=1 at endPt
var x=CubicN(t,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(t,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
// cubic helper formula at t interval
function CubicN(t, a,b,c,d) {
var t2 = t * t;
var t3 = t2 * t;
return a + (-a * 3 + t * (3 * a - a * t)) * t
+ (3 * b + t * (-6 * b + b * 3 * t)) * t
+ (c * 3 - c * 3 * t) * t2
+ d * t3;
}