簡體   English   中英

帶有線條和區域的程序地形紋理

[英]Procedural terrain texture with lines and zones

我目前正在開發一個程序,以程序生成二維地形圖,並在尺寸定義的圖像上使用Perlin噪聲,單純形,voronoi,分形噪聲等不同技術,以便能夠在需要二維地形的游戲中使用它。

我遇到了http://paulbourke.net/fractals/noise的“模擬假行星建模”部分,我需要將其設置為2d紋理,而不是像說明的那樣在3d世界中進行。

現在我想

  1. 創建從點“ X”到點“ Y”的線
  2. 該行將定義一個具有布爾值的區域,該行的左側或右側為“較暗”。
  3. 進行多次迭代以創建紋理。
  4. 使用最終圖像的RGB值更改諸如森林,湖泊等之類的東西。

這將以這種方式工作:

在下面用此方法覆蓋,

http://img35.imageshack.us/img35/24/islf.png

我用我的高中數學能力創建了一個代碼示例,但實際上並沒有用...

問題:

  1. 我應該如何更改它以使其起作用而不僅僅是失敗?
  2. 有沒有比使用我正在使用的方法更簡單的方法?

Java文件:如果我需要有關如何進行的示例,則為:

package Generator;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

import VectorialStuffs.Vector2;

public class Linear
{
    public static BufferedImage generateImage(Dimension dim, int iterations)
    {
        BufferedImage image = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_ARGB);

        //point X and point Y
        Vector2 pointX;
        Vector2 pointY;

        //difference between those
        Vector2 diff;
        Vector2 side;
        double slope;

        //random
        Random rand = new Random();
        boolean direction;              //the orientation of the dark zone. (left/right)

        for (int i = 0; i < iterations; ++i)
        {
            pointX = new Vector2(0, 0);
            pointY = new Vector2(0, 0);
            direction = rand.nextBoolean();
            System.out.println(direction);

            side = new Vector2(0, 0);   //there are 4 sides of the image.
            while (side.x == side.y)
            {
                side.x = rand.nextInt(3);   //0 - 1 - 2 - 3
                side.y = rand.nextInt(3);
            }

            switch(side.x)  //not the x coord, the X point! ;D
            {
                //x = random and y = 0
                case 0:
                    pointX.x = rand.nextInt(dim.width);
                    pointX.y = 0;
                break;
                //x = max and y = random
                case 2:
                    pointX.x = dim.width;
                    pointX.y = rand.nextInt(dim.height);
                break;
                //x = random and y = max
                case 1:
                    pointX.x = rand.nextInt(dim.width);
                    pointX.y = dim.height;
                break;
                //x = 0 and y = random
                case 3:
                    pointX.x = 0;
                    pointX.y = rand.nextInt(dim.height);
                break;
            }

            switch(side.y)  //not the y coord, the Y point! ;D
            {
                //x = random and y = 0
                case 0:
                    pointY.x = rand.nextInt(dim.width);
                    pointY.y = 0;
                break;
                //x = max and y = random
                case 2:
                    pointY.x = dim.width;
                    pointY.y = rand.nextInt(dim.height);
                break;
                //x = random and y = max
                case 1:
                    pointY.x = rand.nextInt(dim.width);
                    pointY.y = dim.height;
                break;
                //x = 0 and y = random
                case 3:
                    pointY.x = 0;
                    pointY.y = rand.nextInt(dim.height);
                break;
            }

            diff = new Vector2((pointY.x - pointX.x), (pointY.y - pointX.y));
            slope = diff.y / diff.x;

            Graphics graph = image.getGraphics();

            if (direction)  //true = right | false = left
            {
                int start;  //the start x coordinate, on the line then increases until reaching the end of the image
                int end = dim.width;

                graph.setColor(Color.red);
                graph.fillRect(pointX.x - 8, pointX.y -8, 16, 16);
                graph.setColor(Color.yellow);
                graph.fillRect(pointY.x - 8, pointY.y -8, 16, 16);

                for (int times = 0; times < dim.height; ++times)    //horizontal drawer
                {
                    System.out.println(times);
                    start = (int)((times-diff.y)/slope + diff.y);   //this is where it goes wrong?
                    for (int value = start; value < end; ++value)
                    {
                        graph.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255), 100));
                        graph.fillRect(value, times, 1, 1);
                    }
                }
                graph.dispose();
            }
            else
            {
                int start;  //the start x coordinate, on the line then increases until reaching the end of the image
                int end = dim.width;

                graph.setColor(Color.red);
                graph.fillRect(pointX.x - 8, pointX.y -8, 16, 16);
                graph.setColor(Color.yellow);
                graph.fillRect(pointY.x - 8, pointY.y -8, 16, 16);

                for (int times = 0; times < dim.height; ++times)    //horizontal drawer
                {
                    System.out.println(times);
                    start = (int)((times-diff.y)/slope);
                    for (int value = end; value < start; --value)
                    {
                        graph.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255), 100));
                        graph.fillRect(value, times, 1, 1);
                    }
                }
                graph.dispose();
            }
        }

        return image;
    }
}

注意:在這種情況下,vector2只是具有X和Y的類,可以訪問(這可能是臨時的)。

啟動部分,以避免浪費時間:

terrainImage = Linear.generateImage(size, 1);   //size being a Dimension. -> "new Dimension(256, 256)"
if (terrainImage != null)
{
    Icon wIcon = new ImageIcon(terrainImage);
    JOptionPane.showMessageDialog(null, "message", "title", JOptionPane.OK_OPTION, wIcon);
}

//編輯下面是需要改進的代碼:

