当前位置:网站首页>C # draw Bezier curve with control points for lattice images and vector graphics
C # draw Bezier curve with control points for lattice images and vector graphics
2022-07-05 09:07:00 【Dakeshan people】
【 Abstract 】 Without the help of a third party , Use c# + GDI+ Conduct SVG Equal drawing , Draw with control points Bezier curve . It can be used for dot matrix images and vector graphics ( Such as SVG) mapping .
Look at the effect :
( I don't know why , Pictures have been uploaded twice , Unable to display , For help csdn)
Figure note : Use method 2 to draw .
Method 1 :
/// <summary>
/// Bezier Splines
/// </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 + P3
firstControlPoints[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 – P0
secondControlPoints[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 vector
double[] rhs = new double[n];
// Set right hand side X values
for (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-values
double[] x = GetFirstControlPoints(rhs);
// Set right hand side Y values
for (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-values
double[] y = GetFirstControlPoints(rhs);
// Fill output arrays.
firstControlPoints = new Point[n];
secondControlPoints = new Point[n];
for (int i = 0; i < n; ++i)
{
// First control point
firstControlPoints[i] = new Point(x[i], y[i]);
// Second control point
if (i < n - 1)
secondControlPoints[i] = new Point(2 * knots
[i + 1].X - x[i + 1], 2 *
knots[i + 1].Y - y[i + 1]);
else
secondControlPoints[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;
}
}
Method 2 :
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 Tangent control points
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);
// Draw Bezier curve
g.DrawBezier(bzPen, p1, c1, c2, p2);
// Draw a straight line from the key point to the tangent control point
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));
}
}
Calling method of method 2 :
// What we use here is Panel Draw on , Other controls ( Such as PictureBox) It's the same thing .
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);
Here is a good link :
C# GraphicsPath AddBeziers(params System.Drawing.Point[] points)
C# GraphicsPath AddBeziers(System.Drawing.PointF[] points)
The source code can also be downloaded here :C# Bessel with control points Bezier Curve algorithm ( Source code )-C# Document resources -CSDN download
边栏推荐
- Halcon Chinese character recognition
- Use arm neon operation to improve memory copy speed
- nodejs_ fs. writeFile
- AdaBoost use
- [daiy4] copy of JZ35 complex linked list
- Codeworks round 639 (Div. 2) cute new problem solution
- 优先级队列(堆)
- Information and entropy, all you want to know is here
- np.allclose
- 混淆矩阵(Confusion Matrix)
猜你喜欢
生成对抗网络
Applet (global data sharing)
Beautiful soup parsing and extracting data
微信H5公众号获取openid爬坑记
容易混淆的基本概念 成员变量 局部变量 全局变量
[Niuke brush questions day4] jz55 depth of binary tree
Confusion matrix
深度学习模型与湿实验的结合,有望用于代谢通量分析
Ros-10 roslaunch summary
[code practice] [stereo matching series] Classic ad census: (5) scan line optimization
随机推荐
Return of missing persons
使用arm Neon操作,提高内存拷贝速度
Array,Date,String 对象方法
fs. Path module
Applet (global data sharing)
Meta tag details
golang 基础 —— golang 向 mysql 插入的时间数据和本地时间不一致
什么是防火墙?防火墙基础知识讲解
c#比较两张图像的差异
[code practice] [stereo matching series] Classic ad census: (5) scan line optimization
Chris LATTNER, the father of llvm: why should we rebuild AI infrastructure software
2020 "Lenovo Cup" National College programming online Invitational Competition and the third Shanghai University of technology programming competition
ROS learning 1- create workspaces and function packs
信息与熵,你想知道的都在这里了
Programming implementation of ROS learning 2 publisher node
Characteristic Engineering
Adaboost使用
The location search property gets the login user name
一题多解,ASP.NET Core应用启动初始化的N种方案[上篇]
Ros-11 common visualization tools