在处理Dwg图纸的时候,有时候会遇到曲线(Curve)。经过研究发现,曲线的真正定义为Spline,而采用的图形为 非均匀B样条曲线。

作为B样条曲线,可以通过添加多个控制点来控制曲线的细节,而这正是贝塞尔曲线做不到的。同时,修改某个控制点的位置也仅仅修改该控制点附近的曲线。

关于B样条的数学方程的代码很多,例如:

http://blog.csdn.net/tingzhushaohua/article/details/71437169?locationNum=13&fps=1

在这里我们直接找到一个可以用的类库来使用:

 public enum BsplineType{Uniform,//均匀B样条QuasiUniform,//准均匀B样条PiecewiseBezier,//分段贝奇尔NonUniform,//非均匀B样条Null
}
public class BsplineCurve{/// <summary>/// 取样数量/// </summary>public double LinePoint = 10.0;#region 参数private int n;//曲线控制顶点数private int k;//曲线次数public BsplineType curve_type;//B样条曲线类型List<double> Bvalue = new List<double>();/*******节点矢量******/public List<double> knots_value = new List<double>();//节点矢量相异节点public List<int> knots_muti = new List<int>();//节点矢量重复度/******控制顶点及权因子*****/public List<Pos> ControlPoint = new List<Pos>();//控制顶点序列public List<double> wlist = new List<double>();//控制顶点的权因子序列/******曲线上点序列及基函数点序列*****/public List<Pos> CurvePoint = new List<Pos>();//样条曲线上的点的序列public List<List<Pos>> BasicFuncPoint = new List<List<Pos>>();//B样条基函数点列#endregionpublic BsplineCurve()//默认构造函数{n = 0;k = 0;curve_type = BsplineType.QuasiUniform;}public BsplineCurve(BsplineType type, int times, List<Pos> plist)//参数构造函数{curve_type = type;this.k = times;this.n = plist.Count - 1;ControlPoint.AddRange(plist);for (int i = 0; i <= n; i++){wlist.Add(1);}}#region 四种类型B样条 节点矢量的创建private void GenerateKnots()//节点矢量创建及方法选择{/*对于4种B样条曲线类型,有4种节点矢量生成方式*/switch (curve_type){case BsplineType.Uniform:CreateKnots_Uniform();break;case BsplineType.QuasiUniform:CreateKnots_QuasiUniform();break;case BsplineType.PiecewiseBezier:CreateKnots_PiecewiseBezier();break;case BsplineType.NonUniform:CreateKnots_NonUniform();break;default:// MessageBox.Show("节点矢量生成出错!!");break;}}private void CreateKnots_Uniform()//均匀B样条节点矢量创建{knots_muti.Clear();knots_value.Clear();double temp, ui = 0;int i;//生成均匀B样条的节点矢量temp = 1.0 / (n - k + 1);ui = -k * temp;for (i = 0; i <= n + k + 1; i++){knots_value.Add(ui);knots_muti.Add(1);ui += temp;}}private void CreateKnots_QuasiUniform()//准均匀B样条节点矢量创建{knots_muti.Clear();knots_value.Clear();double temp, ui = 0;int i;temp = 1.0 / (n - k + 1);ui = 0;for (i = 0; i <= n - k + 1; i++){knots_value.Add(ui);knots_muti.Add(1);ui += temp;}//首末节点重复度为K+1重knots_muti[0] = k + 1;knots_muti[n - k + 1] = k + 1;}private void CreateKnots_PiecewiseBezier()//分段Bezier曲线点矢量创建{knots_muti.Clear();knots_value.Clear();int i, j;double temp = 0;double ui;if (n % k == 0){i = n / k;temp = 1.0 / i;ui = 0;for (j = 0; j <= i; j++){knots_value.Add(ui);knots_muti.Add(k);ui += temp;}knots_muti[0]++;knots_muti[i]++;}else{// MessageBox.Show("n/k != 整数");}}private void CreateKnots_NonUniform()//非均匀B样条节点矢量创建{knots_muti.Clear();knots_value.Clear();/*******采用Hartley-Judd方法**********/List<double> lengthi = new List<double>();List<double> molecule = new List<double>();molecule.Clear();lengthi.Clear();double deltaX, deltaY, length, temp, denominator = 0;int i, j;for (i = 1; i <= n; i++){deltaX = ControlPoint[i].X - ControlPoint[i - 1].X;deltaY = ControlPoint[i].Y - ControlPoint[i - 1].Y;length = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);lengthi.Add(length);}knots_value.Add(0);knots_muti.Add(k + 1);//计算分母denominator,每一项的分子molecule[i]for (i = 1; i <= n - k + 1; i++){temp = 0;for (j = i; j <= i + k - 1; j++){temp += lengthi[j - 1];denominator += lengthi[j - 1];}molecule.Add(temp);}for (i = 1; i <= n - k; i++){knots_value.Add(knots_value[i - 1] + molecule[i - 1] / denominator);knots_muti.Add(1);}knots_value.Add(1);knots_muti.Add(k + 1);}#endregion#region 计算曲线上的离散点public void CreateCurve()//计算B样条曲线离散点{int i, j;double u = 0;double du = 0;double h = 0.02;Bvalue.Clear();for (j = 0; j <= k; j++){Bvalue.Add(1.0);}GenerateKnots();//创建节点矢量CurvePoint.Clear();BasicFuncPoint.Clear();for (j = 0; j <= n; j++){BasicFuncPoint.Add(new List<Pos>());}u = 0;for (i = 0; i <= n; i++){if (knots_value[i] > 0) break;}//Find the first more than 0for (; i < knots_value.Count() && knots_value[i] <= 1.00000001; i++){du = knots_value[i];h = (knots_value[i] - knots_value[i - 1]) / LinePoint;do{AddCurvePoint(u);u += h;}while (u < du);u = du;}//此时u==1,但未计算u=1处的点坐标,故手动计算节点为1的AddCurvePoint(1);if (curve_type == BsplineType.Uniform)CalculateUniformBfunc1st();}private void AddCurvePoint(double u){int i;double tempx, tempy;double sum;int j;bool Isnode = false;for (i = k + 1; i <= n; i++)//确定u所在区间号,u-[ui,ui+1]{if (u < KnotValue(i))break;}i--;//确定u所在子区间/*Bvalue为基函数Ni,--Ni+p在u点的值*/if (u == KnotValue(i) && u > 0)Isnode = true;CalculateBvalue(u, i);for (j = 0; j <= k; j++){BasicFuncPoint[i - k + j].Add(new Pos((float)u, (float)Bvalue[j]));}if (Isnode == true)BasicFuncPoint[i - k - 1].Add(new Pos((float)u, (float)Bvalue[k]));tempx = 0;tempy = 0;sum = 0;for (j = 0; j <= k; j++){sum += Bvalue[j] * wlist[i - k + j];}for (j = 0; j <= k; j++){tempx += Bvalue[j] * wlist[i - k + j] / sum * ControlPoint[i - k + j].X;tempy += Bvalue[j] * wlist[i - k + j] / sum * ControlPoint[i - k + j].Y;}CurvePoint.Add(new Pos((float)tempx, (float)tempy));}private double KnotValue(int j)//计算节点j的值,考虑节点重复度{double u = 0;int l = knots_value.Count;int index = 0;for (int i = 0; i < l; i++){index += knots_muti[i];if (index - 1 >= j){u = knots_value[i];break;}}return u;}private void CalculateBvalue(double u, int i)//计算每一点的基函数值{int j, r;double temp = 0, saved = 0;List<double> left = new List<double>();List<double> right = new List<double>();for (j = 0; j <= k; j++){left.Add(1);right.Add(1);}Bvalue[0] = 1;for (j = 1; j <= k; j++){left[j] = u - KnotValue(i + 1 - j);right[j] = KnotValue(i + j) - u;saved = 0;for (r = 0; r < j; r++){temp = Bvalue[r] / (right[r + 1] + left[j - r]);Bvalue[r] = saved + right[r + 1] * temp;saved = left[j - r] * temp;}Bvalue[j] = saved;}}private void CalculateUniformBfunc1st()//计算均匀B样条的基函数{double dh, u;List<double> knoth = new List<double>();List<double> Bfunc = new List<double>();int i, j, r;double temp = 0, saved = 0;List<double> left = new List<double>();List<double> right = new List<double>();for (j = 0; j <= k; j++){left.Add(1);right.Add(1);}dh = knots_value[1] - knots_value[0];temp = -k * dh;for (i = 0; i < 3 * k + 2; i++){knoth.Add(temp + i * dh);}for (i = 0; i <= k; i++)Bfunc.Add(1);dh /= 5;u = 0;BasicFuncPoint[0].Clear();for (i = k; i < 2 * k + 1; i++){while (u <= knoth[i + 1]){Bfunc[0] = 1;for (j = 1; j <= k; j++){left[j] = u - knoth[i + 1 - j];right[j] = knoth[i + j] - u;saved = 0;for (r = 0; r < j; r++){temp = Bfunc[r] / (right[r + 1] + left[j - r]);Bfunc[r] = saved + right[r + 1] * temp;saved = left[j - r] * temp;}Bfunc[j] = saved;}u += dh;BasicFuncPoint[0].Add(new Pos((float)u, (float)Bfunc[2 * k - i]));}}}#endregion}

调用的代码如下:

BsplineCurve bc = new BsplineCurve(BsplineType.NonUniform, item.Degree,item.Points);
bc.CreateCurve();
var points = bc.CurvePoint;

绘制AutoCad中的曲线(Curve)相关推荐

