c#畫一個五角星,最重要的就是計算哪些坐標點出來,也是最難的一部分,這要涉及到一些數學方面的知識.對數學坐標知識不是很熟的人,如果想學畫圖,我建議多去看一下數學書,對我們寫程序的人來說是沒有什么壞處可言的.
想學習的朋友可以一起學習,我覺得分享學習是一種快樂,所以把自己的一些心得分享給大家,我本人也是走了很多的彎路,所以也不希望一些朋友做一些吃力不討好的事.
廢話不多說,先看一下效果圖吧:
效果還可以吧,至少長得很像五角星,當然你也可以說不像,可能我的口味和你的不同,不過我們的目的都是一樣的,就是怎么算這些坐標出來並且把他畫出來.
好,現在我們開始來分析問題(在此之前,我建議不懂極坐標的朋友先看看極坐標方面的一些知識,因為算法的核心問題主要在這里.):
程序分析步驟:
1.畫一個五角星,需要先確定五角星的十個點,有朋友可能問:"為什么是十個點而不是五個點呢?",這種問題希望沒有學過c#的人都會知道,確定一個五角星需要十個點,多邊形嘛!
2.如何獲得我們所需要的十個點呢?反問自己,經常反問自己可以解決很多問題.要想確定十個點,你可以觀察一下圖形,或自己畫一下,看一下圖形的特點(中心對稱圖形),對於中心對稱圖形,就可以確定其中心點,其他所有的點都是圍繞着這個中心點轉的,我們可以根據三個條件來確定我們想要得到的點:
1.中心點
2.中心點到目標點的距離
3.目標點和X軸(水平距離)的夾角
現在我們可以寫一個GetPoint的方法來獲得目標點,代碼如下:
/// <summary> /// 獲得五角星的各個點 /// </summary> /// <param name="ptCenter">中心點坐標</param> /// <param name="length">距離中心點的長度</param> /// <param name="angle">和水平方向的夾角</param> /// <returns></returns> public PointF GetPoint(PointF ptCenter, double length, double angle) { return new PointF( (float)(ptCenter.X + length * Math.Cos(angle)), (float)(ptCenter.Y + length * Math.Sin(angle))); }
方法很簡單,返回一個目標點,這個算是核心的一個方法,理解了這個方法,接下來的都迎刃而解.既然能夠得到一個點當然也能夠得到一系列的點,所以我們還可以寫一個獲得一系列點的方法GetPoints,代碼如下:
/// <summary> /// 返回一個坐標的數組 /// </summary> /// <param name="ptCenter">中心點</param> /// <param name="length">距離中心點的長度</param> /// <param name="angles">兩點之間的夾角</param> /// <returns></returns> public PointF[] GetPoints(PointF ptCenter, double length, params double[] angles) { PointF[] points = new PointF[angles.Length]; for (int i = 0; i < points.Length; i++) { points[i] = GetPoint(ptCenter,length,angles[i]); } return points; }
從我們的代碼中可以看到一個角度的參數(double angle),所以我們就需要確定目標點和X軸(水平距離)的夾角,我們還是讓代碼來說話吧!
/// <summary> /// 獲得所有角度的數組 /// </summary> /// <param name="startAngle">開始的角度</param> /// <param name="pointed">個數</param> /// <returns></returns> public double[] GetAngles(double startAngle,int pointed) { double[] angles = new double[pointed]; angles[0] = startAngle; for (int i = 1; i < angles.Length; i++) { angles[i] =angles[i-1] + GetAngleLength(pointed); } return angles; } /// <summary> /// 獲得角度的增量 /// </summary> /// <param name="pointed"></param> /// <returns></returns> public double GetAngleLength(int pointed) { return 2*Math.PI/pointed; }
可以看到我們定義了兩個方法,想要確定目標點和X軸(水平距離)的夾角,就要確定多少個角(pointed),還有你的起始角的位置(startAngle,中心點之上的那個點),然后確定角度的增量就可以計算出所有的角度了!
3.萬事俱備,只欠一個DrawStar的方法,先看一下代碼:
/// <summary> /// 畫五角星 /// </summary> /// <param name="pointed">多少個角</param> /// <param name="e">Graphics參數</param> public void DrawStar(int pointed,PaintEventArgs e) { Graphics g = e.Graphics;//建立一個畫布 g.CompositingQuality = CompositingQuality.HighQuality;//設置圖像呈現的質量 g.SmoothingMode = SmoothingMode.HighQuality;//對圖片進行平滑處理 Pen p = new Pen(Color.Red);//畫筆的顏色 double[] angles1 = GetAngles(-Math.PI / 2, pointed);//五角星外圍的點角度的一個數組 double[] angles2 = GetAngles(-Math.PI / 2+Math.PI/pointed, pointed);//五角星內圍的點角度的一個數組 PointF[] points1 = GetPoints(new PointF(300, 300), 100, angles1);//五角星外圍的點的一個數組 PointF[] points2 = GetPoints(new PointF(300, 300), 50, angles2);//五角星內圍的點的一個數組 PointF[] points = new PointF[points1.Length+points2.Length];//最終合成多邊形所有點的數組 for (int i = 0,j=0; i < points.Length; i+=2,j++) { points[i] = points1[j]; points[i + 1] = points2[j]; } g.DrawPolygon(p,points);//畫一個多邊形 g.FillPolygon(Brushes.Aqua,points);//填充顏色 }
這個方法也沒有什么好說的,就是c#一些常用的方法,上面本人也有注解!
我也就不解釋那么多了,相信你自己能夠看得懂!
其實上面的代碼不只是可以畫五角星,只要改一下六角,七角,八角,你喜歡的話一百角都行!看一下效果圖吧!
接下來一個一百角的,當然看起來更像一個太陽,根據自己的喜好吧!
Ok!寫完,本人寫作水平和表達能力有點菜,有不足之處希望大家諒解!也希望對各位朋友有所幫助!
完整源代碼:
public class 五角星 { /// <summary> /// 畫五角星 /// </summary> /// <param name="pointed">多少個角</param> /// <param name="e">Graphics參數</param> public void DrawStar(int pointed,Graphics g) { g.CompositingQuality = CompositingQuality.HighQuality;//設置圖像呈現的質量 g.SmoothingMode = SmoothingMode.HighQuality;//對圖片進行平滑處理 Pen p = new Pen(Color.Red);//畫筆的顏色 double[] angles1 = GetAngles(-Math.PI / 2, pointed);//五角星外圍的點角度的一個數組 double[] angles2 = GetAngles(-Math.PI / 2+Math.PI/pointed, pointed);//五角星內圍的點角度的一個數組 PointF[] points1 = GetPoints(new PointF(300, 300), 100, angles1);//五角星外圍的點的一個數組 PointF[] points2 = GetPoints(new PointF(300, 300), 50, angles2);//五角星內圍的點的一個數組 PointF[] points = new PointF[points1.Length+points2.Length];//最終合成多邊形所有點的數組 for (int i = 0,j=0; i < points.Length; i+=2,j++) { points[i] = points1[j]; points[i + 1] = points2[j]; } g.DrawPolygon(p,points);//畫一個多邊形 g.FillPolygon(Brushes.Aqua,points);//填充顏色 } /// <summary> /// 獲得所有角度的數組 /// </summary> /// <param name="startAngle">開始的角度</param> /// <param name="pointed">個數</param> /// <returns></returns> public double[] GetAngles(double startAngle,int pointed) { double[] angles = new double[pointed]; angles[0] = startAngle; for (int i = 1; i < angles.Length; i++) { angles[i] =angles[i-1] + GetAngleLength(pointed); } return angles; } /// <summary> /// 獲得角度的增量 /// </summary> /// <param name="pointed"></param> /// <returns></returns> public double GetAngleLength(int pointed) { return 2*Math.PI/pointed; } /// <summary> /// 獲得五角星的各個點 /// </summary> /// <param name="ptCenter">中心點坐標</param> /// <param name="length">距離中心點的長度</param> /// <param name="angle">和水平方向的夾角</param> /// <returns></returns> public PointF GetPoint(PointF ptCenter, double length, double angle) { return new PointF( (float)(ptCenter.X + length * Math.Cos(angle)), (float)(ptCenter.Y + length * Math.Sin(angle))); } /// <summary> /// 返回一個坐標的數組 /// </summary> /// <param name="ptCenter">中心點</param> /// <param name="length">距離中心點的長度</param> /// <param name="angles">兩點之間的夾角</param> /// <returns></returns> public PointF[] GetPoints(PointF ptCenter, double length, params double[] angles) { PointF[] points = new PointF[angles.Length]; for (int i = 0; i < points.Length; i++) { points[i] = GetPoint(ptCenter,length,angles[i]); } return points; } }