zoukankan      html  css  js  c++  java
  • 样条曲线catmull rom转bezier

    b0,..,b3是贝塞尔,c-1, c2是catmull rom控制点

    [b0] = 1 [ 0  6  0  0] [c_1]
    [b1]   - [-1  6  1  0] [c0]
    [b2]   6 [ 0  1  6 -1] [c1]
    [b3]     [ 0  0  6  0] [c2]

    Qt版本代码:

        QList<QPointF> cps;
        cps.append(QPointF(0, 100));
        cps.append(QPointF(75, 75));
        cps.append(QPointF(200, 150));
        cps.append(QPointF(325, 25));
        cps.append(QPointF(400, 100));
    
        QPainter p(this);
    
        //draw control point
        foreach(const QPointF& pos, cps)
            p.drawEllipse(pos, 5, 5);
    
        QPainterPath path;
        //create bezier from catrull-rom
        /*
            full conversion matrix (inverse bezier * catmull-rom): 4*4(matrix, 4* 1(catrull-rom control points)
            0.000,  1.000,  0.000,  0.000,
            -0.167,  1.000,  0.167,  0.000,
            0.000,  0.167,  1.000, -0.167,
            0.000,  0.000,  1.000,  0.000
    
            conversion doesn't require full matrix multiplication,
            so below we simplify
        */
    path.moveTo(cps.first());

    QPointF prevFar, prev, point, next;
    for(int i = 1; i < cps.size(); i ++)
        {
            int prevFarIdx = i - 2;
            int prevIdx = i - 1;
            int nextIdx = i + 1;
            point = cps[i];
            if(prevIdx >= 0)
                prev = cps[prevIdx];
            else
                prev = point;
            if(prevFarIdx >= 0)
                prevFar = cps[prevFarIdx];
            else
                prevFar = prev;
            if(nextIdx < cps.size())
                next = cps[nextIdx];
            else
                next = point;
    
            QPointF control1(prevFar.x() * qreal(-0.167) +
                             prev.x() +
                             point.x() * qreal(0.167),
                             prevFar.y() * qreal(-0.167) +
                             prev.y() +
                             point.y() * qreal(0.167));
    
            QPointF control2(prev.x() * qreal(0.167) +
                             point.x() +
                             next.x() * qreal(-0.167),
                             prev.y() * qreal(0.167) +
                             point.y() +
                             next.y() * qreal(-0.167));
    
                path.cubicTo(control1, control2, point);
        }
       p.drawPath(path);

    参考:

    1. http://stackoverflow.com/questions/1030596/drawing-hermite-curves-in-opengl

  • 相关阅读:
    GoogleTest 之路2-Googletest 入门(Primer)
    GoogleTest 之路1-Generic Build Instructions编译指导总方案
    Tinyhttpd 知识点
    栈初始化
    ARM S3C2440 时钟初始化流程
    GNU 关闭 MMU 和 Icache 和 Dcache
    bootloader 关闭看门狗
    bootloader svc 模式
    Uboot S3C2440 BL1 的流程
    GNU 汇编 协处理器指令
  • 原文地址:https://www.cnblogs.com/yanhuiw/p/4385685.html
Copyright © 2011-2022 走看看