  1. python绘制缓和曲线_CAD中缓和曲线的画法 - AutoCAD基础应用 - CAD论坛 - 明经CAD社区 - Powered by Discuz!...

    在AutoCAD中缓和曲线的几种画法,其实在AutoCAD中,想要画出缓和的曲线是一项比较困难的工作,目前常见的画法可以分为以下的这几种: 1.AutoLISP程序法,使用这个方法要求用户掌握已知的曲 ...

  2. pline加点lisp_用Autolisp 在AutoCAD中实现多种曲线的绘制

    用Autolisp 在AutoCAD中实现多种曲线的绘制 一.引言: AutoCAD自1982年由Autodesk公司推出以来,经历了20年的发展更新,目前,已深入到包括机械.建筑.服装.航天航空.地 ...

  3. 如何用lisp画蔓叶线_用Autolisp 在AutoCAD中实现多种曲线的绘制

    用 Autolisp 在 AutoCAD 中实现多种曲线的绘制 一.引言: AutoCAD 自 1982 年由 Autodesk 公司推出以来, 经历了 20 年的发展更 新,目前,已深入到包括机械. ...

  4. python画两条曲线_查找在matplotlib中绘制的两条曲线之间的区域(在区域之间填充)...

    我有两条曲线的x和y值列表,它们都有奇怪的形状,而且我没有任何函数.我需要做两件事:(1)绘制它并对曲线之间的区域进行着色,如下图所示:(2)找到曲线之间该着色区域的总面积. 在matplotlib中 ...

