[英]Procedural terrain texture with lines and zones
我目前正在開發一個程序,以程序生成二維地形圖,並在尺寸定義的圖像上使用Perlin噪聲,單純形,voronoi,分形噪聲等不同技術,以便能夠在需要二維地形的游戲中使用它。
我遇到了http://paulbourke.net/fractals/noise的“模擬假行星建模”部分,我需要將其設置為2d紋理,而不是像說明的那樣在3d世界中進行。
現在我想
這將以這種方式工作:
在下面用此方法覆蓋,
http://img35.imageshack.us/img35/24/islf.png
我用我的高中數學能力創建了一個代碼示例,但實際上並沒有用...
問題:
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.