【问题标题】:How to calculate width, height and position of bezier curve如何计算贝塞尔曲线的宽度、高度和位置
【发布时间】:2013-08-11 01:27:57
【问题描述】:

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

我该如何计算呢?谢谢。

【问题讨论】:

    标签: position height width curve bezier


    【解决方案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)};
        }
    

    【讨论】:

      【解决方案2】:

      如果您正在寻找一个近似解,很容易计算出一个总是足够大以覆盖曲线但可能太大的解。

      贝塞尔曲线满足“凸壳属性”,这意味着您可以获取控制点的边界框,这将限制曲线本身。

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

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

      【讨论】:

        【解决方案3】:

        对于真实边界,您需要计算曲线分量函数的末端,然后将它们代入贝塞尔函数中,以获得每个末端的 (x,y) 坐标。我在http://pomax.github.io/bezierinfo/#extremities 对此进行了介绍,它还解释了如何在通向四肢部分的文本中执行到达那里所需的大部分步骤。然后第 11 和 12/13 段介绍了边界框(分别是普通的,你可能感兴趣的,而紧凑的)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-21
          • 1970-01-01
          • 2011-08-03
          • 2015-12-30
          • 1970-01-01
          相关资源
          最近更新 更多