  5. js绘制的漂亮玫瑰曲线rose curve

    js绘制的漂亮玫瑰曲线rose curve,在数学上 玫瑰 或 罗多纳 曲线 是用极坐标绘制的正弦曲线.基本极性方程是 r = a sin(kθ) 这些曲线是由意大利数学家命名的 Guido Gran ...

  6. R语言使用pROC包在同一图中绘制两条ROC曲线并通过假设检验检验ROC曲线的AUC或者偏AUC的差异(输出p值)

    R语言使用pROC包在同一图中绘制两条ROC曲线并通过假设检验检验ROC曲线的AUC或者偏AUC的差异(输出p值) 目录

  7. 用C语言绘制任意阶贝塞尔曲线(Bézier curve)

    计算机图形学中贝塞尔曲线的绘制.使用的开发软件及版本为VS2015,以及 EasyX库.实现动态演示贝塞尔曲线实现的过程,且阶次不限! 源代码获取方式:1.添加微信(微信号:my_12581)获取.2 ...

  8. Android自定义控件之绘制选矿中的可选性曲线

    WashView WashView是一个绘制四坐标轴的光滑曲线的控件,主要用于绘制煤矿中的可选性曲线 项目地址:https://github.com/zfman/WashView 可选性曲线 原始数据 ...

  9. 计算机图形学中的曲线问题——贝塞尔曲线的绘制

    贝塞尔曲线的绘制 由于 CSDN 的博客修改字数的限制,我们不得不将这一部分放到一个新的博客中.原文详见: GGN_2015 计算机图形学中的曲线问题 贝塞尔曲线的几何作图法 在上面介绍儿时的回忆中, ...

  10. ROC曲线是什么?ROC曲线是怎么绘制的?ROC曲线的横纵坐标是什么?如何用Python绘制?AUC又是什么?

    ROC曲线是什么?ROC曲线是怎么绘制的?ROC曲线的横纵坐标是什么?AUC又是什么? metrics.roc_auc_score metrics.roc_curve ROC= Receiver Op ...

最新文章

  1. 人工智能 MIT 博士系列讲课
  2. 扫地机器人从“玩具”到“工具”,科沃斯、云鲸们要如何扫开屏障?
  3. ai入门视频,亲测有效
  4. opencv3.2.0 Cmake 3.8.0 + tdm-gcc-5.1.0-3
  5. duration java_Java Duration类| ofHours()方法与示例
  6. 换手率与股价成交量 关系
  7. 从上到下打印二叉树的三种题型
  8. 【转载】【C基础】#define宏定义中的#,##,@#,\ 这些符号的神奇用法
  9. delphi10 ftp文件名乱码问题
  10. 用tbtools基因家族分析《一》
  11. NDoc - .NET 代码文档生成器
  12. 编程狂人|后台服务架构高性能设计之道
  13. 一个阿里前端工程师的成长之路
  14. 【VIO笔记(学习VINS的必备基础)】第五讲(1/2) 手写VIO后端
  15. ★互联网告别免费时代,准备…
  16. 动态规划(八):子序列系列
  17. Python接私活,兼职也可以月入10000+。Python爬虫兼职
  18. sqrt函数的几种实现方法
  19. 道路交通实时流量监控预测系统
  20. 自媒体人如何提高写作水平,创造出爆款文章?这五点很重要

热门文章

  1. 关于windows 7 启动 security center
  2. hp1020plus网络打印机服务器
  3. 狮子鱼小程序独立版安装配置教程
  4. Android Studio 导入安卓源码步骤
  5. 精简版XP安装IIS
  6. filezilla linux服务器端,FileZilla Server安装配置教程
  7. 《交互设计沉思录》译序
  8. 如何反编译dll文件
  9. Why 自动化交易/程序化交易/量化交易?交易软件有哪些?
  10. Java 匹配域名正则表达式