C#学习笔记(一)使用C#绘制一个时钟

思路:

我们常见的时钟是由表盘和指针构成,所以此次我们将任务分成绘制表盘和指针两部分来完成。

相关概念
1、坐标系
在 windows 默认坐标系中,坐标原点在绘图对象(本例绘图对象是 pictureBox1)的左上角,横轴(x 轴)水平向右,纵轴(y 轴竖直向下),每经过 1 个像素加 1。

2、绘图流程
在 windows 绘图,一般分成 3 步。分别为得到绘图场景、设置画笔/画刷、绘图。

(1)设置绘图场景,我们先创建一个项目

C#学习笔记(一)使用C#绘制一个时钟_第1张图片

 (2)添加绘图板

选择【工具箱】->【PictureBox】,拖动到窗体中,调整 PictureBox 到窗体大小,查看右侧【属性】,可发现系统将该对象自动起名为 pictureBox1。

C#学习笔记(一)使用C#绘制一个时钟_第2张图片

 C#学习笔记(一)使用C#绘制一个时钟_第3张图片

 (3)双击绘图板,进入代码层

(3.1)我们开始创建画板:

        Bitmap bitmap;//创建画图板
        public Form1()
        {
            InitializeComponent();
            bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = bitmap;
        }

随后我们单独创建一个画表盘的函数:

public void Clock_back()//画表盘
        {
            int i;
            var g = Graphics.FromImage(pictureBox1.Image);
            Pen p = new Pen(Color.Black, 3);
            var clock = new Rectangle(100, 0, 370, 370);//绘制一个(100,0)处开始,长370,宽370的矩形
            var dot = new Rectangle(280, 180, 10, 10);
            for (i = 0; i < 12; i++)//时刻标度
            {
                double angel = i * (Math.PI) / 6;

                Point xy1 = new Point((int)(180 * Math.Cos(angel) + 285), (int)(180 * Math.Sin(angel) + 185));//圆心定义为(285,185)
                Point xy2 = new Point((int)(155 * Math.Cos(angel) + 285), (int)(155 * Math.Sin(angel) + 185));

                g.DrawLine(p, xy1, xy2);
            }
            for (i = 0; i < 60; i++)//小时刻标度
            {
                double angel = i * (Math.PI) / 30;

                Point xy1 = new Point((int)(180 * Math.Cos(angel) + 285), (int)(180 * Math.Sin(angel) + 185));
                Point xy2 = new Point((int)(170 * Math.Cos(angel) + 285), (int)(170 * Math.Sin(angel) + 185));

                g.DrawLine(new Pen(Color.Blue), xy1, xy2);
            }
            g.DrawEllipse(p, clock);//绘制一个由clock边框定义的椭圆
            g.DrawEllipse(p, dot);
            g.Dispose();
        }

代码解析:(无注释部分)

 var g = Graphics.FromImage(pictureBox1.Image);
 Pen p = new Pen(Color.Black, 3);

第一行是为了得到 pictureBox1 的绘图场景。var 是 c# 的类型关键字,说明该类型由编译器根据后续代码自动给出。
第二行定义了一个黑色的粗度为3的画笔。new 表示调用构造函数。C#规定,值类型初始化时可以直接赋值。引用类型初始化时需要用 new 调用该类型的构造函数进行初始化。

刻度的制作:

首先我们思考怎样才能绘制出刻度值,在这里我想到的办法是:绘制共用圆心的一个大圆和一个小圆。它们在同一角度下,两圆的点在同一条过圆心的直线上。

C#学习笔记(一)使用C#绘制一个时钟_第4张图片

 所以我们就能每隔6°和60°取一次角度,在每个圆上取出1个点,然后我们通过

g.DrawLine(p, xy1, xy2);

函数连接,就可以绘制出表盘了。函数使用方法如下

C#学习笔记(一)使用C#绘制一个时钟_第5张图片

 (3.2)指针绘制

 public void Clock(int second,int minute,int hour)//画指针
        {
            var gg = Graphics.FromImage(pictureBox1.Image);

            Pen s_p = new Pen(Color.Yellow, 3);
            Pen m_p = new Pen(Color.Blue, 4);
            Pen h_p = new Pen(Color.Red, 5);

            double angel_s = second * Math.PI / 30;
            double angel_m = minute * Math.PI / 30;
            double angel_h = hour * Math.PI / 6 + minute * (1 / (Math.PI * 30));

            Point o = new Point(285, 185);//圆心

            Point s = new Point((int)(285 + 160 * Math.Sin(angel_s)), (int)(185 - 160 * Math.Cos(angel_s)));//秒针
            Point m = new Point((int)(285 + 130 * Math.Sin(angel_m)), (int)(185 - 130 * Math.Cos(angel_m)));//分针
            Point h = new Point((int)(285 + 100 * Math.Sin(angel_h)), (int)(185 - 100 * Math.Cos(angel_h)));//时针

            gg.DrawLine(s_p, o, s);
            gg.DrawLine(m_p, o, m);
            gg.DrawLine(h_p, o, h);
            gg.Dispose();
        }

大致思路和绘制表盘是一样的,只不过这里将时针分针秒针的角度设置成了变量,后续读取系统时钟进行赋值。

