0はGraphicsの変形で書き込んでおり、1はあらかじめ変形した位置を書き込んでいます。
GraphicsのTransformはピクセル単位で計算されますが、自前の計算では位置しか計算できないので、線幅や図形の形状は計算されません。上図の比較はLineとEllipseしか使っていませんが、Rectangleとか使うともっと顕著にわかると思います。
とりあえず今回の目的はGraphics1のaからGraphics2のAに対して直線を引きたいだけだったので、位置の計算だけで充分なので、目標は達成です。
やろうと思えばピクセル単位での変形も可能でしょうが、そこまでするとグラフィックエンジンを自前で作ることになるので、相当に面倒なことになると思います。
C#のImage, Bitmap, Graphicsはちょっとクセがありますが、そこに触れない程度の使い方ならかなり便利だと思います。
でもGraphics.DrawImageUnscaledにImageを渡すとスケーリングされる?バグはどうにかならんのか。。。
using System; using System.Drawing; namespace GraphicsMatrixTransform { class Program { static void Main(string[] args) { for (int j = 0; j < 2; j++) { using (Bitmap bmp = new Bitmap(1000, 1000)) using (Graphics g1 = Graphics.FromImage(bmp)) using (Graphics g2 = Graphics.FromImage(bmp)) { g1.Clear(Color.Black); g1.TranslateTransform(bmp.Width * 0.5f, bmp.Height * 0.5f); Random rand = new Random(1234); for (int i = 0; i < 100; i++) { switch (rand.Next(0, 3)) { case 0: { float f = rand.Next(-45, 91); g1.RotateTransform(f); break; } case 1: { float x = rand.Next(-19, 20); float y = rand.Next(-19, 20); g1.TranslateTransform(x,y); break; } case 2: { float x = rand.Next(6, 16) * 0.1f; float y = rand.Next(6, 16) * 0.1f; g1.ScaleTransform(x,y); break; } } using (Pen pen = new Pen(Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256)))) { switch (rand.Next(2)) { case 0: { PointF p1 = new PointF(rand.Next(-2000, 2000) * 0.1f, rand.Next(-2000, 2000) * 0.1f); PointF p2 = new PointF(rand.Next(-2000, 2000) * 0.1f, rand.Next(-2000, 2000) * 0.1f); if (j == 0) { g1.DrawLine(pen, p1, p2); } else { p1 = g1.Transform.Translate(p1); p2 = g1.Transform.Translate(p2); g2.DrawLine(pen, p1, p2); } break; } case 1: { PointF p1 = new PointF(rand.Next(-1000, 1000) * 0.1f, rand.Next(-1000, 1000) * 0.1f); float r = rand.Next(100, 500) * 0.1f; if (j == 0) { g1.DrawEllipse(pen, p1.X - r, p1.Y - r, r * 2, r * 2); } else { p1 = g1.Transform.Translate(p1); g2.DrawEllipse(pen, p1.X - r, p1.Y - r, r * 2, r * 2); } break; } } } } using (Font font = new Font("メイリオ", 24)) { g2.DrawString(j.ToString(), font, Brushes.White, 0, 0); } bmp.Save("./log" + j + ".png"); } } } } static class MyExt { public static PointF Translate(this System.Drawing.Drawing2D.Matrix mtx, PointF point) { return (new PointF( mtx.Elements[0] * point.X + mtx.Elements[2] * point.Y + mtx.Elements[4], mtx.Elements[1] * point.X + mtx.Elements[3] * point.Y + mtx.Elements[5] )); } } }
0 件のコメント:
コメントを投稿