什么是立方贝塞尔曲线和二次贝塞尔曲线以及它们的使用场景有何区别?

42

最近我一直在玩Canvas,并使用与这些曲线相关的方法画了几个形状(水滴、花瓣、云、石头)。但是,我似乎无法弄清楚这些不同曲线的用例之间的区别。

我知道立方贝塞尔曲线有2个控制点、一个起始点和一个终点,而二次贝塞尔曲线只有一个控制点、一个起始点和一个终点。然而,在绘制形状时,我似乎无法轻松地决定何时使用哪个曲线或何时同时使用它们。

如何知道在绘制形状的不同点使用哪种类型的曲线?


1
Wikipedia摘要。 基本上它与您想要的曲线外观有关。 二次曲线是圆锥截面。 - Pointy
2
从函数名称来看,我并没有立刻意识到bezierCurveTo()是假定为三次贝塞尔曲线。我来这里是为了寻找quadraticCurveTo()bezierCurveTo()之间的区别 :-) - PJ Brunet
2个回答

82

你已经发现,二次曲线和三次贝塞尔曲线都是用曲线连接两个点。

由于三次曲线有更多的控制点,因此在这两个点之间的路径上更加灵活。

例如,假设您想绘制字母“R”:

enter image description here

从“非曲线”部分开始绘制R:

enter image description here

现在尝试使用二次曲线来绘制曲线。

请注意,二次曲线比我们需要的更加“尖锐”。

这是因为我们只有一个控制点来定义二次曲线的曲度。

enter image description here

现在尝试使用三次贝塞尔曲线绘制曲线。

三次贝塞尔曲线比二次曲线更圆滑。

这是因为我们有两个控制点来定义三次曲线的曲度。

enter image description here

所以……更多的控制点可以更好地控制“曲度”

这里是代码和Fiddle:http://jsfiddle.net/m1erickson/JpXZW/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:20px; }
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    ctx.lineWidth=8;
    ctx.lineCap="round";

    function baseR(){
        ctx.clearRect(0,0,canvas.width,canvas.height);
        ctx.beginPath();
        ctx.moveTo(30,200);
        ctx.lineTo(30,50);
        ctx.lineTo(65,50);
        ctx.moveTo(30,120);
        ctx.lineTo(65,120);
        ctx.lineTo(100,200);
        ctx.strokeStyle="black";
        ctx.stroke()
    }

    function quadR(){
        ctx.beginPath();
        ctx.moveTo(65,50);
        ctx.quadraticCurveTo(130,85,65,120);
        ctx.strokeStyle="red";
        ctx.stroke();
    }

    function cubicR(){
        ctx.beginPath();
        ctx.moveTo(65,50);
        ctx.bezierCurveTo(120,50,120,120,65,120);
        ctx.strokeStyle="red";
        ctx.stroke();
    }

    $("#quad").click(function(){
        baseR();
        quadR();
        //cubicR();
    });

    $("#cubic").click(function(){
        baseR();
        cubicR();
    });

}); // end $(function(){});
</script>

</head>

<body>
    <button id="quad">Use Quadratic curve</button>
    <button id="cubic">Use Cubic Bezier curve</button><br><br>
    <canvas id="canvas" width=150 height=225></canvas>
</body>
</html>

2
谢谢,已接受。如果立方曲线提供更多的灵活性,那么使用二次曲线的原因是什么? - Conqueror
1
二次曲线在数学上比贝塞尔曲线更简单,因此对于画布绘制来说更加高效。 - markE
3
顺便提一句,如果你使用两个相同的控制点来绘制贝塞尔曲线,那么你得到的是一个二次曲线。有时候这样想会更有帮助,因为这两种曲线是相关的。 - markE
1
从设计角度来看,二次曲线的好处是可以利用基于点相互约束的快捷方式来建模多阶贝塞尔曲线(这也是缺点,因为在二次贝塞尔多阶曲线中移动一个坐标将完全改变形状)。仅使用控制点在曲线点上反射的曲线意味着您只需要第一个控制点和所有曲线点即可,节省了编码曲线时的大量空间(这就是TrueType字体如何对其轮廓进行建模的方法)。 - Mike 'Pomax' Kamermans
9
马克先生,你在上一条评论中说的话是错误的!具有相同控制点的立方Bezier曲线不是二次Bezier曲线!实际上,如果我们将二次Bezier曲线转换为立方Bezier曲线,我们会得到两个不同的句柄,其坐标也不同。请参考这个SVG示例:http://jsfiddle.net/vkcahL1e/。 - Max Payne

17

我知道这篇文章有点晚。但是似乎有一些关于二次和三次Bezier曲线的重要方面仍然缺失。

对于二次Bezier曲线来说,你永远无法使两个端点的斜率平行。但是你可以通过三次Bezier曲线来实现这一点。此外,三次Bezier曲线允许你单独控制两个端点的斜率,而这在二次Bezier曲线中是不可能的。然而,二次Bezier曲线永远不会存在拐点(曲率符号改变的点),而如果你在控制点上不小心,三次Bezier曲线可能会存在拐点。因此,总的来说,由于其灵活性,三次Bezier曲线比二次Bezier曲线更受欢迎。当单调曲率很重要时,二次Bezier曲线(更常见的是有理二次Bezier曲线)将被使用。


1
如果我们将两个相连的二次曲线与一个三次曲线进行比较,它们不能达到相同的灵活性水平吗? - vek
3
使用两条连接的二次曲线可以增加灵活性水平。但这会增加复杂性,因为你需要处理两个曲线而不是一个。此外,你必须确保这两条曲线始终具有切线连续性。即使你做到了这一点,这两条曲线在连接处可能仍存在曲率不连续性。因此,使用三次曲线仍然是更好的选择,以避免所有这些麻烦。 - fang
1
单调曲率是什么? - Scorb
@Scorb 单调曲率意味着随着我们沿着曲线移动,曲率始终在增加或减少(就像螺旋形状一样)。 - Maxence

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接