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