我有一系列要放在同心圆上的项目。参见图。我在数学上遇到麻烦。

我可以计算“ steps”变量(每个项目为40x40,因此,步长是周长除以宽度加边距)。而且我可以根据半径和步长来计算点,但是我不知道如何根据当前项目索引来计算半径。

for(var i = 0; i < items.length; i++) {
    var radius = functionOf(i)??;
    var steps = Math.floor((2*radius*Math.PI)/60);
    var x = Math.floor(0 + radius * Math.cos(2 * Math.PI * index / steps));
    var y = Math.floor(0 + radius * Math.sin(2 * Math.PI * index / steps));
    //draw item at x,y
}


关于如何计算半径作为i的函数的思考?

最佳答案

您可以使用算术级数的总和来计算每个项目的半径(对于等距的圆形数,即形成该级数的项目),但是有一种更简单,更快速的方法-填充圆后更改半径(伪代码)

var radius = 0;
var i = 0;
while (i < items.length) {
    var steps = Math.floor((2*radius*Math.PI)/60);
    for(var index = 0; index < steps; index++) {
        var x = Math.floor(0 + radius * Math.cos(2 * Math.PI * index / steps));
        var y = Math.floor(0 + radius * Math.sin(2 * Math.PI * index / steps));
        //draw item at x,y
        i++;
        if (i == items.length)
           break;
    }
    radius = radius + 60; //start next circle
}


关于arithmetic progression
对于第一个项a0和差d的级数,前n个成员的总和为

 S = n * (2 * a0 + d * (n - 1)) / 2


因此,要找到某个索引S属于哪个圆,我们必须解决二次不等式(找到最大整数x来满足条件)

 x^2 * d + x * (2 * a0 - d) - 2 * S <= 0


在Delphi中检查解决方案:

  function GetCircle(a0, d, i: Integer): Integer;
  var
    Discr: Double;
  begin
    Discr := (2 * a0 - d) * (2 * a0 - d) + 8 * i * d;
    if Discr < 0 then
      Exit(0);
    Result := Floor((d - 2 * a0 + Sqrt(Discr)) / (2 * d));
  end;


对于情况a0 = 1,d = 6(您的图片有所不同-进度不精确),它给出

 i=0:       0
 i=1..7:    1
 i=8..20:   2
 i=21..39:  3
 and so on


这表示:
第0个项目位于半径为0的圆上
半径为1 * R的圆处的第三项
半径2 * R的圆处的第11个项目
...

关于javascript - 在同心圆上绘制点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38355808/

10-09 13:52