生成随机花朵的算法创意

5

有人能否提供任何链接、想法或算法来随机生成如我个人资料图片中的花朵?我的资料图片中的花朵只有一个10 x 10的网格,并且该算法并不真正随机。我更喜欢新算法使用大约500 x 500的网格,甚至更好的是,允许用户选择网格的大小。

[Plant[][]被声明为int plant[10][10];]

public void generateSimpleSky(){

    for(int w2=0;w2<10;w2++)
        for(int w3=0;w3<10;w3++)
            plant[w2][w3]=5;

}

public void generateSimpleSoil(){

    for(int q=0;q<10;q++)
        plant[q][9]=1;

}

public void generateSimpleStem(){

    int ry=rand.nextInt(4);
    plant[3+ry][8]=4;
    xr=3+ry;

    for(int u=7;u>1;u--){

        int yu=rand.nextInt(3);
        plant[xr-1+yu][u]=4;
        xr=xr-1+yu;

    }

}

public void generateSimpleFlower(){

    plant[xr][2]=3;

    for(int q2=1;q2<4;q2++)
        if((2-q2)!=0)
            plant[xr][q2]=2;

    for(int q3=xr-1;q3<=xr+1;q3++)
        if((xr-q3)!=0)
            plant[q3][2]=2;

}

2
“Truly random” 是什么意思? - jeremy
4
我赞同@Nile的评论。你可能需要先确定你想要随机的花的是什么。比如颜色、花瓣大小、中心大小/颜色、茎的大小等。对于那朵花的真正随机化将导致一棵非常混乱的植物。 - brainmurphy1
1
你有看过L-Systems吗?http://en.wikipedia.org/wiki/L-system - Henry
请在此处发布您现有的算法,我们将提出改进意见。 - SergeyS
@SergeyS:我会尽快在这里发布。 - Hele
显示剩余4条评论
1个回答

5
这个问题听起来相当简单,您只需要按照先前变量的输出生成一个参数。
我对花的模型是:它有根合理直立的茎,一个完美圆形的中心,在交替的叶片上有一定数量的叶子,花瓣完美地分布在中心周围。 random()只是在一些选择的范围内生成随机数字,这些范围可能对于每个变量都是独特的。random(x1, x2, ..., xn) 在某些依赖于变量x1、x2、...、xn的范围内生成一个随机数字(例如stemWidth < stemHeight/2,这是一个合理的假设)。
stemXPosition = width / 2
stemHeight = random()
stemWidth = random(stemHeight)
stemColour = randomColour()
stemWidthVariationMax = random(stemWidth, stemHeight)
stemWidthVariationPerPixel = random(stemWidth, stemHeight)

stemWidthVariationMax/-PerPixel 用于生成一个不完全直的茎干(如果您想做一些复杂的事情,使用低 PerPixel 可以使其更加平滑)。按照以下方式使用这些内容来生成茎干:

pixelRelative[y-position][0] := left x-position at that y-position relative to the stem
pixelRelative[y-position][1] := right x-position at that y-position relative to the stem

pixelRelative[0][0] = randomInRange(-stemWidthVariationMax, stemWidthVariationMax)
for each y > 0:
  pixelRelative[y-1][0] = max(min(randomInRange(pixel[y] - stemWidthVariationPerPixel,
                                        pixel[y] + stemWidthVariationPerPixel),
                          -stemWidthVariationMax),
                      stemWidthVariationMax)
//pixelRelative[0][1] and pixelRelative[y-1][1] generated same as pixelRelative[y-1][i]
for each y:
  pixelAbsolute[y][0] = width / 2 - stemWidth / 2 + pixelRelative[y][0]
  pixelAbsolute[y][1] = width / 2 + stemWidth / 2 + pixelRelative[y][1]

你还可以使用弧线来简化操作,每次移动超过1个像素。 顶部
centerRadius = random(stemHeight)
petalCount = random() // probably >= 3
petalSize = random(centerRadius, petalCount)

生成花瓣并不容易,你需要从0到2 * PI步进,并以 2 * PI / petalCount 的步长在圆周上生成弧线。这需要一个好的图形API或一些不错的数学知识。 这里有一些漂亮的花朵顶部生成的例子,但似乎不是开源的。请注意,它们根本没有中心点。 (或centerRadius = 0)
叶子:
你可能可以写一篇完整的论文来阐述此问题(例如这篇文章),但一个简单的想法只是生成一个1/2的圆,并向外延伸线条,直到达到圆的2倍半径为止,并在花上绘制平行线。
一旦你有了一个叶子生成算法:
leafSize = random(stemHeight) // either all leaves are the same size or generate the size for each randomly
leafStemLength = random(leafSize) // either all leaves have the same stem length or generate for each randomly
leafStemWidth = random(leafStemLength)
leaf[0].YPosition = random(stemHeight)
leaf[0].XSide = randomly either left or right
leaf[0].rotation = random between say 0 and 80 degrees
for each leaf i:
  leaf[i].YPosition = random(stemHeight, leaf[i-1]) // only generate new leaves above previous leaves
  leaf[i].XSide = opposite of leaf[i].XSide

最后的话

确定每个random范围的方法可以通过争论或给定一个固定值,随机生成其他所有内容几次,不断增加/减少它,直到开始看起来奇怪。

10 x 10与500 x 500可能需要完全不同的算法,我不建议在100 x 100以下使用上述方法,也许生成一个更大的图像,然后使用平均值或其他方法缩小它。

代码

我开始编写一些Java代码,当我意识到这可能需要比我想花费的时间更长时,所以我将展示你我目前为止所拥有的东西。

  // some other code, including these functions to generate random numbers:
  float nextFloat(float rangeStart, float rangeEnd);
  int nextInt(int rangeStart, int rangeEnd);

  ...

  // generates a color somewhere between green and brown
  Color stemColor = Color.getHSBColor(nextFloat(0.1, 0.2), nextFloat(0.5, 1), nextFloat(0.2, 0.8));
  int stemHeight = nextInt(height/2, 3*height/4);
  int stemWidth = nextInt(height/20, height/20 + height/5);
  Color flowerColor = ??? // I just couldn't use the same method as above to generate bright colors, but I'm sure it's not too difficult
  int flowerRadius = nextInt(Math.min(stemHeight, height - stemHeight)/4, 3*Math.min(stemHeight, height - stemHeight)/4);

简单来说,你很棒! - Hele

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接