それとStackにTransformの状態を積むことにより、状態を復元できるようにする。
とりあえず試しに時計でも作ってみた。もっとも普通の見やすい時計って文字は正立だし、矢印だって三角関数とか使えば良いのであんまりTransformのメリットは無いけど。
TranslateTransformで移動、ScaleTransformでスケーリング、RotateTransformで回転、ResetTransformで初期化、という感じ。あとは任意の位置でTransformをStackに詰めばその場所を復元することができる。うまく使わないと頭がごちゃごちゃするので注意すること。
using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace GraphicsStack { public partial class Form1 : Form { Bitmap bmp; Graphics gra; DateTime NowDate { get { return (DateTime.Now); } } //DateTime NowDate { get { return (new DateTime(2016, 5, 6, 10, 8, 37, 0)); } } public Form1() { InitializeComponent(); bmp = new Bitmap(512, 512); gra = Graphics.FromImage(bmp); MaximumSize = MinimumSize = Size = Size + bmp.Size - pictureBox1.Size; pictureBox1.Image = bmp; timer1.Start(); } private void timer1_Tick(object sender, EventArgs e) { gra.ResetTransform(); DateTime now = NowDate; using (StringFormat center = new StringFormat(StringFormat.GenericTypographic)) using (Font font1 = new Font(DefaultFont.Name, 25)) using (Font font2 = new Font(DefaultFont.Name, 18)) using (Pen pen1 = new Pen(Color.Gray, 3)) using (Pen pen2 = new Pen(Color.Black, 8)) using (Pen pen3 = new Pen(Color.Red, 5)) { center.Alignment = center.LineAlignment = StringAlignment.Center; pen2.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor; Stack<System.Drawing.Drawing2D.Matrix> Stack = new Stack<System.Drawing.Drawing2D.Matrix>(); Stack.Push(gra.Transform); gra.Clear(Color.LightGray); gra.TranslateTransform(256, 256); Stack.Push(gra.Transform); for (int i = 0; i < 60; i++) { gra.RotateTransform(360 / 60); gra.DrawLine(pen1, 0, -230, 0, -240); } for (int i = 1; i <= 12; i++) { gra.RotateTransform(360 / 12); gra.DrawLine(pen1, 0, -210, 0, -240); gra.DrawString(i.ToString(), font1, pen1.Brush, 0, -190, center); gra.DrawLine(pen1, -15, -170, 15, -170); } gra.Transform = Stack.Pop(); Stack.Push(gra.Transform); gra.TranslateTransform(120, 0); gra.DrawRectangle(Pens.Black, -45, -15, 90, 30); gra.DrawString( now.DayOfWeek.ToString().Substring(0, 3).ToUpper() + now.Day.ToString(" 00"), font2, pen1.Brush, 0, 0, center); gra.Transform = Stack.Pop(); #region 針 float hour = now.Hour * 30 + now.Minute * 0.5f; float minute = now.Minute * 6; float second = now.Second * 6; float subsec = now.Millisecond / (1000 / 360f); Stack.Push(gra.Transform); gra.RotateTransform(hour); gra.DrawLine(pen2, 0, 50, 0, -150); gra.Transform = Stack.Pop(); Stack.Push(gra.Transform); gra.RotateTransform(minute); gra.DrawLine(pen2, 0, 100, 0, -210); gra.Transform = Stack.Pop(); Stack.Push(gra.Transform); gra.RotateTransform(second); gra.DrawLine(pen3, 0, 50, 0, -150); gra.FillEllipse(pen3.Brush, -10, -10, 20, 20); gra.Transform = Stack.Pop(); Stack.Push(gra.Transform); gra.TranslateTransform(90, 90); gra.RotateTransform(subsec); gra.DrawLine(pen3, 0, 10, 0, -30); gra.FillEllipse(pen3.Brush, -10, -10, 20, 20); gra.Transform = Stack.Pop(); #endregion gra.Transform = Stack.Pop(); #if DEBUG if (Stack.Count != 0) { throw new Exception("Stackが異常です"); } #endif } pictureBox1.Refresh(); } } } float hour = now.Hour * 30 + now.Minute * 0.5f; float minute = now.Minute * 6; float second = now.Second * 6; float subsec = now.Millisecond / (1000 / 360f); Stack.Push(gra.Transform); gra.RotateTransform(hour); gra.DrawLine(pen2, 0, 50, 0, -150); gra.Transform = Stack.Pop(); Stack.Push(gra.Transform); gra.RotateTransform(minute); gra.DrawLine(pen2, 0, 100, 0, -210); gra.Transform = Stack.Pop(); Stack.Push(gra.Transform); gra.RotateTransform(second); gra.DrawLine(pen3, 0, 50, 0, -150); gra.FillEllipse(pen3.Brush, -10, -10, 20, 20); gra.Transform = Stack.Pop(); Stack.Push(gra.Transform); gra.TranslateTransform(90, 90); gra.RotateTransform(subsec); gra.DrawLine(pen3, 0, 10, 0, -30); gra.FillEllipse(pen3.Brush, -10, -10, 20, 20); gra.Transform = Stack.Pop(); #endregion gra.Transform = Stack.Pop(); #if DEBUG if (Stack.Count != 0) { throw new Exception("Stackが異常です"); } #endif } pictureBox1.Refresh(); } } }
0 件のコメント:
コメントを投稿