如何计算贝塞尔曲线的宽度,高度和位置

时间:2013-08-09 06:31:16

标签: position height width curve bezier

我有一个由起点,终点和2个控制点定义的贝塞尔曲线(参数:http://www.w3schools.com/tags/canvas_beziercurveto.asp)。 首先,我需要计算这条曲线的宽度和高度。如果我围绕曲线制作矩形,它的宽度和高度就是我所需要的。 然后我需要开始这个矩形的点(左上角的x,y)。

我该如何计算?感谢。

3 个答案:

答案 0 :(得分:1)

我在其他一些主题中找到了近似解决方案(我不记得哪一个)但这里有简单的JS函数来计算它:

function getCurveBoundary(ax, ay, bx, by, cx, cy, dx, dy) {
        var tobx = bx - ax;
        var toby = by - ay;
        var tocx = cx - bx;
        var tocy = cy - by;
        var todx = dx - cx;
        var tody = dy - cy;
        var step = 1 / 40;    // precission
        var d, px, py, qx, qy, rx, ry, tx, ty, sx, sy, x, y, i, minx, miny, maxx, maxy;
        function min(num1, num2) {
            if (num1 > num2)
                return num2;
            if (num1 < num2)
                return num1;
            return num1;
        }
        function max(num1, num2) {
            if (num1 > num2)
                return num1;
            if (num1 < num2)
                return num2;
            return num1;
        }
        for (var i = 0; i < 41; i++)
        {
            d = i * step;
            px = ax + d * tobx;
            py = ay + d * toby;
            qx = bx + d * tocx;
            qy = by + d * tocy;
            rx = cx + d * todx;
            ry = cy + d * tody;
            toqx = qx - px;
            toqy = qy - py;
            torx = rx - qx;
            tory = ry - qy;

            sx = px + d * toqx;
            sy = py + d * toqy;
            tx = qx + d * torx;
            ty = qy + d * tory;
            totx = tx - sx;
            toty = ty - sy;

            x = sx + d * totx;
            y = sy + d * toty;
            if (i == 0)
            {
                minx = x;
                miny = y;
                maxx = x;
                maxy = y;
            }
            else
            {
                minx = min(minx, x);
                miny = min(miny, y);
                maxx = max(maxx, x);
                maxy = max(maxy, y);
            }
        }
        return {x: Math.round(minx), y: Math.round(miny), width: Math.round(maxx - minx), height: Math.round(maxy - miny)};
    }

答案 1 :(得分:0)

如果您正在寻找近似解决方案,那么计算一个总是足以覆盖曲线的解决方案非常容易,但可能太大了。

Beziers满足'凸包属性',这意味着您可以使用控制点的边界框,这将绑定曲线本身。

如果您正在寻找更准确的东西,那么最简单的方法是评估曲线上的一堆不同点并获取曲线上这些点的边界框。您可以改变测试的点数,以便改变质量/速度权衡。

如果你正在寻找直接计算确切答案的东西,那么你需要的是一个寻根函数来寻找函数x(t)和y(t)的极值。

答案 2 :(得分:0)

对于真实边界,您需要计算曲线的组件函数的末端,然后将这些函数插入到每个末端的(x,y)坐标的贝塞尔函数中。我在http://pomax.github.io/bezierinfo/#extremities处覆盖了这个内容,这也解释了如何在通往四肢部分的文本中完成所需的大部分步骤。第11段和第12/13段然后涵盖了边界框(平原,你可能感兴趣,分别紧张)