GDI+: Curved Shapes

原文 http://www.functionx.com/vcsharp2003/gdi/curves.htm

Curves

 

Introduction to Curves

 

A curve is a line that joins two or more points. If only two points are involved, the line would join them. If there are three points A, B, and C, the line would start on the first point A, cross the second point B, and stop at the last point C. If more than three points are involved, the line would start on the first, cross the second, cross the third and each line before stopping on the last. The points of a curve don't have to be aligned. In fact, the whole idea of drawing a curve is to have a non-straight line that joins different non-aligned points. This can be illustrated with the following three curves labeled C1, C2, and C3:

The first curve, C1, includes only two points. The second, C2 includes three points. The third, C3, includes four points. The section between two points is called a segment. This also means that a curve can be distinguished by the number of segments it has. If a curve is made of only two points, this means that it has only one segment from the first to the second, which is the last, point. If a curve includes three points, it has two segments. The first segment spans from the first point to the second point and the second segment spans from the second point to the third point. Based on this, the number of segments of a curve is equal to the number of its points - 1.

A curve can be drawn in GDI+ using the Graphics.DrawCurve() method. When drawing a curve, you must specify how many points would be involved. This means that you can first declare an array of Point or PointF values. Because it is left up to you to decide on this issue, the Graphics class provides the following syntaxes of the DrawCurve() method:

public void DrawCurve(Pen pen, Point[] points);
public void DrawCurve(Pen pen, PointF[] points);

This version of the method takes an array of Point or PointF values as arguments. The number of members of the array depends on you. Here is an example that uses four points to draw a curve with three segments:

private void Form1_DoubleClick(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);Point[] pt     = { new Point(40,  42), new Point(188, 246),new Point(484, 192), new Point(350,  48) };graph.DrawCurve(penCurrent, pt);
}

This would produce:

As you can see, when the curve is draw, a bent line crosses the intermediary points between the first and the last. To make the lines non-straight, the compiler uses a value called tension used to bend the line. If you want, you can specify the bending factor that should be applied. To do this, you would use the version version of the DrawCurve()method:

public void DrawCurve(Pen pen,Point[] points,float tension);
public void DrawCurve(Pen pen,PointF[] points,float tension);

The amount of bending to apply is passed as the tension argument. It can be passed as a decimal value >= 0.00. If this value is passed as 0.00, the lines would be drawn straight. Here is an example:

private void Form1_DoubleClick(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);Point[] pt     = { new Point(40,  42), new Point(188, 246),new Point(484, 192), new Point(350,  48) };graph.DrawCurve(penCurrent, pt, 0.00F);
}

This means that, if you want a real curve, either you don't pass the tension argument and use the first version of the method or you pass the tension argument as a value higher than 0.00. Here is an example:

private void Form1_DoubleClick(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);Point[] pt     = { new Point(40,  42), new Point(188, 246),new Point(484, 192), new Point(350,  48) };graph.DrawCurve(penCurrent, pt, 2.15F);
}

This would produce:

Both versions of the DrawCurve() method that we have used allow you to start the curve on the first point. Consider the following example that draws a curve of five points resulting in four segments:

private void Form1_DoubleClick(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);PointF[] pt     = {   new PointF(20F,  322F), new PointF(124, 24),new PointF(214, 242), new PointF(275,  28),new PointF(380F,  322F) };graph.DrawCurve(penCurrent, pt);
}

This would produce:

If you want, you can start the curve on any point instead of the first. To support this, the Graphics class provides the following version of the DrawCurve() method:

public void DrawCurve(Pen pen,PointF[] points,int offset,int numberOfSegments);

The offset argument allows you to specify how many points should be skipped before starting to draw. The first conclusion is that the value of the offset must be 0 or higher. If you pass this argument as 0, the curve would be drawn from the first point. If you pass this argument as 1, the first point would not be considered in the curve. This means that the drawing of the curve would start on the second point and so on. If you pass it as 2, the first and the second point would not be part of the curve, meaning that the curve would start on the third point.

After the curve has started from the point you specify using the offset argument, you can then specify how many segments of the curve would be drawn. This number must be lower than the number of available segments, that is after subtracting the offset value from the total number of segments of the array. Here is an example:

private void Form1_DoubleClick(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);PointF[] pt     = {   new PointF(20F,  322F), new PointF(124, 24),new PointF(214, 242), new PointF(275,  28),new PointF(380F,  322F) };graph.DrawCurve(penCurrent, pt, 1, 2);
}

This would produce:

Once again, the compiler arranges to apply a tension when drawing the curve. If you would prefer to use straight lines or to apply a different tension than the default, you can use the following version of the Graphics.DrawCurve() method:

public void DrawCurve(Pen pen,Point[] points,int offset,int numberOfSegments,float tension);
public void DrawCurve(Pen pen,PointF[] points,int offset,int numberOfSegments,float tension);

This time, you can pass the value of the tension as 0 to get straight lines:

private void Form1_DoubleClick(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);PointF[] pt     = {   new PointF(20F,  322F), new PointF(124, 24),new PointF(214, 242), new PointF(275,  28),new PointF(380F,  322F) };graph.DrawCurve(penCurrent, pt, 0, 4, 0);
}

