C#绘制带控制点的Bezier曲线,用于点阵图像及矢量图形
【摘要】不借助第三方, 使用c# + GDI+进行SVG等绘图,绘制带控制点的Bezier曲线。可用于点阵图像及矢量图形(如SVG)绘图。先看效果: (不知为何,已两次上传图片,无法显示,求助csdn)图注:使用方法二绘制。方法一: /// <summary> /// Bezier样条曲线 /// </summary> public static class BezierSpline {/// <summary>/// Get open-ended Bezier Spline Control Points./// </summary>/// <param name="knots">Input Knot Bezier spline points.</param>/// <param name="firstControlPoints">Output First Control points/// array of knots.Length - 1 length.</param>/// <param name="secondControlPoints">Output Second Control points/// array of knots.Length - 1 length.</param>/// <exception cref="ArgumentNullException"><paramref name="knots"/>/// parameter must be not null.</exception>/// <exception cref="ArgumentException"><paramref name="knots"/>/// array must contain at least two points.</exception>public static void GetCurveControlPoints(Point[] knots,out Point[] firstControlPoints, out Point[] secondControlPoints){if (knots == null)throw new ArgumentNullException("knots");int n = knots.Length - 1;if (n < 1)throw new ArgumentException("At least two knot points required", "knots");if (n == 1){ // Special case: Bezier curve should be a straight line.firstControlPoints = new Point[1];// 3P1 = 2P0 + P3firstControlPoints[0].X = (2 * knots[0].X + knots[1].X) / 3;firstControlPoints[0].Y = (2 * knots[0].Y + knots[1].Y) / 3;secondControlPoints = new Point[1];// P2 = 2P1 – P0secondControlPoints[0].X = 2 *firstControlPoints[0].X - knots[0].X;secondControlPoints[0].Y = 2 *firstControlPoints[0].Y - knots[0].Y;return;}// Calculate first Bezier control points// Right hand side vectordouble[] rhs = new double[n];// Set right hand side X valuesfor (int i = 1; i < n - 1; ++i)rhs[i] = 4 * knots[i].X + 2 * knots[i + 1].X;rhs[0] = knots[0].X + 2 * knots[1].X;rhs[n - 1] = (8 * knots[n - 1].X + knots[n].X) / 2.0;// Get first control points X-valuesdouble[] x = GetFirstControlPoints(rhs);// Set right hand side Y valuesfor (int i = 1; i < n - 1; ++i)rhs[i] = 4 * knots[i].Y + 2 * knots[i + 1].Y;rhs[0] = knots[0].Y + 2 * knots[1].Y;rhs[n - 1] = (8 * knots[n - 1].Y + knots[n].Y) / 2.0;// Get first control points Y-valuesdouble[] y = GetFirstControlPoints(rhs);// Fill output arrays.firstControlPoints = new Point[n];secondControlPoints = new Point[n];for (int i = 0; i < n; ++i){// First control pointfirstControlPoints[i] = new Point(x[i], y[i]);// Second control pointif (i < n - 1)secondControlPoints[i] = new Point(2 * knots[i + 1].X - x[i + 1], 2 *knots[i + 1].Y - y[i + 1]);elsesecondControlPoints[i] = new Point((knots[n].X + x[n - 1]) / 2,(knots[n].Y + y[n - 1]) / 2);}}/// <summary>/// Solves a tridiagonal system for one of coordinates (x or y)/// of first Bezier control points./// </summary>/// <param name="rhs">Right hand side vector.</param>/// <returns>Solution vector.</returns>private static double[] GetFirstControlPoints(double[] rhs){int n = rhs.Length;double[] x = new double[n]; // Solution vector.double[] tmp = new double[n]; // Temp workspace.double b = 2.0;x[0] = rhs[0] / b;for (int i = 1; i < n; i++) // Decomposition and forward substitution.{tmp[i] = 1 / b;b = (i < n - 1 ? 4.0 : 3.5) - tmp[i];x[i] = (rhs[i] - x[i - 1]) / b;}for (int i = 1; i < n; i++)x[n - i - 1] -= tmp[n - i] * x[n - i]; // Backsubstitution.return x;} }
方法二:
private void DrawCurve(Graphics g, PointF[] points, float tension)
{
int n=points.Length;
Pen rPen = new Pen(Color.Red, 2f);
Pen blPen= new Pen(Color.Blue, 1f);
Pen bzPen = new Pen(Color.DarkGoldenrod, 2f);
for (int i = 0; i < n; ++i)
{
// draw segment points[i] - points[(i + 1) % n]
var pPrev1 = points[(i - 1 + n) % n];
var p1 = points[i];
var p2 = points[(i + 1) % n];
var pAfter2 = points[(i + 2) % n];
// tangents 切线控制点
var t1 = new PointF(tension * (p2.X - pPrev1.X), tension * (p2.Y - pPrev1.Y));
var t2 = new PointF(tension * (pAfter2.X - p1.X), tension * (pAfter2.Y - p1.Y));
// interior Bezier control points
var c1 = new PointF(p1.X + t1.X / 3.0f, p1.Y + t1.Y / 3.0f);
var c2 = new PointF(p2.X - t2.X / 3.0f, p2.Y - t2.Y / 3.0f);
//画贝塞尔曲线
g.DrawBezier(bzPen, p1, c1, c2, p2);
//画关键点到切线控制点的直线
g.DrawLine(blPen, p1, c1);
g.DrawEllipse(rPen, p1.X - 2, p1.Y - 2, 4, 4);
g.DrawEllipse(rPen, c1.X - 2, c1.Y - 2, 4, 4);
g.DrawLine(blPen, p2, c2);
g.DrawEllipse(rPen, p2.X - 2, p2.Y - 2, 4, 4);
g.DrawEllipse(rPen, c2.X - 2, c2.Y - 2, 4, 4);
g.FillEllipse(new SolidBrush(Color.Green), new RectangleF(p1.X-2, p1.Y-2, 4, 4));
}
}
方法二的调用方法:
//这里使用的是Panel上绘图,其他控件(如PictureBox)道理一样。
Graphics g = pnlWorkArea.CreateGraphics();
g.Clear(Color.White);
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
PointF[] points = { new PointF(568,200),new PointF(168,110),new PointF(60,186),new PointF(300,191),new PointF(600,300),new PointF(800,431),new PointF(300,650), new PointF(568, 200) };
float tension=0.68f;
DrawCurve(g, points, tension);
这里有一个不错的链接:
C# GraphicsPath AddBeziers(params System.Drawing.Point[] points)
C# GraphicsPath AddBeziers(System.Drawing.PointF[] points)
源码也可以在此下载:C#带控制点的贝塞尔Bezier曲线算法(源码)-C#文档类资源-CSDN下载
C#绘制带控制点的Bezier曲线,用于点阵图像及矢量图形相关推荐
- 计算机图形学:Bezier曲线的绘制
1.实验目的 掌握Bezier曲线的定义原理及绘制过程 定义: 贝塞尔曲线(Bezier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出 ...
- rms | 如何绘制模型带置信区间的预测曲线
前段时间,有读者咨询如何绘制带置信区间的预测曲线.本篇介绍的rms工具包可以很简便地解决这个问题. 该包是Regression Modeling Strategies的附加学习资源,小编从网上找到了这 ...
- android曲线位移动画,Bezier曲线在Android动画中的应用
Android动画的开发中,为了达到更加酷炫的效果,常常需要自定义运动轨迹,或者绘制花式复杂的曲线,这正是Bezier曲线大显神通的地方,本文将带你了解Bezier曲线在Android开发中的一些应用 ...
- bezier曲线_Bezier算法
个人博客: vectormoon's blogwww.vectormoon.net bezier算法的背景 vm公司设计出了一个原型车--moon,这样的: 产品经理一看觉得有点抽象,他使用了Bez ...
- 计算机图形学E10——Bezier曲线
其他计算机图形学实验见 链接 #include<gl/glut.h> #include<iostream> #include<algorithm> #include ...
- 开源项目推荐:Bezier曲线、B-Spline和NURBS的区别与《THE NURBS BOOK 2nd》简介,曲线拟合可视化工具
一.基本概念 B-Spline:B样条曲线 NURBS(Non Uniform Rational B-Spline):非均匀有理B样条曲线 B样条曲线有三种类型: 当起始点和终止点的重复度为最高次数加 ...
- Bezier曲线、B样条和NURBS的基本概念
最不能理解的一点,一讨论软件的曲面,曲线功能,最后就变成曲线.曲面的数学原理的讨论了,但是里面也没数学好的,讨论的结果可想而知. 我不是数学家,我不懂这么复杂的方程,只要好用就行了. 在CAD中,设计 ...
- Bezier曲线曲面绘制
知识点: Bezier曲面性质 Bezier曲线简单理解 代码参考:https://blog.csdn.net/wpxu08/article/details/70208395 曲线 #include ...
- lisp 非对称缓和曲线_利用AutoLISP语言绘制带缓和曲线的铁路曲线平面图
利用 AutoLISP 语言绘制带缓和曲线的铁路曲线平面图 [ 摘要 ] 通过 AutoLISP 编程方法的剖析 , 探讨了基于 Visual LISP(VLISP) 编程软件环境下 , 利用 Aut ...
最新文章
- java word模板占位符_word模板导出的几种方式:第一种:占位符替换模板导出(只适用于word中含有表格形式的)...
- 读论文之《基于 FPGA 的并行全比较排序算法》
- 非mapreduce生成Hfile,然后导入hbase当中
- ClassLoader.getResourceAsStream(name);获取配置文件的方法
- nuxt解决首屏加载慢问题_如何解决百度云盘下载速度慢的问题
- STM32的2.02固件库提供的启动文件详解 stm32f10x_vector.s
- vs2017调试浏览器闪退
- 双水泵轮换工作原理图_周宁气压给水设备控制柜原理图
- 通过IF({1,0}和VLOOKUP函数实现Excel的双条件多条件查找的方法
- CDR真实图片转水墨画效果制作教程
- 等差数列和等比数列公式
- 浅谈国内域名注册商与国外域名注册商的区别与优势
- 【python】使用pushplus实现警报微信提醒,提供代码和详细注释
- 如何用python爬取数据_入门用Python进行Web爬取数据:为数据科学项目提取数据的有效方法...
- Android逆向学习(1)--记一次破解某直播盒子App
- 【继上篇】云计算架构概念和技术基础
- 运用Python+Pygame开发坦克大战游戏_版本V1.01
- Why Littlefinger says ‘an historic day‘ not ‘a historic day‘?
- HDU - 3594 Cactus (仙人掌图)
- OLED屏幕和LCD屏幕的区别与优劣
热门文章
- 组合数奇偶性判定方式
- 在nginx日志的access log中记录post请求的参数值
- java计算数据的百分比
- windows优化大师怎么用_win7系统提示未能连接一个windows服务如何解决【详解】
- 那些年跳过的坑--编码格式(记事本 + WinSCP + MyEclipse)
- Linux c语言 creat参数,C++_使用C语言操作文件的基本函数整理,C语言creat()函数:创建文件函 - phpStudy...
- 【Java 8 新特性】Java Supplier示例
- 活性炭去甲醛的原理!
- AAA云主机免费推荐码
- leetcode 字母异位词分组(js实现)