首页 > 解决方案 > C++ 创建随机形状的“blob”对象

问题描述

我需要定义一个对象(或一个区域),它是一种在离散网格图上形成的“blob”形状。它应该看起来像这样:在此处输入图像描述

其中红色区域表示中心点(这些只是想法,只要可以随机变化,任何斑点形状都可以使用)。到目前为止,我的想法是迭代地将角度从起点(= 0 度)增加到 360 度,并使用三角函数来计算圆的外点(如果半径 = 1 = const,这将导致单位圆)。然后我使用 Bresenham 的线算法(记住:我们在离散网格上移动)来计算连接圆心和我刚刚提出的外点的线。我的想法是,如果我可以稍微改变半径,我就可以创造出这些水滴状的形状。到目前为止,我想出的东西给了我很好的形状,但它们并不是真正的“斑点”。这是我的代码(请注意x0y0标记我的网格图的中心点,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++,但我认为这种方法并不真正依赖于所使用的语言。关于如何创建类似于我需要的形状的任何提示/帮助/指导?或者甚至是为你做这样的事情的框架?对我来说,将点的坐标放入我的网格图中很重要。

标签: c++arrays2ddrawingshapes

解决方案


随角度改变半径是要走的路。但是,您可以使用具有预定幅度和相位的几个周期函数的总和,而不是随机游走。这保证了

  1. 转弯 360° 后半径会恢复到原来的值,
  2. 您可以轻松控制遇到的半径范围。(您需要避免小于零)。

选择一个正弦或余弦函数,将角度乘以一个整数并添加一个随机相位。按随机(预定)幅度缩放每个。添加一个大于所有幅度之和的常数。利润。

我不打算用 C++ 编写这个,因为正如你所说,它不会为算法添加任何重要的东西。它可能是这样的:

  1. 取 N,你想要的波数。
  2. 定义浮点数组amps[N]phases[N].
  3. 为每个 选择一个介于 0 和 1/(2N) 之间的随机数,为每个 选择一个amps[i]介于 0 和 2π 之间的随机数phases[i]
  4. 对于每个角度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;
  1. 像以前一样进行。

结果(来自 Wolfram Mathematica):

为了让它更有趣,将第k个幅度限制为 k 的某个负幂k +1,因为我们从零开始索引)。这是在步骤 3 中将随机数除以 2N 而不是 2N 时,N = 30:pow(i+1,1.5)


推荐阅读