为了把一串点连成光滑的曲线,先研究贝塞尔曲线,又搞B样条插值。。。。都没有成功(数学没那么强)。
后来在
“[翻译] AGG 之贝塞尔插值 ”http://liyiwen.javaeye.com/blog/705489 。看到一种比较好的方法:
运用贝塞尔曲线的光滑性来穿过这些点。
大致思路就是 先算出相邻原始点的中点,在把相邻中点连成的线段平移到对应的原始点,以平移后的中点作为控制点,相邻原始点为起始点画贝塞尔曲线,这样就保证了连接处的光滑。而贝塞尔曲线本身是光滑的,所以就把这些原始点用光滑曲线连起来了。
![](http://dl.javaeye.com/upload/attachment/297507/571b6373-7a65-3e37-9aa9-70b232e38f80.jpg)
我封装了一个函数,留着以后用。
(c++版,其它语言只要把数组和可变数组稍微变一下就能用)
- void createCurve(CvPoint *originPoint,int originCount,vector<CvPoint> &curvePoint){
-
- float scale = 0.6;
- CvPoint midpoints[originCount];
-
- for(int i = 0 ;i < originCount ; i++){
- int nexti = (i + 1) % originCount;
- midpoints[i].x = (originPoint[i].x + originPoint[nexti].x)/2.0;
- midpoints[i].y = (originPoint[i].y + originPoint[nexti].y)/2.0;
- }
-
-
- CvPoint extrapoints[2 * originCount];
- for(int i = 0 ;i < originCount ; i++){
- int nexti = (i + 1) % originCount;
- int backi = (i + originCount - 1) % originCount;
- CvPoint midinmid;
- midinmid.x = (midpoints[i].x + midpoints[backi].x)/2.0;
- midinmid.y = (midpoints[i].y + midpoints[backi].y)/2.0;
- int offsetx = originPoint[i].x - midinmid.x;
- int offsety = originPoint[i].y - midinmid.y;
- int extraindex = 2 * i;
- extrapoints[extraindex].x = midpoints[backi].x + offsetx;
- extrapoints[extraindex].y = midpoints[backi].y + offsety;
-
- int addx = (extrapoints[extraindex].x - originPoint[i].x) * scale;
- int addy = (extrapoints[extraindex].y - originPoint[i].y) * scale;
- extrapoints[extraindex].x = originPoint[i].x + addx;
- extrapoints[extraindex].y = originPoint[i].y + addy;
-
- int extranexti = (extraindex + 1)%(2 * originCount);
- extrapoints[extranexti].x = midpoints[i].x + offsetx;
- extrapoints[extranexti].y = midpoints[i].y + offsety;
-
- addx = (extrapoints[extranexti].x - originPoint[i].x) * scale;
- addy = (extrapoints[extranexti].y - originPoint[i].y) * scale;
- extrapoints[extranexti].x = originPoint[i].x + addx;
- extrapoints[extranexti].y = originPoint[i].y + addy;
-
- }
-
- CvPoint controlPoint[4];
-