ドットで図形を描画

Image 領域に直接アクセスして、ドットで図形を描きます。

前田稔の超初心者のプログラム入門

プログラムの説明

  1. Visual Studio で新規プロジェクトから[空白アプリ(ユニバーサル Windows)]を生成します。
    MainPage.xaml のデザイン画面を表示して、ツールから Image を張り付けます。
    Image のプロパティから Width=400, Height=300 に設定して下さい。
    "image" の名前で画像を設定するので x:Name="image" を確認して下さい。
    新規プロジェクトの詳細は C# Store Application を参照して下さい。
  2. MainPage.xaml.cs で WriteableBitmap に図形を描画して Image に設定します。
    下記のソースを参考にして using を追加して下さい。
    using System;
        ・・・
    using Windows.UI.Xaml.Navigation;
    using Windows.System.Threading;
    using Windows.UI.Xaml.Media.Imaging;
    using System.Numerics;
    
        public sealed partial class MainPage : Page
        {   private WriteableBitmap writeablebitmap;
            public MainPage()
            {   this.InitializeComponent();
                writeablebitmap = new WriteableBitmap(400, 300);
                image.Source = writeablebitmap;
                Draw();
            }
    
            async private void Draw()
            {   int pixelWidth = writeablebitmap.PixelWidth;
                int pixelHeight = writeablebitmap.PixelHeight;
                byte[] result = null;
                await ThreadPool.RunAsync(new WorkItemHandler(
                    (IAsyncAction action) =>
                    {   result = DrawRect(pixelWidth, pixelHeight);  }
                    ));
                using(Stream stream = writeablebitmap.PixelBuffer.AsStream())
                {   await stream.WriteAsync(result, 0, result.Length);  }
                writeablebitmap.Invalidate();
            }
    
            private byte[] DrawRect(int width, int height)
            {   byte[] result = new byte[width * height * 4];
                int resultIndex = 0;
                int maxIterationCount = 50;
                Complex minimum = new Complex(-2.5, -1.0);
                Complex maximum = new Complex(1.0, 1);
                double xScaleFactor = (maximum.Real - minimum.Real) / width;
                double yScaleFactor = (maximum.Imaginary - minimum.Imaginary) / height;
                for (int y = 0; y < height; y++)
                {   for (int x = 0; x < width; x++)
                    {   result[resultIndex++] = 20;         // Green value of pixel
                        result[resultIndex++] = 20;         // Blue value of pixel
                        result[resultIndex++] = 255;        // Red value of pixel
                        result[resultIndex++] = 255;        // Alpha value of pixel
                    }
                }
                return result;
            }
        }
    
  3. MainPage() の Constructor から image.Source に WriteableBitmap を設定して、Draw() 関数を呼び出します。
    Draw() 関数から赤の矩形のイメージを生成する DrawRect() 関数を呼び出します。
    生成したイメージを WriteableBitmap に設定して writeablebitmap.Invalidate() で再描画します。
  4. DrawRect() で赤の矩形のイメージを byte[] result に生成してリターンします。
    図形(矩形)は「緑(20),青(20),赤(255),アルファ(255)」ごとに1ドットずつ書き込みます。
  5. メニューの[デバッグ]から[デバッグ開始]でコンパイル&実行すると赤色の矩形が描画されます。

マンデルブロ図形を描画

  1. マンデルブロ集合というのは幾何学、フラクタルと呼ばれる構造を持った図形です。
    その図形の細部を拡大していくと、様々な図形が現れては消え、やがてまたその ・・・
    しかもその複雑で深淵な図形の集合は、オドロク程単純な数式から導き出されています。
  2. プログラムを修正してマンデルブロ図形を描画してみましょう。
    DrawRect() に代えて DrawMandelbrotGraph() を呼び出して下さい。
            async private void Draw()
            {
                ・・・
                    //{ result = DrawRect(pixelWidth, pixelHeight); }
                    { result = DrawMandelbrotGraph(pixelWidth, pixelHeight); }
                ・・・
            }
    
  3. マンデルブロ図形を作成する DrawMandelbrot() メソッドです。
            private byte[] DrawMandelbrotGraph(int width, int height)
            {
                // 4 bytes required for each pixel
                byte[] result = new byte[width * height * 4];
                int resultIndex = 0;
    
                // Max iterations when testing whether a point is in the set
                int maxIterationCount = 50;
    
                // Choose intervals
                Complex minimum = new Complex(-2.5, -1.0);
                Complex maximum = new Complex(1.0, 1);
    
                // Normalize x and y values based on chosen interval and size of WriteableBitmap
                double xScaleFactor = (maximum.Real - minimum.Real) / width;
                double yScaleFactor = (maximum.Imaginary - minimum.Imaginary) / height;
    
                // Plot the Mandelbrot set on x-y plane
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        Complex c = new Complex(minimum.Real + x * xScaleFactor, maximum.Imaginary - y * yScaleFactor);
                        Complex z = new Complex(c.Real, c.Imaginary);
    
                        // Iterate with simple escape-time algorithm
                        int iteration = 0;
                        while (z.Magnitude < 2 && iteration < maxIterationCount)
                        {
                            z = (z * z) + c;
                            iteration++;
                        }
    
                        // Shade pixel based on probability it's in the set
                        byte grayScaleValue = Convert.ToByte(255 - 255.0 * iteration / maxIterationCount);
                        result[resultIndex++] = grayScaleValue; // Green value of pixel
                        result[resultIndex++] = grayScaleValue; // Blue value of pixel
                        result[resultIndex++] = grayScaleValue; // Red value of pixel
                        result[resultIndex++] = 255;            // Alpha value of pixel
                    }
                }
                return result;
            }
    

超初心者のプログラム入門(C# Frame Work)