5

私は学習目的で独自の中点変位アルゴリズムを作成しており、1) アルゴリズムを理解できるかどうか、2) 好みに合わせて変更できるかどうかを確認するために、独自の方法で実装することにしました。

フラクタルを生成するコードは次のとおりです。

 public void Generate(Double rg, int size)
    {
        Random rand = new Random();
        int min = -127;
        int max = 128;

        // Starting points of the rectangle
        MDP_Point s1 = new MDP_Point(0, 0, rand.Next(min, max));
        MDP_Point s2 = new MDP_Point(size, 0, rand.Next(min, max));
        MDP_Point s3 = new MDP_Point(size, size, rand.Next(min, max));
        MDP_Point s4 = new MDP_Point(0, size, rand.Next(min, max));

        // Lists containing the rectangles
        List<MDP_Rect> newRect = new List<MDP_Rect>();  // Newly created rectangles
        List<MDP_Rect> oldRect = new List<MDP_Rect>();  // Rectangles being divided


        // Starting rectangle is added to the list
        oldRect.Add(new MDP_Rect(s1, s2, s3, s4));

        // Distance between 2 points in a rectangle
        int h = size;

        while (h > 1)
        {
            foreach (MDP_Rect r in oldRect)
            {
                // Middle points of rectangle segments
                MDP_Point m1 = new MDP_Point();
                MDP_Point m2 = new MDP_Point();
                MDP_Point m3 = new MDP_Point();
                MDP_Point m4 = new MDP_Point();
                // Middle point of rectangle
                MDP_Point mm = new MDP_Point();

                m1.x = (r.C1.x + r.C2.x) / 2;
                m1.y = (r.C1.y + r.C2.y) / 2;
                m1.z = ((r.C1.z + r.C2.z) / 2) +(rand.Next(min, max) * rg);

                m2.x = (r.C2.x + r.C3.x) / 2;
                m2.y = (r.C2.y + r.C3.y) / 2;
                m2.z = ((r.C2.z + r.C3.z) / 2) +(rand.Next(min, max) * rg);

                m3.x = (r.C3.x + r.C4.x) / 2;
                m3.y = (r.C3.y + r.C4.y) / 2;
                m3.z = ((r.C3.z + r.C4.z) / 2) +(rand.Next(min, max) * rg);

                m4.x = (r.C1.x + r.C4.x) / 2;
                m4.y = (r.C1.y + r.C4.y) / 2;
                m4.z = ((r.C1.z + r.C4.z) / 2) + (rand.Next(min, max) * rg);

                mm.x = (r.C1.x + r.C2.x + r.C3.x + r.C4.x) / 4;
                mm.y = (r.C1.y + r.C2.y + r.C3.y + r.C4.y) / 4;
                mm.z = ((r.C1.z + r.C2.z + r.C3.z + r.C4.z) / 4) + (rand.Next(min, max) * rg);

                newRect.Add(new MDP_Rect(r.C1, m1, mm, m4));
                newRect.Add(new MDP_Rect(m1, r.C2, m2, mm));
                newRect.Add(new MDP_Rect(mm, m2, r.C3, m3));
                newRect.Add(new MDP_Rect(m4, mm, m3, r.C4));
            }


            oldRect.Clear();
            oldRect = new List<MDP_Rect>(newRect);
            newRect.Clear();
            h /= 2;
        }

        List<MDP_Rect> sorted = new List<MDP_Rect>();
        sorted = oldRect.OrderBy(y => y.C1.y).ThenBy(x => x.C1.x).ToList();

        List<MDP_Point> mapArray = new List<MDP_Point>();
        mapArray.AddRange(CreateArray(sorted));

        CreateImage(size, mapArray, rg);
    }

MDP_Point には x、y、z の値のみが含まれます MDP_Rectangle には 4 つの点が含まれ、長方形を作成します

CreateArray() メソッドは、正しい順序で並べられた四角形のリストと出力およびポイントのリストのみを取得して、画像を作成します。

CreateArray():

        private List<MDP_Point> CreateArray(List<MDP_Rect> lRect)
    {
        List<MDP_Point> p = new List<MDP_Point>();

        int size = (int)Math.Sqrt(lRect.Count);

        int i = 0;
        foreach (MDP_Rect r in lRect)
        {
            p.Add(new MDP_Point((int)r.C1.x, (int)r.C1.y, (int)r.C1.z));

            if (i > 0 && i % size == size - 1)
            {
                p.Add(new MDP_Point((int)r.C2.x, (int)r.C2.y, (int)r.C2.z));
            }

            i++;
        }

        for (int a = 0; a < size; a++)
        {
            p.Add(new MDP_Point((int)lRect[(size * size - size) + a].C4.x,
                (int)lRect[(size * size - size) + a].C4.y,
                (int)lRect[(size * size - size) + a].C4.z));

            if (a > 0 && a % size == size - 1)
            {
                p.Add(new MDP_Point((int)lRect[(size * size - size) + a].C3.x,
                    (int)lRect[(size * size - size) + a].C3.y,
                    (int)lRect[(size * size - size) + a].C3.z));
            }
        }

        return p;
    }

これは、イメージを作成する方法です。

        private void CreateImage(int size, List<MDP_Point> arr, double roughness)
    {
        Bitmap map = new Bitmap(size, size);

        int ver = 0;
        for (int i = 0; i < map.Height; i++)
        {
            for (int n = 0; n < map.Width; n++ )
            {
                int h = (int)arr[ver].z + 127;
                if (h < 0)
                {
                    h = 0;
                }
                else if (h > 255)
                {
                    h = 255 ;
                }
                Color c = Color.FromArgb(h, h, h);

                //map.SetPixel(n, i, c);
                map.SetPixel(i, n, c);
                ver++;
            }
        }

        Bitmap m = new Bitmap(map);
        bool saved = true;
        int num = 0;

        while (saved)
        {
            if (File.Exists("map_S" + size + "_R" + roughness + "_" + num + ".png"))
            {
                num++;
            }
            else
            {
                m.Save("map_S" + size + "_R" + roughness + "_" + num + ".png", System.Drawing.Imaging.ImageFormat.Png);
                saved = false;
            }
        }

        map.Dispose();
        m.Dispose();
    }

0 未満の値が 0 に設定され、255 を超える値が 255 に設定されるという事実は、おそらく大きな問題です....どうすればよいかわかりません。

コードによって生成された画像は次のとおりです: サイズ: 1024 粗さ: 0.5

ここに画像の説明を入力

最も明白な問題は、斜めの「稜線」とそこにあるタイル状の外観です。

この時点で、これを修正してより自然に見えるようにするにはどうすればよいかわかりません。何か案は?

4

2 に答える 2

1

hここで、問題の一部は、 255と0の変数のハッキングだと思います。次を使用してコードを試しました。

int h = (int) arr[ver].z;
if (h < 0)
{
    h = Math.Abs(h);
}
while(h > 255)
{
    h -= 255;
}

私のPCでの結果は次のとおりです。 1を取る

そして私が使用したとき:

int h = (int) arr[ver].z + 127;

2を取る

MDP_Pointテストクラスを作成してこれをテストする必要があることに注意MDP_Rectしてください...

于 2012-07-25T05:12:52.580 に答える