此处有两点值得注意的地方

1、时针的设置

时针有12个刻度,得再加上分针走过的刻度,才能使时针不会在非整时的时候都指向整数。

2、x坐标用285+sin(angel_s),y坐标用185-cos(angel_s)求

因为在绘图板中,y轴指向下,并非我们平常认知的坐标系,所以是相反的,我们可以自己找一张白纸画一下就明白了。

(3.3)读取系统时钟,钟表运动

首先我们添加一个timer控件,其作用是没100毫秒执行一次。

C#学习笔记(一)使用C#绘制一个时钟_第6张图片

 双击,进入代码层,添加要执行的代码:

private void timer1_Tick(object sender, EventArgs e)
        {
             h = DateTime.Now.Hour;//读取系统时钟
             m = DateTime.Now.Minute;
             s = DateTime.Now.Second;
            var gg = Graphics.FromImage(pictureBox1.Image);
            gg.Clear(this.BackColor);
            Clock_back();
            Clock(s, m, h);
            pictureBox1.Refresh();
        }

启动控件:

        public Form1()
        {
            InitializeComponent();
            bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = bitmap;
            timer1.Enabled = true;//启动timer
        }

(3.4)

画板显示:

        private void pictureBox1_Click(object sender, EventArgs e)
        {

            Clock_back();
            Clock(s, m, h);
            MessageBox.Show(s.ToString());
            pictureBox1.Refresh();
        }

此时我们的任务就完成了,成品效果如下:

C#学习笔记(一)使用C#绘制一个时钟_第7张图片

附全部代码:

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 whx1
{
    public partial class Form1 : Form
    {
        Bitmap bitmap;//创建画图板
        public Form1()
        {
            InitializeComponent();
            bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = bitmap;
            timer1.Enabled = true;//启动timer
        }
        int h, m, s;
        private void timer1_Tick(object sender, EventArgs e)
        {
             h = DateTime.Now.Hour;//读取系统时钟
             m = DateTime.Now.Minute;
             s = DateTime.Now.Second;
            var gg = Graphics.FromImage(pictureBox1.Image);
            gg.Clear(this.BackColor);
            Clock_back();
            Clock(s, m, h);
            pictureBox1.Refresh();
        }
        public void Clock_back()//画表盘
        {
            int i;
            var g = Graphics.FromImage(pictureBox1.Image);
            Pen p = new Pen(Color.Black, 3);
            var clock = new Rectangle(100, 0, 370, 370);//绘制一个(100,0)处开始,长370,宽370的矩形
            var dot = new Rectangle(280, 180, 10, 10);
            for (i = 0; i < 12; i++)//时刻标度
            {
                double angel = i * (Math.PI) / 6;

                Point xy1 = new Point((int)(180 * Math.Cos(angel) + 285), (int)(180 * Math.Sin(angel) + 185));//圆心定义为(285,185)
                Point xy2 = new Point((int)(155 * Math.Cos(angel) + 285), (int)(155 * Math.Sin(angel) + 185));

                g.DrawLine(p, xy1, xy2);
            }
            for (i = 0; i < 60; i++)//小时刻标度
            {
                double angel = i * (Math.PI) / 30;

                Point xy1 = new Point((int)(180 * Math.Cos(angel) + 285), (int)(180 * Math.Sin(angel) + 185));
                Point xy2 = new Point((int)(170 * Math.Cos(angel) + 285), (int)(170 * Math.Sin(angel) + 185));

                g.DrawLine(new Pen(Color.Blue), xy1, xy2);
            }
            g.DrawEllipse(p, clock);//绘制一个由clock边框定义的椭圆
            g.DrawEllipse(p, dot);
            g.Dispose();
        }
        public void Clock(int second,int minute,int hour)//画指针
        {
            var gg = Graphics.FromImage(pictureBox1.Image);

            Pen s_p = new Pen(Color.Yellow, 3);
            Pen m_p = new Pen(Color.Blue, 4);
            Pen h_p = new Pen(Color.Red, 5);

            double angel_s = second * Math.PI / 30;
            double angel_m = minute * Math.PI / 30;
            double angel_h = hour * Math.PI / 6 + minute * (1 / (Math.PI * 30));

            Point o = new Point(285, 185);//圆心

            Point s = new Point((int)(285 + 160 * Math.Sin(angel_s)), (int)(185 - 160 * Math.Cos(angel_s)));//秒针
            Point m = new Point((int)(285 + 130 * Math.Sin(angel_m)), (int)(185 - 130 * Math.Cos(angel_m)));//分针
            Point h = new Point((int)(285 + 100 * Math.Sin(angel_h)), (int)(185 - 100 * Math.Cos(angel_h)));//时针

            gg.DrawLine(s_p, o, s);
            gg.DrawLine(m_p, o, m);
            gg.DrawLine(h_p, o, h);
            gg.Dispose();
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

            Clock_back();
            Clock(s, m, h);
            MessageBox.Show(s.ToString());
            pictureBox1.Refresh();
        }
    }
}

ps:一只编程和写文章的小白萌新,望各路大佬多指点嘿嘿(*^▽^*)

你可能感兴趣的:(课程设计,学习笔记,c#,visual,studio)