文号
t24721
阅读
6609
回复
2
收藏
2
分享以前写的3次贝塞尔曲线分割算法
2010/04/15
IP:辽宁
【标准C++编写】

@_@ 为后来的矢量图形长篇讲座做铺垫,排版不好看,请谅解

Package:[s:7]ointArray 是一个自己定义的std::vector<[s:9]ackage:[s:7]ointType> 类型

而,Package:[s:7]ointType是一个基于浮点的Point对象,自己定义一个double x,doule y 即可:

比如:
class Package:[s:7]ointType
{

  double x;
  double y;

public:
  double &X();
  double &Y() ;
  double X() const;
  double Y() const;

  // 按照你的需要,可以自己定义操作符重载,比如向量的加减,点乘,叉乘等,
//  当然还有向量的模等方法,按照你的想法去做。
}



几个参数

origin 是bezier曲线的入口点,然后依次3n+1个点推,支持3n +1个点,对于多段曲线,你需要自己写个非常简单的for 循环(为什么不一次做好呢?函数要功能单一,高内聚,尽量的兼容其他算法)

time是曲线t值;对于beizer的time范围是 [0,1) 半开区间

// 分割曲线 by Joyeep [3/24/2008 ]
bool GetBezierSegment(Package:[s:7]ointType& origin, Package:[s:7]ointArray& points,    double orgTime, double endTime)
{
    bool bRet = false;

                     const int nSegment = points.size()/3; // 给定的曲线的段数
    const double tMax = nSegment ;
    const double tMin = 0;

    double d =  (double)((int)orgTime);
    double d2 = orgTime-d;
    double pirc = 0.0001;
    if (d2 < pirc) // 是存在点,非边缘,这里控制下面的所有精度
    {
        if ( (d2 - tMin)) < pirc )
        {
            // 头        

        }else
        {
            // 中间
            origin = points[(int)orgTime*3-1];
        }

    }
    return bRet;
}

bool AddPoint(Package:[s:7]ointType& origin, Package:[s:7]ointArray& points, double time)
{
    const int nSegment = points.size()/3; // 给定的曲线的段数
    ASSERT(time <= nSegment);

    // time超过范围返回false
    if( (time - (double)nSegment)  > 0.0)    
        return false;    

    double d =  (double)((int)time);
    double d2 = time-d;
    if ( d2 > 0    ){    
        // 边缘
        const int nCurSegment = (int)time;

        Package:[s:7]ointType cur_origin ;
        Package:[s:7]ointArray cur_points;
        if (nCurSegment == 0){
            cur_origin = origin;                
        }else{
            cur_origin = points[nCurSegment];
        }
        cur_points.push_back( points[nCurSegment+1] );
        cur_points.push_back( points[nCurSegment+2] );
        cur_points.push_back( points[nCurSegment+3] );    

        // 得到添加的控制点
        Package:[s:7]ointType addCtrl ;
        addCtrl.X() = (1-time)*(1-time)*(1-time)* cur_origin.X() + 3*(1-time)*(1-time)*time* cur_points[0].X()
        + 3*(1-time)*time*time* cur_points[1].Y() + time*time*time* cur_points[2].X();
        addCtrl.Y() = (1-time)*(1-time)*(1-time)* cur_origin.Y() + 3*(1-time)*(1-time)*time* cur_points[0].Y()
        + 3*(1-time)*time*time* cur_points[1].Y() + time*time*time* cur_points[2].Y();

        // 得到控制点的lhs:
        Package:[s:7]ointType addLhs;
        addLhs.X() = (1-time)*(1-time)* cur_origin.X() + 2*time*(time-1)*cur_points[0].X() + time*time* cur_points

[1].X();
        addLhs.Y() = (1-time)*(1-time)* cur_origin.Y() + 2*time*(time-1)*cur_points[0].Y() + time* time* cur_points

[1].Y();

        // 得到控制点rhs;
        Package:[s:7]ointType addRhs;
        addRhs.X() = (1-time)*(1-time)*cur_points[0].X() + 2*time*(time-1)*cur_points[1].X() + time*time* cur_points

[2].X();
        addRhs.Y() = (1-time)*(1-time)*cur_points[0].Y() + 2*time*(time-1)*cur_points[1].Y() + time*time* cur_points

[2].Y();
        
        // 得到被修改的rhs
        Package:[s:7]ointType modifLhs;
        modifLhs.X() = (1-time)* cur_origin.X() + time * cur_points[1].X();
        modifLhs.Y() = (1-time)* cur_origin.Y() + time * cur_points[1].Y();

        // 得到被修改的rhs
        Package:[s:7]ointType modifRhs;
        modifRhs.X() = (1-time)*cur_points[1].X() + time* cur_points[2].X();
        modifRhs.X() = (1-time)*cur_points[1].Y() + time* cur_points[2].Y();
            
        // 修改原来的lhs        
        cur_points[0] = modifLhs;
        // 修改原来的rhs
        cur_points[1] = modifRhs;

        // 添加新的rhs,ctrl,lhs;
        cur_points.insert(&cur_points[0],addLhs);
        cur_points.insert(&cur_points[1],addCtrl);
        cur_points.insert(&cur_points[2],addRhs);

        if (nCurSegment == 0){            
            points.erase(&points[0]);
            points.erase(&points[0]);
        
            points.insert(points.begin(), cur_points.begin(), cur_points.end());
                        
        }else{            
            points.erase(&points[nCurSegment+1]);
            points.erase(&points[nCurSegment+1]);

            points.insert(&points[nCurSegment],cur_points.begin(), cur_points.end());            
        }

        return true;
    }    
}
16年9个月前IP:未同步
209489
1楼
沙发。。留用。。。。。。
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的