计算不完美的圆圈

时间:2015-03-25 11:20:09

标签: java android math

我想创建一个“不完美的圆圈”的创作者,圆圈有点扭曲,更随机,但仍然看起来有点像圆圈或云。

这就是我所说的不完美的圆圈: enter image description here

我想创建一个能够获得“不完美圆圈”的最大和最小比例的函数,并得到它的所有点。我知道一个圆的公式: X ^ 2 + Y ^ 2 = R ^ 2但我想不出一种让它更随机的方法。有人有什么想法吗?

编辑:试图用点绘制一个完美的圆圈,但它不起作用:

    for (int step = 0; step < 300; ++step) {
         double t = step / 300 * 2 * Math.PI;
         c.drawPoint(300+(float)(33 * Math.cos(t)), 300+(float)(33 * Math.sin(t)), p);
    }

编辑2:

    for (int step = 0; step < 20; ++step) {
          double t = step / 20.0 * 2 * Math.PI; 
          double imperfectR = 50.0+randInt(10, 50);
          //I do it here?
          points[step]=new PointF();
          points[step].set((300+(float)(imperfectR  * Math.cos(t))), 300+(float)(imperfectR  * Math.sin(t)));
          if(step==0){
                pp.moveTo(points[step].x, points[step].y);
          }
          else
                pp.quadTo(points[step-1].x, points[step-1].y,points[step].x, points[step].y);

    } 

编辑3:

double t=0;
for (int i = 0; i < points.length/4; i++) {
        if(t==1){
            t=0;
        }
        t+=0.10;
        double imperfectR=0.5*((2*points[i+1].y)+(-points[i].y+points[i+2].y)*t+(2*points[i].y-5*points[i+1].y+4*points[i+2].y-points[i+3].y)*(t*t)+((-points[i].y+3*points[i+1].y-3*points[i+2].y+points[i+3].y)*(t*t*t)));
        newPoints[i].set((300+(float)(imperfectR  * Math.cos(t))), 300+(float)(imperfectR  * Math.sin(t)));
        t+=0.10;
        imperfectR=0.5*((2*points[i+1].y)+(-points[i].y+points[i+2].y)*t+(2*points[i].y-5*points[i+1].y+4*points[i+2].y-points[i+3].y)*(t*t)+((-points[i].y+3*points[i+1].y-3*points[i+2].y+points[i+3].y)*(t*t*t)));
        newPoints[i+1].set((300+(float)(imperfectR  * Math.cos(t))), 300+(float)(imperfectR  * Math.sin(t)));
        t+=0.10;
        imperfectR=0.5*((2*points[i+1].y)+(-points[i].y+points[i+2].y)*t+(2*points[i].y-5*points[i+1].y+4*points[i+2].y-points[i+3].y)*(t*t)+((-points[i].y+3*points[i+1].y-3*points[i+2].y+points[i+3].y)*(t*t*t)));
        newPoints[i+2].set((300+(float)(imperfectR  * Math.cos(t))), 300+(float)(imperfectR  * Math.sin(t)));
        t+=0.10;
        imperfectR=0.5*((2*points[i+1].y)+(-points[i].y+points[i+2].y)*t+(2*points[i].y-5*points[i+1].y+4*points[i+2].y-points[i+3].y)*(t*t)+((-points[i].y+3*points[i+1].y-3*points[i+2].y+points[i+3].y)*(t*t*t)));
        newPoints[i+3].set((300+(float)(imperfectR  * Math.cos(t))), 300+(float)(imperfectR  * Math.sin(t)));
        if(i==0){
            pp.moveTo(newPoints[i].x, newPoints[i].y);
        }
        pp.lineTo(newPoints[i].x, newPoints[i].y);
        pp.lineTo(newPoints[i+1].x, newPoints[i+1].y);
        pp.lineTo(newPoints[i+2].x, newPoints[i+2].y);
        pp.lineTo(newPoints[i+3].x, newPoints[i+3].y);

}
pp.close();

1 个答案:

答案 0 :(得分:3)

圆形的另一个等式,它更容易绘制,是其参数形式之一:

x = R * cos(t);
y = R * sin(t);

其中R是标称半径,t02 * pi之间的参数。所以,你可以在圆周上绘制一个像这样的“完美”圆圈:

for (int step = 0; step < NSTEPS; ++step) {
  double t = step / (double) NSTEPS * 2 * pi;
  drawPoint(R * cos(t), R * sin(t));
}

根据@nikis的建议,您可以通过在圆的半径上添加随机数量来使圆圈“不完美”:

for (int step = 0; step < NSTEPS; ++step) {
  double t = step / (double) NSTEPS * 2 * pi;
  double imperfectR = R + randn();  // Normally distributed random
  drawPoint(imperfectR * cos(t), imperfectR * sin(t));
}

然而,这可能会给你非常尖锐的形状,因为没有任何东西可以使stepstep + 1的半径相似。在不失一般性的情况下,您可以将上面的代码重写为:

for (int step = 0; step < NSTEPS; ++step) {
  double t = step / (double) NSTEPS * 2 * pi;
  double imperfectR = f(t);
  drawPoint(imperfectR * cos(t), imperfectR * sin(t));
}

其中f(t)是为参数t生成半径的函数。现在,您可以选择t的任何函数,但您可能希望选择在圆上连续的内容,即f(t)突然改变值没有任何意义。

这里有很多选择。我上面建议的例子是建议使用余弦函数的总和:

double f(double t) {
  double f = 0;
  for (int i = 0; i < N; ++i) {
    f += A[i] * cos(i * t + w[i]);
  }
  return f;
}

其中Aw是随机选择的值; A[0]应设为R。这里的要点是余弦函数的周期为2 * pi,因此f(alpha) = f(alpha + 2 * pi)满足连续的要求。

然而,这远非唯一的选择。你可以选择像高斯内核之和那样的东西,它将“凸起”置于w[i]的中心,并在圆周上放置sigma[i]

double f(double t) {
  double f = 0;
  for (int i = 0; i < N; ++i) {
    f += A[i] * exp(-Math.pow(t-w[i], 2) / sigma[i]);
  }
  return f;
}

(这不起作用,它不处理t

的环绕

您需要四处游戏,看看哪些功能以及哪种随机选择的值可以为您提供所需的形状。