这听起来像是一个相当简单的问题,您一次只生成 1 个参数,可能基于先前变量的输出。
我的花模型是:它只有一个相当直立的茎,一个完美的圆形中心,茎上交替的两侧有一些叶子,花瓣完美地分布在中心周围。
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)
叶子
您可能可以就此写一篇整篇论文,(如this one)但一个简单的想法就是生成一个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);