This would produce:

Or you can pass the tension with any positive value of your choice. Here is an example:

private void Form1_DoubleClick(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);PointF[] pt     = {   new PointF(20F,  322F), new PointF(124, 24),new PointF(214, 242), new PointF(275,  28),new PointF(380F,  322F) };graph.DrawCurve(penCurrent, pt, 1, 3, 1.750F);
}

This would produce:

A B閦ier Curve

 

A b閦ier curve is a continuous line that is drawn using four points that are not necessarily aligned. It can be illustrated as follows:

To draw this line (with four points), the compiler would draw a curve from the first point to the fourth point. Then it would bend the curve by bringing each middle (half-center) side close to the second and the third points respectively, without touching those second and third points. For example, the above b閦ier curve could have been drawn using the following four points:

To draw a b閦ier curve, the Graphics class provides the DrawBezier() method that is overloaded in three versions whose syntaxes are:

public void DrawBezier(Pen pen,Point pt1,Point pt2,Point pt3,Point pt4);
public void DrawBezier(Pen pen,PointF pt1,PointF pt2,PointF pt3,PointF pt4);
public void DrawBezier(Pen pen,float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4);

Based on this, to draw a b閦ier line, you can use either four Point or PointF values or the coordinates of the four points. Here is an example:

private void button1_Click(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);Point pt1 = new Point(20,  12),pt2 = new Point(88, 246),pt3 = new Point(364, 192),pt4 = new Point(250,  48);graph.DrawBezier(penCurrent, pt1, pt2, pt3, pt4);
}

This would produce:

A Series of B閦ier Curves

 

The Graphics.DrawBezier() method is used to draw one b閦ier curve. If you want to draw many b閦ier curves, you can call the Graphics.DrawBeziers() method that is overloaded in two versions as follows:

public void DrawBeziers(Pen pen, Point[] points);
public void DrawBeziers(Pen pen, PointF[] points);

The DrawBeziers() method requires an array of Point of PointF values. When working with only four coordinates, the DrawBeziers() method works exactly like DrawBezier(), the different is that, while DrawBezier() expects four Point or four PointF values,DrawBeziers() expects an array of Point or PointF values. Using, DrawBeziers(), the above b閦ier curve can be drawn as follows and produce the same result:

private void button1_Click(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);Point[] pt = { new Point(20,  12), new Point(88, 246),new Point(364, 192), new Point(250,  48) };graph.DrawBeziers(penCurrent, pt);
}

The advantage of using DrawBeziers() is that it allows you to draw a b閦ier curve using 7Point or PointF values. Here is an example:

private void button1_Click(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Blue);Point[] pt = { new Point( 10,  5), new Point(340, 60),new Point(320, 148), new Point(150, 120),new Point(24, 220), new Point(250, 150),new Point(304, 240) };graph.DrawBeziers(penCurrent, pt);
}

This would produce:

A Closed Curve

 

If you use either the DrawLines(), the DrawBezier() or the DrawBeziers() methods, you would get a continuous line or a series of lines that has a beginning and an end. Alternatively, GDI+ allows you to draw a series of lines but join the end of the last line to the beginning of the first line to have a closed shape. To draw this figure, you can call theGraphics.DrawClosedCurve() method that is overloaded in four versions. Two of them have the following syntaxes:

public void DrawClosedCurve(Pen pen,Point[] points);
public void DrawClosedCurve(Pen pen,PointF[] points);

These two versions are the easiest to use. They allow you to provide an array of fourPoint or four PointF values. When executed, each of these methods gets together draws a curve that passes through each coordinate and closes the curve by joining the end point to the first unless both points are the same. Here is an example:

private void Form1_DoubleClick(object sender, System.EventArgs e)
{Graphics graph  = this.CreateGraphics();Pen penCurrent = new Pen(Color.Red);Point[] pt           = { new Point(40,  42), new Point(188, 246),new Point(484, 192), new Point(350,  48) };graph.DrawClosedCurve(penCurrent, pt);
}

This would produce:

The first two versions are used to draw the lines but curve them in order to make the shape appear smooth. If you want, you can draw the lines straight from one point to the next without curving them. Using this scenario, the above shape would appear as follows:

To draw this type of shape using the ClosedCurve() method, you can use one of the following versions of the method:

public void DrawClosedCurve(Pen pen,Point[] points,float tension,FillMode fillmode);
public void DrawClosedCurve(Pen pen,PointF[] points,float tension,FillMode fillmode);

These versions allow you to specify the tension and the fill mode. The tension factor allow you to specify how much curve would be applied. If this value is passed as 0.00, the points would be joined with straight lines. Otherwise, you can apply a tension using an appropriate decimal value.

The fillmode factor determines how the interior of the curve would be filled. It is controlled through the FillMode enumerator that is defined in the System.Drawing.Drawing2Dnamespace. The FillMode enumerator has two members: Alternate and Winding. Here is an example:

