基于boost库使用的Bézier曲线绘图

基于boost库使用的Bézier曲线绘图

这几天在工作上遇到了图形优化相关的问题,于是区学了bezier曲线
具体原理的证明过程,我在此处就不再赘述,有兴趣者可以去知网查询相关文献(如:Bézier基函数的导出
我们要做的就是把得到的线段按照比例分开,并根据每一段找到相应的点。
具体的操作还是看图说话好了。

第一步:点的存入

将点存入直线类型 a中,如绿色线集显示的
此处我们输入了四个点(0,0)(2,1)(3,-2)(5,-0.5),并且得到了由三条线段组成的线集
初始

第二步:线段的分割

将线集a中每条线段都均匀的分成m份,并将线段记录在线集l1中(红色)
线段的分割

第三步:同序号点的连接

具体一点来说,就是: 一条线段的第k个点,与他下一条线段的第k个点相连。
图中黄色线段就是第一条线段的第2个点和第二条线段的第2个点相连。
同序号点的连接

第四步:线段的再次分割

你需要把第三步生成的线段分割,并找到上面对应的点。由第k个点生成的线段,就寻找第k个点。
如图,绿色是已经选择的点,黄色线段上面已经划分好的点中,因为该黄色线段是红色线段第二条的第5个点,和第三条线段的第5个点生成,因此取黄色线段上第5个点。
线段的再次分割

第五步:得到新线集

蓝色的就是根据红色l1生成的新的线集l2。
了解一些Bezier曲线的朋友可能已经看出来了,蓝色的每条线段就是两条红色线段的Bezier曲线
得到新线集

第六步:递归,直到线集只剩一条线段

l2变为新的l1,继续第三步到第五步的操作,直到l1只有一条线段。
递归,直到线集只剩一条线段

第七步:完成,并对比

紫色为原图形,红色为他的Bezier曲线。
在这里插入图片描述

实现代码

#include<cstdio>
#include<iostream>
#include<vector>
#include<boost/geometry.hpp>

using namespace std;
namespace bg = boost::geometry;

typedef bg::model::d2::point_xy<double> point_t;
typedef bg::model::segment<point_t> segment_t;
typedef bg::model::linestring<point_t> line_t;
typedef bg::model::polygon<point_t> polygon_t;
typedef bg::model::multi_point<point_t> mpoint_t;
typedef bg::model::multi_linestring<line_t> mline_t;
typedef bg::model::multi_polygon<polygon_t> mpolygon_t;
typedef bg::strategy::transform::rotate_transformer<bg::radian,double,2,2> rotate_t;

int n,m;
mpoint_t ps;
line_t a;
mline_t l1,l2;
void makePoint()
{
    for(int i=1;i<l1.size();i++)//寻找线段
    {
        line_t l;
        l.push_back(l1[i-1][0]);
        for(int j=1;j<l1[i].size();j++)//遍历线段切分点
        {
            segment_t s{l1[i-1][j],l1[i][j]};//根据切分点生成线段s
            double len;
            len=bg::distance(l1[i-1][j],l1[i][j]);
            len/=m;
            ps.clear();
            bg::line_interpolate(s,len,ps);//线段s的切分
            l.push_back(ps[j-1]);//线段s切分点的存入
        }
        l2.push_back(l);//生成线集l2
    }
    return;
}
int main()
{

    scanf("%d%d",&n,&m);//记录点的个数n,每一条线段分开的数量m
    while(n--)
    {
        double inx,iny;
        point_t p;
        scanf("%lf%lf",&inx,&iny);
        p.set<0>(inx);
        p.set<1>(iny);
        a.push_back(p);//将点存入直线a中
    }
    for(int i=1;i<a.size();i++)
    {
        segment_t s{a[i-1],a[i]};
        double len;
        len=bg::distance(a[i-1],a[i]);
        len/=m;
        ps.clear();
        bg::line_interpolate(s,len,ps);//将线段分割成m+1段
        line_t l;
        l.push_back(a[i-1]);
        for(int j=0;j<ps.size();j++)
        {
            l.push_back(ps[j]);
        }
        l1.push_back(l);
    }
    while(l1.size()>1)
    {
        makePoint();//生成新的线集
        l1=l2;//用l2更新l1
        l2.clear();
    }
    return 0;
}
输入
	4 10
	0 0
	2 1
	3 -2
	5 -0.5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值