来自:https://blog.csdn.net/microchenhong/article/details/6316332

真正的原文:https://www.cnblogs.com/muxue/archive/2010/06/23/1763886.html

原文的原文:http://agg.sourceforge.net/antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION

没时间研究,先翻译过来

Point类用的是wpf里的Point,就是里面有double类型的X,Y,没有其他依赖

void createCurve(Point[] originPoint, int originCount, List<Point> curvePoint){//控制点收缩系数 ,经调试0.6较好double scale = 0.6;Point[] midpoints = new Point[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;}//平移中点  Point[] extrapoints = new Point[2 * originCount];for (int i = 0; i < originCount; i++){int nexti = (i + 1) % originCount;int backi = (i + originCount - 1) % originCount;Point midinmid = new Point();midinmid.X = (midpoints[i].X + midpoints[backi].X) / 2.0;midinmid.Y = (midpoints[i].Y + midpoints[backi].Y) / 2.0;double offsetx = originPoint[i].X - midinmid.X;double offsety = originPoint[i].Y - midinmid.Y;int extraindex = 2 * i;extrapoints[extraindex].X = midpoints[backi].X + offsetx;extrapoints[extraindex].Y = midpoints[backi].Y + offsety;//朝 originPoint[i]方向收缩   double addx = (extrapoints[extraindex].X - originPoint[i].X) * scale;double 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;//朝 originPoint[i]方向收缩   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;}Point[] controlPoint = new Point[4];//生成4控制点,产生贝塞尔曲线  for (int i = 0; i < originCount; i++){controlPoint[0] = originPoint[i];int extraindex = 2 * i;controlPoint[1] = extrapoints[extraindex + 1];int extranexti = (extraindex + 2) % (2 * originCount);controlPoint[2] = extrapoints[extranexti];int nexti = (i + 1) % originCount;controlPoint[3] = originPoint[nexti];double u = 1;while (u >= 0){double px = bezier3funcX(u, controlPoint);double py = bezier3funcY(u, controlPoint);//u的步长决定曲线的疏密  u -= 0.005;Point tempP = new Point(px, py);//存入曲线点   curvePoint.Add(tempP);}}}//三次贝塞尔曲线  double bezier3funcX(double uu, Point[] controlP){double part0 = controlP[0].X * uu * uu * uu;double part1 = 3 * controlP[1].X * uu * uu * (1 - uu);double part2 = 3 * controlP[2].X * uu * (1 - uu) * (1 - uu);double part3 = controlP[3].X * (1 - uu) * (1 - uu) * (1 - uu);return part0 + part1 + part2 + part3;}double bezier3funcY(double uu, Point[] controlP){double part0 = controlP[0].Y * uu * uu * uu;double part1 = 3 * controlP[1].Y * uu * uu * (1 - uu);double part2 = 3 * controlP[2].Y * uu * (1 - uu) * (1 - uu);double part3 = controlP[3].Y * (1 - uu) * (1 - uu) * (1 - uu);return part0 + part1 + part2 + part3;}
 public void GetControlPoint(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, double smooth_value){// 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 = Math.Sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));double len2 = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));double len3 = Math.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].///两个控制点double ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;double ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;double ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;double ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;}
void curve4(List<Point> p,double x1, double y1,   //Anchor1double x2, double y2,   //Control1double x3, double y3,   //Control2double x4, double y4)   //Anchor2{int step = 20;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 / (step + 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;// 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 > 0){step--;fx += dfx;fy += dfy;dfx += ddfx;dfy += ddfy;ddfx += dddfx;ddfy += dddfy;p.Add(new Point(fx, fy));}p.Add(new Point(x4, y4)); // Last step must go exactly to x4, y4}

这篇文章里的代码的C#版本 (穿过已知点画平滑曲线(3次贝塞尔曲线)相关推荐

  1. ROS实现串口GPS数据的解析与通信(这篇文章所用的代码和我买的带有ROS功能包的GPS模块的功能包的代码一样)

    我发现这篇文章所用的代码和我买的带有ROS功能包的GPS模块的功能包的代码一样!!! https://gitee.com/maxibooksiyi/gps_driver 转载自:https://blo ...

  2. 「收藏」关于机器学习的知识点,全在这篇文章里了

    尊重原创版权: https://www.qingtianxiaoshuo.com/hot/44432.html 更多内容参考: https://www.qingtianxiaoshuo.com/ 「收 ...

  3. 关于机器学习的知识点,全在这篇文章里了

    导读:作者用超过1.2万字的篇幅,总结了自己学习机器学习过程中遇到知识点."入门后,才知道机器学习的魅力与可怕."希望正在阅读本文的你,也能在机器学习上学有所成. 本文为「大数据」 ...

  4. 关于Java字符串的全部,就在这篇文章里了

    String 可以说是 Java 中最常见的数据类型,用来表示一串文本,它的使用频率非常高,为了小伙伴们着想,我怒肝了一周,把字符串能写的全都写了出来. 来看一下脑图吧,感受一下这份手册涉及到的知识点 ...

  5. JavaScript基础内功系列,这十篇文章里一定有你感兴趣的

    前端基础内功 这里总结了最经典.出镜率最高的一部分前端基础.希望能帮助自己和其他初级.中级前端同学打牢基础更进一步,加油! 前言 喜欢武侠或热衷武侠游戏的小伙伴门肯定了解,门派的弟子们在学习上乘武功大 ...

  6. 1万+字原创读书笔记,机器学习的知识点全在这篇文章里了

    作者 | 尘恋 来源 | 大数据(ID:hzdashuju) [导读]作者用超过1.2万字的篇幅,总结了自己学习机器学习过程中遇到知识点."入门后,才知道机器学习的魅力与可怕."希 ...

  7. txt转换epub如何转?你将在这篇文章里找到答案

    大家应该对txt文件不陌生吧,它作为众多电子书格式的一种,能够节省空间大小,便于在各个设备上浏览,但由于它只能存储文本内容,无法进行插入图片以及生成目录的操作,在阅读上给我们带来了一定的不便之处.而e ...

  8. 你想了解的所有树结构,都收集在这篇文章里了

    前言: <算法 第四版>官网 树结点类: public class TreeNode {Integer key; // 键Integer val; // 值TreeNode left; / ...

  9. 北京那些年轻人的秘密,都藏在这篇文章里

    这么大的北京,谁都有自己的秘密. 你可能永远都不会知道-- 平时在座位上似乎从来不动弹的开发小哥哥,业余时间是健身房的瑜伽教练: 隔壁team文文静静的小姐姐,周末是三里屯夜店的暖场女王: 坐在你旁边 ...

  10. 带你少走弯路:五篇文章学完吴恩达机器学习

    本文是吴恩达老师的机器学习课程[1]的笔记和代码复现部分,这门课是经典,没有之一.但是有个问题,就是内容较多,有些内容确实有点过时. 如何在最短时间学完这门课程?作为课程的主要翻译者和笔记作者,我推荐 ...

最新文章

  1. 秘籍 | 机器学习数据集网址大全
  2. 回归、分类与聚类:三大方向剖解机器学习算法的优缺点
  3. 关于eclipse中web项目tomcat报错Server Tomcat v9.0 Server at localhost failed to start问题解决
  4. android自定义布局实现优惠券效果
  5. SAP 用户账号管理系统
  6. struts的输入验证服务器端与客户端
  7. 深入研究java.lang.Runtime类,Process类
  8. hdu-5495 LCS(置换)
  9. codevs4919 线段树练习4
  10. 知识图谱构建通俗理解
  11. Origin2018-小白安装
  12. 弱监督学习综述(Weak Supervision 2019)
  13. python 中文分析句子成分_中文句子结构分析
  14. 管理文件夹,批量重命名排序
  15. SaaS模式、技术与案例详解——第17章 案例详解
  16. mongodb update操作
  17. 关于js阻止冒泡时的一些坑
  18. python爬取收费素材_基于Python爬取素材网站音频文件
  19. Uni-app 中使用 .ttf 字体图标
  20. DP动态规划--最大子段和问题

热门文章

  1. PMBOK(第五版)学习笔记 —— 3 项目管理过程
  2. 多人共同在线文档协同编辑的技术实现
  3. 5 windows PE COFF
  4. c语言2的n次方编程利用数组,1.6编程基础之一维数组_12计算2的N次方
  5. 积分墙为什么要做反作弊
  6. 汽车金融信用评分卡模型-论文_毕业设计_企业项目复现
  7. 羡慕别人表格做的快?6个Excel小技巧+25个Excel快捷键!收藏没错
  8. Excel如何插入可以打钩的方框
  9. Linux 服务器CPU占用率100%,使用率高解决方案
  10. js实现浏览器书签收藏