转载地址:http://www.antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION

Interpolation with Bezier Curves
A very simple method of smoothing polygons

Initially, there was a question in comp.graphic.algorithms how to interpolate a polygon with a curve in such a way that the resulting curve would be smooth and hit all its vertices. Gernot Hoffmann suggested to use a well-known B-Splineinterpolation. Here is his original article.B-Splineworks good and it behaves like an elastic ruler fixed in the polygon vertices.

 

 

But I had a gut feeling that there must be a simpler method. For example, approximation with cubic Bezier curves. A Bezier curve has two anchor points (begin and end) and two control ones (CP) that determine its shape. More information about Bezier curves can be found using any search engine, for example, on Paul Bourke's excellent site. Our anchor points are given, they are pair of vertices of the polygon. The question was, how to calculate the control points. I ran Xara Xand drew this picture. It was pretty easy and I decided to try to calculate their coordinates. It was obvious that the control points of two adjacent edges plus the vertex between them should form one straight line. Only in this case the two adjacent curves will be connected smoothly. So, the two CP should be the a reflection of each other, but… not quite. Reflection assumes equal distances from the central point. For our case it's not correct. First, I tried to calculate a bisectrix between two edges and then take points on the perpendicular to it. But as shown in the picture, the CP not always lie on the perpendicular to thebisectrix.

 

Finally, I found a very simple method that does not require any complicated math. First, we take the polygon and calculate the middle points Ai of its edges.

 

Here we have line segments Ci that connect two points Aiof the adjacent segments. Then, we should calculate points Bi as shown in this picture.

 

The third step is final. We simply move the line segments Ci in such a way that their points Bicoincide with the respective vertices. That's it, we calculated the control points for our Bezier curve and the result looks good.

 

One little improvement. Since we have a straight line that determines the place of our control points, we can move them as we want, changing the shape of the resulting curve. I used a simple coefficient K that moves the points along the line relatively to the initial distance between vertices and control points. The closer the control points to the vertices are the sharper figure will be obtained.

 

Below is the result of rendering a popular in SVG lion in its original form and with Bezier interpolation with K=1.0

 

 

And the enlarged ones.

 

 

The method works quite well with self-intersecting polygons. The examples below show that the result is pretty interesting.

 
 
 

This method is pure heuristic and empiric. It probably gives a wrong result from the point of view of strict mathematical modeling. But in practice the result is good enough and it requires absolute minimum of calculations. Below is the source code that has been used to generate the lions shown above. It's not optimal and just an illustration. It calculates some variables twice, while in real programs we can store and reuse them in the consecutive steps.

    // Assume we need to calculate the control// points between (x1,y1) and (x2,y2).// Then x0,y0 - the previous vertex,//      x3,y3 - the next one.double xc1 = (x0 + x1) / 2.0;double yc1 = (y0 + y1) / 2.0;double xc2 = (x1 + x2) / 2.0;double yc2 = (y1 + y2) / 2.0;double xc3 = (x2 + x3) / 2.0;double yc3 = (y2 + y3) / 2.0;double len1 = sqrt((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0));double len2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));double len3 = sqrt((x3-x2) * (x3-x2) + (y3-y2) * (y3-y2));double k1 = len1 / (len1 + len2);double k2 = len2 / (len2 + len3);double xm1 = xc1 + (xc2 - xc1) * k1;double ym1 = yc1 + (yc2 - yc1) * k1;double xm2 = xc2 + (xc3 - xc2) * k2;double ym2 = yc2 + (yc3 - yc2) * k2;// Resulting control points. Here smooth_value is mentioned// above coefficient K whose value should be in range [0...1].ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;

And the source code of an approximation with a cubic Bezier curve.

// Number of intermediate points between two source ones,
// Actually, this value should be calculated in some way,
// Obviously, depending on the real length of the curve.
// But I don't know any elegant and fast solution for this
// problem.
#define NUM_STEPS 20void curve4(Polygon* p,double x1, double y1,   //Anchor1double x2, double y2,   //Control1double x3, double y3,   //Control2double x4, double y4)   //Anchor2
{double dx1 = x2 - x1;double dy1 = y2 - y1;double dx2 = x3 - x2;double dy2 = y3 - y2;double dx3 = x4 - x3;double dy3 = y4 - y3;double subdiv_step  = 1.0 / (NUM_STEPS + 1);double subdiv_step2 = subdiv_step*subdiv_step;double subdiv_step3 = subdiv_step*subdiv_step*subdiv_step;double pre1 = 3.0 * subdiv_step;double pre2 = 3.0 * subdiv_step2;double pre4 = 6.0 * subdiv_step2;double pre5 = 6.0 * subdiv_step3;double tmp1x = x1 - x2 * 2.0 + x3;double tmp1y = y1 - y2 * 2.0 + y3;double tmp2x = (x2 - x3)*3.0 - x1 + x4;double tmp2y = (y2 - y3)*3.0 - y1 + y4;double fx = x1;double fy = y1;double dfx = (x2 - x1)*pre1 + tmp1x*pre2 + tmp2x*subdiv_step3;double dfy = (y2 - y1)*pre1 + tmp1y*pre2 + tmp2y*subdiv_step3;double ddfx = tmp1x*pre4 + tmp2x*pre5;double ddfy = tmp1y*pre4 + tmp2y*pre5;double dddfx = tmp2x*pre5;double dddfy = tmp2y*pre5;int step = NUM_STEPS;// Suppose, we have some abstract object Polygon which// has method AddVertex(x, y), similar to LineTo in// many graphical APIs.// Note, that the loop has only operation add!while(step--){fx   += dfx;fy   += dfy;dfx  += ddfx;dfy  += ddfy;ddfx += dddfx;ddfy += dddfy;p->AddVertex(fx, fy);}p->AddVertex(x4, y4); // Last step must go exactly to x4, y4
}