if (direction)  //true = right | false = left
                {
                    int start;  //the start x coordinate, on the line then increases until reaching the end of the image
                    int end = dim.width;

                    graph.setColor(Color.red);
                    graph.fillRect(pointX.x - 8, pointX.y -8, 16, 16);
                    graph.setColor(Color.yellow);
                    graph.fillRect(pointY.x - 8, pointY.y -8, 16, 16);

                    for (int times = 0; times < dim.height; ++times)    //horizontal drawer
                    {
                        System.out.println(times);
                        start = (int)((times-diff.y)/slope + diff.y);   //this is where it goes wrong?
                        for (int value = start; value < end; ++value)
                        {
                            graph.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255), 100));
                            graph.fillRect(value, times, 1, 1);
                        }
                    }
                    graph.dispose();
                }
                else
                {
                    int start;  //the start x coordinate, on the line then increases until reaching the end of the image
                    int end = dim.width;

                    graph.setColor(Color.red);
                    graph.fillRect(pointX.x - 8, pointX.y -8, 16, 16);
                    graph.setColor(Color.yellow);
                    graph.fillRect(pointY.x - 8, pointY.y -8, 16, 16);

                    for (int times = 0; times < dim.height; ++times)    //horizontal drawer
                    {
                        System.out.println(times);
                        start = (int)((times-diff.y)/slope);
                        for (int value = end; value < start; --value)
                        {
                            graph.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255), 100));
                            graph.fillRect(value, times, 1, 1);
                        }
                    }
                    graph.dispose();
                }

我無法像上圖所示那樣使它正常工作,它所做的全部都不是,也不是從2點偏移。 另外,有時它會無緣無故死機,所以idk如果我對此進行更多迭代,會發生什么:/

代碼的圖案生成元素應該只占用3行,包括旋轉,顏色圖案調制以及所有與i迭代有關的函數。

我會嘗試清楚一點:

您不需要條形圖線就可以生成地圖,您需要在一個/ 2軸上的任何模式都可以從地圖周期的一半開始,並且在地圖中所占的比例越來越小或周期越來越小。

圖案:

一條線是圓的(x); 或圓角(x + y)或圓角(sin(x + y + translatebar)+ barwidth)<-中間的實線,不僅在側面// //您可以稍后使用加法和乘法來制作曲線和鋸齒形線,以及2D線X和Y函數。 該函數實際上只是一行,您可以在其中更改X值以便旋轉。

回轉:

而不是每次使用功能性X生成一條垂直線,您都需要使用正弦和余弦函數生成X和Y值。

4例30; 旋轉為:圓(X * 0.866+ Y * 0.5)

得到一個隨機值的正弦和余弦,它將為您提供模式的隨機旋轉。方便的事情是,您只需對循環迭代生成一個隨機值並將其發送給正弦余弦。

好吧,我將用偽代碼編寫它,這樣會更簡單:


var pattern = 0; // black canvas

for(var i=1; i=100; i++)
{
   pattern += round((sin   (X*sin(pseudorand(i))  + Y*cos(pseudorand(i)) + translation) + roundshift )*strength;
}

上面的循環通過添加不同旋轉的條形圖將生成數千個地圖圖案。

Round =量化您的sin(XY)函數,因此它只是黑白/紅色灰色。

Sin(XY)=用作模式的變量函數,通過舍入量化為0/1值...將該值乘以並鉗制在同一行中,以使其不超過1或0

roundshift = round(sin)模式內的值,該值在正整數值內上下移動正弦,從而導致每次迭代的黑白比值變小或變大。 它是i的倍數,所以它是i的函數,每個循環變小。

xsin(rnd i)ycos(rnd i)=旋轉您的圖案,兩個rnd的編號必須相同。

轉換值=當您將數字+/-為Sin(x + translate)時。 它向后/向前移動欄

最終,您的圖案值將等於最大值100,因此將其除以100,使其為0-1,或者對2.5乘以2.56,然后使用顏色隨機化器將RGB隨機值作為圖案值的倍數。

上面的循環顯然需要為每個像素x y運行一次。

我不知道如何在JS中做canvas數組/紋理插件像素,這應該很容易。

上面的代碼將為您提供錯誤的出色模式和可視反饋,因此您應該能夠很好地對其進行細化,僅認為我錯過的就是將sin(-1 1)+輪班結果固定在0-1值。

因此,條形是圓形的(sin(xy)+ translate),您可以使用xy的許多功能添加多義的罪孽,將條形圖,圖形圓,正方形,擺動,橢圓形,矩形等其他所有內容加在一起。

有一個關於這種類型圖案的網站,除了有序的角度和說5-6次迭代,使用圓點,三角形等外,他是加拿大人,並且也是異常藝術作品,如果沒有那么多TD圖案生成,我可以找到他的網站!

這是一個解釋“圖案堆積”過程的網站,它以越來越小的迭代方式覆蓋了許多形狀。

唯一的區別是他使用有序旋轉來創建對稱性,而您想要隨機旋轉來創建混沌圖。

看到2d中所有堆積圖案的照片,他有許多關於異常藝術的例子以及他的網站,我從這個人身上學到了很多東西:

http://algorithmic-worlds.net/info/info.php?page=pilpat,這是有關對稱旋轉中越來越小的圖案疊加的更多工作: https : //www.google.com/search?q=Samuel+Monnier&espv = 210&es_sm = 93&源= LNMS&TBM = isch&SA = X&EI = It0AU9uTCOn20gXXv4G4Cw&VED = 0CAkQ_AUoAQ&BIW = 1365&波黑= 911

與此相同,使用隨機sin cos旋轉。

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM