2022年4月13日 星期三

[Window Form] 繪製地面站姿態儀(一) 天空與地面

主要在Form1(主畫面)中拉三個TrackBar當作輸入源分別為TB_Roll(-60~60)、TB_Yaw(-360~360)、TB_Pitch(-90~90),最後是一個UserControl繪製姿態儀(Hud)大小為300x300。

在UserControl內先設定三個屬性分別為Roll、Yaw、Pitch

UserControl.cs

    private float _pitch;
    public float Pitch { get => _pitch; set { _pitch = value; Invalidate(); } }
    private float _roll;
    public float Roll { get => _roll; set { _roll = value; Invalidate(); } }
    private float _yaw;
    public float Yaw { get => _yaw; set { _yaw = value; Invalidate(); } }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        var graphics = e.Graphics;//取得畫布
        var skyRec = new RectangleF(0, 0, Width, Height/2f);
        //定義天空的範圍,(0,0)為左上角當原點,天空是上半部,所以長寬為畫面高度的一半
        using (var linearBrush = new LinearGradientBrush(skyRec, Color.White, Color.Blue, LinearGradientMode.Vertical))
        {
            //使用LinearGradientBrush,由上至下,由白至藍,畫在定義的區塊內
            graphics.FillRectangle(linearBrush, skyRec);
        }
        var groundRec = new RectangleF(0, Height/2f, Width, Height/2f);
        //定義地面的範圍,(0,Height/2)為地面的啟始點,地面是下半部,所以長寬為畫面高度的一半
        using (var linearBrush = new LinearGradientBrush(groundRec, Color.Brown, Color.White, LinearGradientMode.Vertical)
        {
            //使用LinearGradientBrush,由上至下,由咖啡至白,畫在定義的區塊內       
            graphics.FillRectangle(linearBrush, groundRec);
        }
    }

加入與Pitch的連結

    //天空
    var skyRec = new RectangleF(0, 0 + Pitch, Width, Height/2f);
    using (var linearBrush = new LinearGradientBrush(skyRec, Color.White, Color.Blue, LinearGradientMode.Vertical))
    {
        graphics.FillRectangle(linearBrush, skyRec);
    }
    //地面
    var groundRec = new RectangleF(0, Height/2f + Pitch, Width, Height/2f);
    using (var linearBrush = new LinearGradientBrush(groundRec, Color.Brown, Color.White, LinearGradientMode.Vertical))
    {
        graphics.FillRectangle(linearBrush, groundRec);
    }
要記得每個TrackBar的Value要綁定UserControl相對應的屬性

Form1.cs

    userControl1.DataBindings.Add(new Binding("Roll", TB_Roll, "Value"));
    userControl1.DataBindings.Add(new Binding("Yaw", TB_Yaw, "Value"));
    userControl1.DataBindings.Add(new Binding("Pitch", TB_Pitch, "Value"));

拉動TB_Pitch的時候會發現上下會有缺塊,

是因為超出範圍了,所以要將上下的面積加大一倍。

    //天空
    var skyRec = new RectangleF(0, -Height / 2f + 0 + Pitch, Width, Height);//Height變為2倍,Y軸也要跟著往上(負值)移動(Height/2f)
    using (var linearBrush = new LinearGradientBrush(skyRec, Color.White, Color.Blue, LinearGradientMode.Vertical))
    {
        graphics.FillRectangle(linearBrush, skyRec);
    }
    //地面
    var groundRec = new RectangleF(0, Height / 2f + Pitch, Width, Height);//Height變為2倍
    using (var linearBrush = new LinearGradientBrush(groundRec, Color.Brown, Color.White, LinearGradientMode.Vertical))
    {
        graphics.FillRectangle(linearBrush, groundRec);
    }

x在UserControl的建構式中將DoubleBuffered開啟改善畫面閃爍的問題

    public UserControl()
    {
        InitializeComponent();
        DoubleBuffered = true;
    }

沒有留言:

張貼留言