본문 바로가기

C# WPF

Analog Clock in C# WPF using Rotation(아날로그 시계)

C# WPF로 다음과 같은 Analog Clock 을 RotateTransform 을 이용하여 구현한다.

RotateTransform을 이용하면 시침, 분침, 초침을 만들어두고, 1초에 한번씩 현재 시간에 따라 시침, 분침, 초침의 각도를 계산한 후, 시계의 중심좌표를 중심으로 각 바늘의 각도만큼 회전시켜 줌으로써 시계를 만들 수 있다. 삼각함수를 써서 바늘의 좌표를 계산하여 그리는 것보다 간단하다.

눈금도 같은 방법으로 간단히 그릴 수 있다. 소스를 참조하시길...

 

 

// XAML

<Window x:Class="Rotation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="330">
    <Canvas Name="myCanvas">
    </Canvas>
</Window>

// CS

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace Rotation
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {       
        private double hourDeg;
        private double secDeg;
        private double minDeg;
       
        private Line hourHand;
        private Line minHand;
        private Line secHand;
       
        //private TextBlock tb;

        public MainWindow()
        {
            InitializeComponent();

            myCanvas.Width = 300;
            myCanvas.Height = 300;

            Rectangle r = new Rectangle();
            r.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
            r.Width = 300;
            r.Height = 300;
            myCanvas.Children.Add(r);
           
            // Draw Face
            DrawFace();

            // make Hands
            secHand = new Line();
            secHand.Stroke = Brushes.Red;
            secHand.StrokeThickness = 2;
            secHand.X1 = r.Width / 2;
            secHand.Y1 = r.Height / 2;
            secHand.X2 = r.Width / 2;
            secHand.Y2 = 20;

            minHand = new Line();
            minHand.Stroke = Brushes.Green;
            minHand.StrokeThickness = 4;
            minHand.X1 = r.Width / 2;
            minHand.Y1 = r.Height / 2;
            minHand.X2 = r.Width / 2;
            minHand.Y2 = 40;

            hourHand = new Line();
            hourHand.Stroke = Brushes.Blue;
            hourHand.StrokeThickness = 6;
            hourHand.X1 = r.Width / 2;
            hourHand.Y1 = r.Height / 2;
            hourHand.X2 = r.Width / 2;
            hourHand.Y2 =60;

            getCurrentTime();

            DispatcherTimer dt = new DispatcherTimer();
            dt.Tick += new EventHandler(dt_Tick);
            dt.Interval = new TimeSpan(0, 0, 1);
            dt.Start();
        }

        private void DrawFace()
        {
            //double radius = myCanvas.Width / 2;
            Ellipse circle = new Ellipse();
            circle.Width = 300;
            circle.Height = 300;
            circle.Stroke = Brushes.LightSteelBlue;
            circle.StrokeThickness = 2;
            myCanvas.Children.Add(circle);

            Line[] marking = new Line[60];

            for (int i = 0; i < 60; i++)
            {
                marking[i] = new Line();
                marking[i].Stroke = Brushes.LightSteelBlue;

                marking[i].X1 = circle.Width / 2; marking[i].Y1 = 2;
                marking[i].X2 = circle.Width / 2;
                if (i % 5 == 0)
                {
                    marking[i].StrokeThickness = 5;
                    marking[i].Y2 = 20;
                }
                else
                {
                    marking[i].StrokeThickness = 2;
                    marking[i].Y2 = 10;
                }

                RotateTransform rt = new RotateTransform(6 * i);
                rt.CenterX = 150;
                rt.CenterY = 150;
                marking[i].RenderTransform = rt;
                myCanvas.Children.Add(marking[i]);
            }

            Line l1 = new Line();
            l1.X1 = 0; l1.Y1 = 150; l1.X2 = 300; l1.Y2 = 150;
            l1.Stroke = Brushes.LightBlue;
            myCanvas.Children.Add(l1);

            Line l2 = new Line();
            l2.X1 = 150; l2.Y1 = 0; l2.X2 = 150; l2.Y2 = 300;
            l2.Stroke = Brushes.LightBlue;
            myCanvas.Children.Add(l2);
        }

        private void getCurrentTime()
        {
            DateTime currentTime = new DateTime();
            currentTime = DateTime.Now;

            int hour = currentTime.Hour;
            int min = currentTime.Minute;
            int sec = currentTime.Second;

            hourDeg = hour%12 * 30 + min * 0.5;
            minDeg = min * 6;
            secDeg = sec * 6;

            // Remove & Add
            myCanvas.Children.Remove(hourHand);
            RotateTransform hourRt = new RotateTransform(hourDeg);
            hourRt.CenterX = hourHand.X1;
            hourRt.CenterY = hourHand.Y1;
            hourHand.RenderTransform = hourRt;
            myCanvas.Children.Add(hourHand);

            myCanvas.Children.Remove(minHand);
            RotateTransform minRt = new RotateTransform(minDeg);
            minRt.CenterX = minHand.X1;
            minRt.CenterY = minHand.Y1;
            minHand.RenderTransform = minRt;
            myCanvas.Children.Add(minHand);

            myCanvas.Children.Remove(secHand);
            RotateTransform secRt = new RotateTransform(secDeg);
            secRt.CenterX = secHand.X1;
            secRt.CenterY = secHand.Y1;
            secHand.RenderTransform = secRt;
            myCanvas.Children.Add(secHand);

            Ellipse center = new Ellipse();
            center.Width = 20;
            center.Height = 20;
            center.Margin = new Thickness(myCanvas.Width / 2 - center.Width / 2);
            center.Stroke = Brushes.DarkOliveGreen;
            center.StrokeThickness = 2;
            center.Fill = Brushes.Chocolate;
            myCanvas.Children.Add(center);
        }

        void dt_Tick(object sender, EventArgs e)
        {
            getCurrentTime();
        }
    }
}

C# WPF에서의 Graphics와 Multimedia의 처리에 대해서는 아래의 링크를 참조하기 바란다. http://msdn.microsoft.com/en-us/library/ms742562.aspx 

Shape의 Transform에 대해서는 아래의 링크를 참조하기 바란다.
http://msdn.microsoft.com/en-us/library/ms747393.aspx#transforms

The Transform class provides the means to transform shapes in a two-dimensional plane. The different types of transformation include rotation (RotateTransform), scale (ScaleTransform), skew (SkewTransform), and translation (TranslateTransform).

 

BeeEye Dmu

'C# WPF' 카테고리의 다른 글

Analog Clock in C# WPF(아날로그 시계) - 3  (0) 2013.10.18
Analog Clock in C# WPF(아날로그 시계) - 2  (0) 2013.10.18
C# WPF 계산기  (0) 2013.10.02
Visual Studio 2012와 2010의 차이점  (0) 2013.07.10
Delegate  (0) 2013.07.08