我试图在画布浏览器上绘制隐士曲线。Hermite曲线定义为2分和2个衍生物。
Point1X = 71
Point1Y = 165
Deriv1X = -12
Deriv1Y = 2
Point2X = 210
Point2Y = 153
Deriv2X = 108
Deriv2Y = 0
我可以在画布上绘制曲线。有什么办法可以将Hermite曲线的点和衍生物转换为Bezzier曲线,以便我可以在画布上画出它?
我可以在浏览器上绘制Hermite曲线的另一个选项吗?
感谢您的帮助。
canvas2d不支持任意赫米特花纹,但它确实支持了立方体曲线,并且由于立方beziers是第二阶Hermite曲线,因此我们可以在您的数据和偏曲曲线之间自由转换。
可以在Bezier曲线上找到此底漆的数学,特别是对于此问题,我们可以将序列的HERMITE点转换为[P1,D1,P2,D2]为:
Hermite points [p1,d1,p2,d2] = Bezier [p1, (p1 + d1/(2*t)), (p2 - d2/(2*t)), p2]
请注意,t
值是曲线张力,并控制每个点的曲率顺序(张力越高,沿曲线点附近曲线的曲率变化速率越高),在这种情况下,1
。
(没有张力值,您的四个坐标实际上定义了飞机上的沙漏六角形区域,而不是单个曲线,因为不能保证定向向量是真正的切线;仅仅是代表旅行方向的向量。这些值定义的是一侧{start,end}的行界,并且在开始和结束时沿着旅行的方向无限地扩展边界)。
因此,您可以使用canvas2d api在画布上的画布上绘制任何Hermite曲线,用于立方bezier曲线:
// Hermite data
var p1 = ..., d1 = ..., p2 = ..., d2 = ...;
var cmpoints = [p1.x, p1.y, d1.x, d1.y, p2.x, p2.y, d2.x, d2.y];
// Bezier data
var tension = 1;
var tensionFactor = 2 * tension;
var bpoints = [
p1.x,
p1.y,
p1.x + d1.x/tensionFactor,
p1.y + d1.y/tensionFactor,
p2.x - d2.x/tensionFactor,
p2.y - d2.y/tensionFactor,
p2.x,
p2.y
]
// Draw code (where we assume you already
// have your canvas context as "ctx")
ctx.beginPath();
ctx.moveTo.apply(bpoints.slice(0,2));
ctx.bezierCurveTo.apply(bpoints.slice(2);
ctx.stroke();
立方Hermite曲线(由C(0),C'(0),C(1)和C'(1))和Cubic Bezier曲线(由P0,P1,P1,C(1)定义P2和P3)可以通过
c(0)= p0,
c(1)= p3,
c'(0)= 3(p1-p0),
c'(1)= 3(p3-p2)
因此,您可以找到控制点
p0 = c(0),
p1 =(1/3)*c'(0) p0,
p2 = p3-(1/3)*c'(1),
p3 = c(1)