分享以前写的3次贝塞尔曲线分割算法
joyeep2010/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 = XXXXXXXXXze()/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 = XXXXXXXXXze()/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_XXXXXXXXXsert(&cur_points[0],addLhs);
        cur_XXXXXXXXXsert(&cur_points[1],addCtrl);
        cur_XXXXXXXXXsert(&cur_points[2],addRhs);

        if (nCurSegment == 0){            
            XXXXXXXXXase(&points[0]);
            XXXXXXXXXase(&points[0]);
        
            XXXXXXXXXsert(XXXXXXXXXgin(), cur_XXXXXXXXXgin(), cur_points.end());
                        
        }else{            
            XXXXXXXXXase(&points[nCurSegment+1]);
            XXXXXXXXXase(&points[nCurSegment+1]);

            XXXXXXXXXsert(&points[nCurSegment],cur_XXXXXXXXXgin(), cur_points.end());            
        }

        return true;
    }    
}
来自:计算机科学 / 软件综合
2
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
warmonkey
14年3个月前 IP:未同步
209489
沙发。。留用。。。。。。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
joyeep
学者 机友 笔友
文章
88
回复
565
学术分
8
2009/05/25注册,1个月17天前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}