2011-08-12 43 views

回答

3

拐角可以通过设置线帽为圆形的。

ctx.lineCap = "round"

您还可以将贝塞尔曲线的整体线条,打造更顺畅整条生产线,通过,该行的每个点P“,...,P” N + 1 ,应用等式P' k =(k /(n + 1))P k-1 +(1-(k /(n + 1)))P k[注意:以及选择指向您用P ň之间的角度设定的阈值时,也许申请贝塞尔曲线的平滑和P N + 1]

结合这两种技术与标准箱模糊的线本身会给你一个更平滑的线条出现。

编辑

从我可以告诉,实际上是一个数字的方式来做到这一点 - 你用的是完全取决于你。我给你举个例子,让您决定:假设你有一个从开始点p(鼠标按下)到终点(鼠标松开)绘制的路径p ñ。该路径由子路径(由连接点连接的点)组成。我们可以使用lineTo()和stroke()来正常绘制从p0到p1的上下文路径。仅仅通过观看控制台输出,子路径加入的点就是mousemove事件触发。按顺序在数组中记录这些点。

当然,如果我们得出这样的背景下为主,我们已经移除了问题,所以这应该是做一个缓冲上下文(额外的canvas元素,例如)。缓冲区被清除,并且我们使用定位点来计算曲线。 bezierCurveTo打印三次函数(B(T)=(1-T) P +3(1-T) P +3(1-t)的吨 P +吨 P ,叔∈ [0,1]。通过您的阵列步骤(认为for循环)重新计算与这些点的线从P 更新曲线0至P 的n-3。(做快速头数学,你可能需要考虑在这个端点。所有这一切都取决于它的电弧式使用)。

因此,让我看看我是否可以做这件事...我没有测试它,所以我保证bugginess。

// Assume: 
// bfr = buffer context. 
// ctx = main context. 
// md = boolean value for mousedown 
// pts = []; <-- already contains lp (below) at pts[0]; 
// We've also recorded Pm in associative array lp [last point] 
// Draw is fired on mousemove. Mousemove records a current point in associative array cp 
draw = function() { 
    if(md) { 
     bfr.beginPath(); 
     bfr.moveTo(lp.x-.5, lp.y-.5); 
     bfr.lineTo(cp.x-.5, cp.y-.5); 
     pts.push({cp.x, cp.y}); 
     bfr.stroke(); 
    } 
} 

// Optionally, you could make this function recursive. 
// This assumes that you want to estimate the curve based on the whole line. 
bezier = function(pts) { 
    ctx.beginPath(); 
    ctx.moveTo(pts[0].x, pts[0].y); 
    for(var i = 0; i < pts.length - 3; i++) { 
    ctx.bezierCurveTo(pts[i+1].x, pts[i+1].y, pts[i+2].x, pts[i+2].y, pts[i+3].x, pts[i+3].y); 
    } 
    ctx.stroke(); 
} 

再次,这就是我所看到的 - 别人可能有一个完全不同的,我敢肯定,更好的解释。我试图撕掉我已经完成的大量事情,并快速地将它们与一些新代码放在一起,给你一些想法。

+0

关于lineCap作品的提示。谢谢。关于贝塞尔曲线......我如何去“应用”方程?我计算每个点P后,是否只使用lineTo?我找到了quadraticCurveTo函数和贝塞尔版本,但只有3或4个输入点。我如何将贝塞尔曲线应用于整个画笔描边? – Homan

+0

我会写一个自定义函数。选择记录到阵列的采样点,应用曲线。您可以对'mousemove'点火的点进行采样,确定三点之间的角度以检查它是否对采样点具有显着差异,如果是,则将其标记,然后使用它来应用曲线。我会将标记点的数组传递给函数以执行评估。始终以'mousedown'和'mouseup'开头,分别为0和n + 1。 – stslavik

+0

假设用户绘制一个快速圆,但采样点分布更像八角形的角。你建议使用某种自定义函数bezierLine(sample_points)来“弯曲”这条线吗?我不了解该功能会发生什么?函数是否通过计算每个像素坐标来绘制每个像素?或者该函数是否采用Bezier(t)遍历的t-step参数,在这种情况下,该函数最终仍然会使用lineTo绘制一条线,对吗? – Homan