private void Form1_DoubleClick(object sender, System.EventArgs e)
{Graphics graph = this.CreateGraphics();Pen penCurrent = new Pen(Color.Red);Point[] pt     = { new Point(40,  42), new Point(188, 246),new Point(484, 192), new Point(350,  48) };graph.DrawClosedCurve(penCurrent, pt, 0.75F, FillMode.Winding);
}

This would produce:

posted on 2014-01-14 21:51 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/3519833.html

GDI+: Curved Shapes相关推荐

  1. 【数字化】PLM视角下,数字化工厂的构建之道!

    本文立足智能制造,从PLM视角下,提出了数字化工厂的概念,确立了其内涵与定位.针对数字化工厂的通用技术.应用技术.业务活动及管理等内容开展研究和分析,形成了数字化工厂的技术体系框架,并给出了支撑数字化 ...

  2. 论文阅读:CVPR2016 Paper list

    原文地址:http://blog.csdn.net/xizero00/article/details/51386667 在过几天CVPR2016就要召开了,先放个list. ORAL SESSION ...

  3. photoshop标尺工具_如何在Photoshop中使用和掌握非常困难的钢笔工具

    photoshop标尺工具 Photoshop and Illustrator both have a dark point many users choose to avoid-the notori ...

  4. CVPR 2016 摘要阅读

    为了说明看过CVPR2016全部文章的摘要,总结一下,摘要只保留了创新点部分. ORAL SESSION Image Captioning and Question Answering Monday, ...

  5. CVPR 2016 全部文章摘要阅读

    为了说明看过CVPR2016全部文章的摘要,总结一下,摘要只保留了创新点部分. ORAL SESSION Image Captioning and Question Answering Monday, ...

  6. 10 Fun Things to do with Tessellation

    10 Fun Things to do with Tessellation 原文地址:http://castano.ludicon.com/blog/2009/01/10/10-fun-things- ...

  7. 形状分析在植物种类鉴定方面的应用

    背景介绍 相关文献 预处理步骤 基于srv-framework的分类 背景介绍 叶片分类问题难点是叶片表面性质不同引起的光强改变,叶片部分包卷,缺损,虫蛀的情况.这类问题不适合使用图像数据进行识别和判 ...

  8. Win32 GDI 学习总结

    Windows GDI 教程(一) 一个简单的绘图程序 http://www.tuicool.com/articles/jeMBZ3v 常见的图形编程库,除了 GDI 外还有 GDI+.OpenGL. ...

  9. 戏说 .NET GDI+系列学习教程(三、Graphics类的应用_验证码)

    关于Graphics也有了基本了解下面想说的的是学这个东东干什么呢,到底如何应用 目前常见应用 1.验证码(参照网上的) 2.打印排版(会提到关于条形码大小设置) 3.自定义控件 一.验证码 1 cl ...

最新文章

  1. [No000039]操作系统Operating Systems用户级线程User Threads
  2. TensorFlow学习笔记:共享变量
  3. Py之glob: glob库文件名模式匹配+返回所有匹配的文件路径列表库的简介、使用方法之详细攻略
  4. 【深度学习】陶大程等人编写!最新41页深度学习理论综述
  5. cesium js 路径_Cesium开发学习路径
  6. 亲自己主动手从源代码 构建 Groovy 2.3.8 公布包
  7. 用sniffer技术盗取电话银行密码
  8. puppet puppet模块、file模块
  9. oracle flashback 深入研究,oracle 之flashback 深入研究。
  10. IE6下透明PNG图片的显示
  11. 电商人:别再跟数据透视表苦苦挣扎,这个报表神器才是你最后出路
  12. Android 编程下 Using ViewPager for Screen Slides
  13. linux c 静态连接,Linux cmake 静态链接boost
  14. UDS协议(车辆控制单元诊断系统开发架构及DID读取数据流程)
  15. html怎么获取手机mac地址,js获取mac地址_Js获取客户端IP地址与MAC地址
  16. 山上有一口缸可以装50升水,现在有15升水。老和尚叫小和尚下山挑水,每次可以挑5升。问:小和尚要挑几次水才可以把水缸挑满?通过编程解决这个问题。
  17. Android11(R) system_ext 分区 system_ext_specific 属性
  18. Source Insight 常用颜色代表种类
  19. el-tree 关键字搜索
  20. iPhone 手机修复屏幕划痕

热门文章

  1. php实现单笔转账到支付宝功能
  2. c++第九次作业(谭浩强c++程序设计第三版P400习题)
  3. 首季度NAND闪存市场呈现萎缩,东芝抢占份额
  4. c 语言输出省份面积和高度,盘点中国23个省份面积排名,最小的一个你知道是哪个省吗?...
  5. 谈一谈|MkDocs介绍及应用
  6. 全国电大计算机英语统考难不难,电大英语统考的难度系数怎么样是不是很大
  7. 写乐100道练习题_初一数学计算题100道
  8. Python系列 | 基于Tkinter图形化界面实现课堂点名系统
  9. wsus下游服务器状态,WSUS上游服务器无法将下游服务器添加到控制台
  10. 珠海服务器风机规格型号,风机分类和其规格型号.pdf