You can download a working application for Windows that renders the lion, rotates and scales it, and generates random polygons. Interpolation with Bezier curves  (bezier_interpolation.zip). Press left mouse button and drag to rotate and scale the image around the center point. Press right mouse button and drag left-right to change the coefficient of smoothing (K). Value K=1 is about 100 pixels from the left border of the window. Each left double-click generates a random polygon. You can also rotate and scale it, and change K.

 
Copyright © 2002-2006 Maxim Shemanarev
Web Design and Programming Maxim Shemanarev

一种简单的贝塞尔插值算法相关推荐

  1. CSS里总算是有了一种简单的垂直居中布局的方法了

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head><me ...

  2. ICCV2021 Oral SimROD:简单高效的数据增强!华为提出了一种简单的鲁棒目标检测自适应方法...

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨小马 来源丨我爱计算机视觉 ▊ 写在前面 本文提出了一种简单有效的鲁棒目标检测无监督自适应方法( ...

  3. 英文字典设计c语言代码,一种简单的英文词典排版系统

    <一种简单的英文词典排版系统>由会员分享,可在线阅读,更多相关<一种简单的英文词典排版系统(20页珍藏版)>请在人人文库网上搜索. 1.中国地质大学(武汉)C语言课程设计论文学 ...

  4. 算法:三种简单排序算法

    排序算法比較常见的有:冒泡排序.简单选择排序.直接插入排序:希尔排序.堆排序.归并排序和高速排序算法等. 今天先学习一下前面三种比較简单的算法.排序的相关概念: ①排序的稳定性:两个或多个元素相等.排 ...

  5. EasyBridge:一种简单的js-bridge设计方案

    EasyBridge是一个简单易用的js-bridge的工具库,提供了日常开发中,JavaScript与Java之间通讯的能力,与其他常见的js-bridge工具库实现方案不同,EasyBridge具 ...

  6. 有没有一种简单的方法可以按值删除列表元素?

    a = [1, 2, 3, 4] b = a.index(6)del a[b] print a 上面显示了以下错误: Traceback (most recent call last):File &q ...

  7. java判断回文字符串几种简单的实现

    11年it研发经验,从一个会计转行为算法工程师,学过C#,c++,java,android,php,go,js,python,CNN神经网络,四千多篇博文,三千多篇原创,只为与你分享,共同成长,一起进 ...

  8. php xml对象解析_php解析xml 的四种简单方法(附实例)

    XML处理是开发过程中经常遇到的,PHP对其也有很丰富的支持,本文只是对其中某几种解析技术做简要说明,包括:Xml parser, SimpleXML, XMLReader, DOMDocument. ...

  9. 【页面传值6种方式】- 【JSP 页面传值方法总结:4种】 - 【跨页面传值的几种简单方式3种】...

    页面传值--最佳答案6种方式: 一. 使用QueryString变量 QueryString是一种非常简单也是使用比较多的一种传值方式,但是它将传递的值显示在浏览器的地址栏中,如果是传递一个或多个安全 ...

最新文章

  1. Introduction to Automata Theory, Languages, and Computation部分习题解答
  2. 使用GlassFish 4.0测试驱动Java API以处理JSON
  3. SAP License:SAP顾问面试问题
  4. Windows Phone 保存录音
  5. 中国AI英雄风云榜十位领军人揭晓 | 网易2018中国年度AI领域人物评选
  6. ios 数组中的字典排序_iOS开发——根据数组中的字典中的某一元素排序
  7. java/php/net/python职工请假管理系统设计
  8. video-js rtmp直播、this .el_vjs_getproperty问题、多个rtmp播放、可用rtmp地址
  9. Oracle PeopleSoft 应用安全加固
  10. changelog 生成  npm install -g conventional-changelog-cli
  11. 【企业数智化转型】知识图谱(Knowledge Graph)
  12. 【区块链108将】区块链无权威,参与之前多了解才可能赚钱
  13. android+考研助手,安卓考研助手问题总结及改进规划是什么
  14. C语言编写数独小游戏
  15. 《A Survey on Transfer Learning》迁移学习研究综述 翻译
  16. 三级等保要求及所需设备
  17. UniApp 本地物资管理出入库系统
  18. 纯手写F3飞控的直升机固件(2.直升机倾斜盘混控了解)
  19. java判断是否为文件夹_java怎么判断是否文件夹
  20. python DHT网络爬虫

热门文章

  1. 5.4.1 映射Blob和Clob类型@Lob
  2. 1005错误解决办法
  3. vw 前端_前端常用开发单位-vw
  4. 在python中使用FP-growth算法
  5. Python数据分析第三期--简述Pandas
  6. 【ZOJ 4062】Plants vs. Zombies
  7. 成为一个程序员要花多长时间
  8. windows局域网能ping通别人,别人确无法ping通自己的解决
  9. 小程序+支付+会员营销,应用场景非常广
  10. kubectl describe命令详解