C++ 创建随机形状 "blob" 对象
C++ create random shaped "blob" objects
我需要定义一个对象(或区域),该对象(或区域)类似于 "blob" 在离散网格图上的形状。它应该看起来像这样:
其中红色区域表示中心点(这些只是想法,只要可以随机变化,任何斑点形状都可以)。到目前为止,我的想法是将角度从起点(= 0 度)迭代增加到 360 度,并使用三角函数计算圆的外点(如果半径 = 1 = const,这将导致单位圆)。然后我使用 Bresenham 的线算法(记住:我们在离散网格上移动)来计算连接圆心和我刚想出的外点的线。我的想法是,如果我可以稍微改变半径,就可以创建这些斑点形状。到目前为止我想出的东西给了我漂亮的形状,但它们并不是真的 "blobby"。这是我的代码(请注意,x0
和 y0
标记了我的网格图的中心点,plotBresenham
只是将所有 1s
放在区域中,以便可以可视化网格图):
double radius = 10;
for(int alpha=0; alpha<360; alpha++) {
double x = cos(alpha*M_PI/180.0)*radius;
double y = sin(alpha*M_PI/180.0)*radius;
if(alpha<45) radius+=0.5;
else if(alpha<90) radius-=0.5;
else if(alpha<135) radius+=0.5;
else if(alpha<180) radius-=0.5;
else if(alpha<225) radius+=0.5;
else if(alpha<270) radius-=0.5;
else if(alpha<315) radius+=0.5;
else radius-=0.5;
plotBresenhamLine(x0,y0,x,y)
}
结果如下所示:
抱歉粗略的绘图。编程语言是 C++,但我认为这种方法并不真正取决于所使用的语言。关于如何创建更像我需要的形状的任何提示/帮助/指导?或者甚至是一个为你做这样的事情的框架?对我来说,重要的是要有点的坐标,把它们放到我的网格图中。
对于斑点形状,metaballs 的(有点密集的)星座可能会产生漂亮的形状。
改变半径和角度是可行的方法。但是您可以使用几个具有预定振幅和相位的周期函数的总和来代替随机游走。这保证
- 旋转360°后半径恢复原值,
- 您可以轻松控制遇到的半径范围。 (你需要避免小于零)。
选择一个正弦或余弦函数,将角度乘以一个整数并添加一个随机相位。按随机(预先确定的)幅度缩放每个。添加一个大于所有振幅之和的常数。利润。
我不会用 C++ 编写它,因为正如您所说,它不会为算法添加任何重要内容。它可能是这样的:
- 取N,你想要的波数。
- 定义浮点数组
amps[N]
和 phases[N]
.
- 为每个
amps[i]
选择一个介于 0 和 1/(2N) 之间的随机数,为每个 phases[i]
选择一个介于 0 和 2π 之间的随机数。
- 对于每个角度
alpha
(以弧度为单位),计算
radius = 1 + sum[i=0 to N-1] amps[i] * cos((i+1)*alpha + phases[i])
x = cos(alpha)*radius;
y = sin(alpha)*radius;
- 像以前一样进行。
结果(来自 Wolfram Mathematica):
为了让它更有趣,用k(或k+1,因为我们从零开始索引)。这是在第 3 步中将随机数除以 pow(i+1,1.5)
而不是 2N,对于 N = 30:
我需要定义一个对象(或区域),该对象(或区域)类似于 "blob" 在离散网格图上的形状。它应该看起来像这样:
其中红色区域表示中心点(这些只是想法,只要可以随机变化,任何斑点形状都可以)。到目前为止,我的想法是将角度从起点(= 0 度)迭代增加到 360 度,并使用三角函数计算圆的外点(如果半径 = 1 = const,这将导致单位圆)。然后我使用 Bresenham 的线算法(记住:我们在离散网格上移动)来计算连接圆心和我刚想出的外点的线。我的想法是,如果我可以稍微改变半径,就可以创建这些斑点形状。到目前为止我想出的东西给了我漂亮的形状,但它们并不是真的 "blobby"。这是我的代码(请注意,x0
和 y0
标记了我的网格图的中心点,plotBresenham
只是将所有 1s
放在区域中,以便可以可视化网格图):
double radius = 10;
for(int alpha=0; alpha<360; alpha++) {
double x = cos(alpha*M_PI/180.0)*radius;
double y = sin(alpha*M_PI/180.0)*radius;
if(alpha<45) radius+=0.5;
else if(alpha<90) radius-=0.5;
else if(alpha<135) radius+=0.5;
else if(alpha<180) radius-=0.5;
else if(alpha<225) radius+=0.5;
else if(alpha<270) radius-=0.5;
else if(alpha<315) radius+=0.5;
else radius-=0.5;
plotBresenhamLine(x0,y0,x,y)
}
结果如下所示:
抱歉粗略的绘图。编程语言是 C++,但我认为这种方法并不真正取决于所使用的语言。关于如何创建更像我需要的形状的任何提示/帮助/指导?或者甚至是一个为你做这样的事情的框架?对我来说,重要的是要有点的坐标,把它们放到我的网格图中。
对于斑点形状,metaballs 的(有点密集的)星座可能会产生漂亮的形状。
改变半径和角度是可行的方法。但是您可以使用几个具有预定振幅和相位的周期函数的总和来代替随机游走。这保证
- 旋转360°后半径恢复原值,
- 您可以轻松控制遇到的半径范围。 (你需要避免小于零)。
选择一个正弦或余弦函数,将角度乘以一个整数并添加一个随机相位。按随机(预先确定的)幅度缩放每个。添加一个大于所有振幅之和的常数。利润。
我不会用 C++ 编写它,因为正如您所说,它不会为算法添加任何重要内容。它可能是这样的:
- 取N,你想要的波数。
- 定义浮点数组
amps[N]
和phases[N]
. - 为每个
amps[i]
选择一个介于 0 和 1/(2N) 之间的随机数,为每个phases[i]
选择一个介于 0 和 2π 之间的随机数。 - 对于每个角度
alpha
(以弧度为单位),计算
radius = 1 + sum[i=0 to N-1] amps[i] * cos((i+1)*alpha + phases[i])
x = cos(alpha)*radius;
y = sin(alpha)*radius;
- 像以前一样进行。
结果(来自 Wolfram Mathematica):
为了让它更有趣,用k(或k+1,因为我们从零开始索引)。这是在第 3 步中将随机数除以 pow(i+1,1.5)
而不是 2N,对于 N = 30: