C#/Csharp,通過GDI+知識,在窗體上繪製彩虹

望江樹發表於2020-11-15

簡介

應用軟體的Loading介面是一個軟體的重要組成部分。請利用所學的GDI+知識,通過在窗體上繪製彩虹的方式,完成一個兒童學習類軟體的Loading介面,功能要求如下所示:
在這裡插入圖片描述在這裡插入圖片描述

軟體需求及編碼提示:
 該軟體只需要一個窗體,該窗體標題為:“彩虹繪製—2017XXXXXXX”。請依據你的情況填寫你的真實學號。
 設定窗體的雙快取為true,避免繪圖是,窗體閃爍。(找到主視窗的DoubleBuffered,把它屬性改為true)
 新增Form_Paint事件,在該事件中,獲取Graphics物件,對應程式碼提示如下。(點選主窗體,點選屬性,找到它屬性中的Paint,雙擊在這裡插入圖片描述
在自己彈入的方法體中寫下面得程式碼

 繪製彩虹的核心方法是Graphics物件的FillPie方法,該方法的引數解釋如下:通過繪製7個同心的不同顏色扇形,即可繪製出彩虹圖案。
在這裡先補充一下座標軸概念,主窗體的左上角的座標為(0,0),往下則y加,往右則x加。
(這個方法還可以用七個屬性定義,也可以用一個矩形概括)
在.NET裡面它的原始碼為:
FillPie(Brush brush, Rectangle rect, float startAngle, float sweepAngle);
public void FillPie(
Brush brush,
int x,//這個是起始的橫座標
int y,//起始的縱座標
int width,//邊框的橫向長度
int height,//邊框的縱向長度
int startAngle,
int sweepAngle
);
摘要:填充橢圓所定義的扇形區的內部,該橢圓System.Drawing.RectangleF 結構和兩條射線指定。
brush:用什麼顏色的筆刷繪製該扇形。
rect:它表示定義該扇形區所屬的邊框。
startAngle:起始角度。
sweepAngle:沿startAngle掃過的角度。
 第一個引數brush,7個顏色的取值分別是:Brushes. Red, Brushes.Orange,Brushes.Yellow,Brushes.Green,Brushes.GreenYellow,Brushes.Blue,Brushes.Purple。
//要畫這個彩虹其實是畫了七個扇形,他們的直徑一次增加,達到看上去色彩遞變的效果,上面是畫每個扇形所用刷子的顏色
 第二個引數,這裡簡化成了一個矩形,直接就定義了邊框。
//這裡矩形的定義可能會難到某些同學,我在這裡說明一下
Point center =new Point(this.Width/2,this.Height/2);
Rectangle rec = new Rectangle(center.X-160, center.Y-160, 320, 320);
第一個屬性是矩形左上角點的橫座標,第二個屬性是左上角點的縱座標
第三個是矩形的寬,第四個屬性的矩形的長。
 第三個引數,由於窗體座標系如下所示:通過上述座標系圖,我們可以知道startAngle應該設定為180。

 第四個引數sweepAngle,由於該值隨著時間變化,因此,我們需要在方法外定義一個float型別的 sweepAng變數,在timer中不斷增加或減少該值,然後在FillPie方法中,使用該變數。利用掃過角度的不斷變化,引起所繪製的圖形的變化。注意:timer控制元件是否啟用,以及在Tick事件中,呼叫this. Invalidate ()或者this. Refresh(),更新畫面。
 為了能將彩虹繪製在窗體中心,在Form_Load事件中獲取窗體中心點。
//這裡也是一個難點,我們彩虹的中心和center並不是一致的,彩虹的中心的我們定義矩形對角線相交的地方,所以為了使彩虹的中心和center一致,我們要讓彩虹的中心等於(center.x-rec.width/2,center.x-rec.height/2)
 在GDI+中螢幕座標系的原點在窗體左上角,根據所獲得窗體中心變數center以及,每個扇形的半徑,結合下圖,可以輕鬆構造出每個扇形應該繪製在的外界矩形Rectangle,即FillPie的第二個引數rect。7個扇形的半徑取值分別是:160,140,120,100,80,60,40。

 為了保證繪製出的彩虹只有180°,請在timer的tick事件中加入判斷,當sweepAng大於180°的時候,重新置為0°
//
if (sweepAngle <= 180)
{
sweepAngle++;
}
else
{
sweepAngle = 1;
}
this.Invalidate();//寫在Timer裡的程式碼,Timer的具體應用我在IOS撥號中寫了。

程式碼

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Rainbow_201831053318
{

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    Point center;
    public int sweepAngle = 1;
    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        center = new Point(this.Width / 2, this.Height / 2);
        Graphics g = e.Graphics;//獲得繪圖物件
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;//抗鋸齒,增加繪圖平滑度

        SolidBrush RainbowBrush1 = new SolidBrush(Color.Red);
        SolidBrush RainbowBrush2 = new SolidBrush(Color.Orange);
        SolidBrush RainbowBrush3 = new SolidBrush(Color.Yellow);
        SolidBrush RainbowBrush4 = new SolidBrush(Color.Green);
        SolidBrush RainbowBrush5 = new SolidBrush(Color.Yellow);
        SolidBrush RainbowBrush6 = new SolidBrush(Color.Blue);
        SolidBrush RainbowBrush7 = new SolidBrush(Color.Purple);

        Rectangle rectangle1 = new Rectangle(center.X - 160, center.Y - 160, 320, 320);
        Rectangle rectangle2 = new Rectangle(center.X - 140, center.Y - 140, 280, 280);
        Rectangle rectangle3 = new Rectangle(center.X - 120, center.Y - 120, 240, 240);
        Rectangle rectangle4 = new Rectangle(center.X - 100, center.Y - 100, 200, 200);
        Rectangle rectangle5 = new Rectangle(center.X - 80, center.Y - 80, 160, 160);
        Rectangle rectangle6 = new Rectangle(center.X - 60, center.Y - 60, 120, 120);
        Rectangle rectangle7 = new Rectangle(center.X - 40, center.Y - 40, 80, 80);


        g.FillPie(RainbowBrush1, rectangle1, 180, sweepAngle);
        g.FillPie(RainbowBrush2, rectangle2, 180, sweepAngle);
        g.FillPie(RainbowBrush3, rectangle3, 180, sweepAngle);
        g.FillPie(RainbowBrush4, rectangle4, 180, sweepAngle);
        g.FillPie(RainbowBrush5, rectangle5, 180, sweepAngle);
        g.FillPie(RainbowBrush6, rectangle6, 180, sweepAngle);
        g.FillPie(RainbowBrush7, rectangle7, 180, sweepAngle);
        
        

    }
    
    private void Timer1_Tick(object sender, EventArgs e)
    {
        if (sweepAngle <= 180)
        {
            sweepAngle++;
        }
        else
        {
            sweepAngle = 1;
        }
        this.Invalidate();
    }
}

}

相關文章