algorithm - 使用 for 循环递增值时计算 n 的值

标签 algorithm flash function math for-loop

首先,对于糟糕的标题感到抱歉。我不太确定如何为这个主题命名,所以请随意修改它。

我正在我的舞台内绘制具有给定尺寸的 X 环。为了给它一些深度感,朝向屏幕边界的每个环都稍微宽一些:

enter image description here

最大的环应与舞台的最大尺寸一样宽(请注意,在图片中我绘制了 3 个额外的环,它们被绘制在舞台边界之外)。它也应该是最小环的两倍宽。对于环,我指的是 2 个红色圆圈之间的空间。

在计算出最小环的宽度 _innerRadius 后,我使用

const RINGS:Number = 10;    //the amount of rings, note we will draw 3 extra rings to fill the screen
const DEPTH:Number = 7; //the amount of size difference between rings to create depth effect

var radius:Number = 0;
for (var i:uint = 0; i < RINGS + 3; i++) {
    radius += _innerRadius + _innerRadius * ((i*DEPTH) / (RINGS - 1));
    _graphics.lineStyle(1, 0xFF0000, 1);
    _graphics.drawCircle(0, 0, radius * .5);
}

底部的一个 slider 从 0 到 100,是从最小到最大的绿色环的半径的百分比。

我尝试在最小半径和最大半径之间进行 lerping,如果 DEPTH 值为 1,效果很好。但是,为了深度的错觉,我不希望环之间的距离相同。

现在我已经尝试了好几个小时来解决这个问题,但似乎我遇到了一堵墙..我似乎需要某种非线性公式..我如何根据以下公式计算半径 slider 百分比值?对于从最小红色圆圈到最大红色圆圈之间或红色圆圈上的任何地方都有效吗?

谢谢!

[编辑] 这是我对 _innerRadius 的示例计算

//lets calculate _innerRadius for 10 rings
//inner ring width =         X + 0/9 * X;
//ring 1 width =         X + 1/9 * X;
//ring 2 width =         X + 2/9 * X
//ring 3 width =         X + 3/9 * X 
//ring 4 width =         X + 4/9 * X 
//ring 5 width =         X + 5/9 * X
//ring 6 width =         X + 6/9 * X
//ring 8 width =         X + 7/9 * X
//ring 9 width =         X + 8/9 * X
//ring 10 width =        X + 9/9 * X

//extent = Math.max(stage.stageWidth, stage.stageHeight);
//now we should solve extent = X + (X + 0/9 * X) + (X + 1/9 * X) + (X + 2/9 * X) + (X + 3/9 * X) + (X + 4/9 * X) + (X + 5/9 * X) + (X + 6/9 * X) + (X + 7/9 * X) + (X + 8/9 * X) + (X + 9/9 * X);
//lets add all X's
//extent = 10 * X + 45/9 * X
//extent = 15 * X;
//now reverse to solve for _innerRadius
//_innerRadius = extent / 15;

最佳答案

你的绘图算法的工作方式,你的半径是:

r[i + 1] = r[i] + (1 + i*a)*r0

其中 a 是一个常量,即 depth/(rings - 1)。这导致:

r0
r1 = r0 + (1 + a)*r0 = (2 + a)*r0
r2 = r1 + (1 + 2*a)*r0 = (3 + 3*a)*r0
r3 = r2 + (1 + 3*a)*r0 = (4 + 6*a)*r0
     ...
rn = (1 + n + a * sum(1 ... n))*r0
   = (1 + n + a * n*(n - 1) / 2)*r0

因为您希望环 n - 1 与您的外半径相对应(让我们暂时忘记三个额外的环),您得到:

r[n - 1] = (n + (n - 1)*(n - 2) / 2)*r0
       a = 2 * (extent / r0 - n) / (n - 1) / (n - 2)

然后你就可以画环了:

for (var i = 0; i < rings; i++) {
    r = (1 + i + 0.5 * a * (i - 1)*i) * r0;
    // draw circle with radius r
}

在计算a 时,您必须至少有三个环才能不被零除。另请注意,这不会对所有组合产生良好的结果:如果外圆和内圆的比率小于环的数量,您将得到负的 a 并且深度效果会反转。

另一种可能更简单的创建深度效果的方法是使每个圆的半径都是前一个圆的常数倍数:

r[i + 1] = r[i] * c

r[i] = r0 * Math.pow(c, i)

然后像这样画出它们:

c = Math.pow(extent / r0, 1 / (rings - 1))

r = r0
for (var i = 0; i < rings; i++) {
    // draw circle with radius r        
    r *= c;
}

只要半径比为正,这就会产生“正”深度效果。 (当然,只要有不止一枚戒指。)

关于algorithm - 使用 for 循环递增值时计算 n 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23400422/

相关文章:

algorithm - 具有优先级的方程(表达式)解析器?

javascript - Flash 使 View 全屏显示

function - scala foreach 和 map 初始化器

flash - 嵌入移动设备

javascript - HTML 会被任何新技术取代吗?

sql - PL/pgSQL : finding all groups person belongs to (also indirectly)

c++ - 重载函数中的静态变量

algorithm - 如何解决填字游戏(NP-Hard)?

c++ - std::shuffle 的可能实现

c++ - 如何将音频字节转换为样本