首先,只是为了直观地了解我所追求的,这是我找到的最接近的结果(但还不完全是我所追求的)图像:

这是整个网站引用:http://www.mathematische-basteleien.de/spiral.htm

但是,它并不能完全解决我所追求的问题。我想存储一个非常具体的螺旋算法的点数组。

  • 点数均匀分布
  • 360度循环的间隙均匀

    如果我没记错的话,前两点将是:
  • point [0] =新Point(0,0);
  • point [1] =新Point(1,0);

  • 但是从这里去哪里呢?

    我想提供的唯一参数是:
  • 我要解决的点数(数组的长度)。
  • 每个点之间的距离(像素间距)。
  • 循环之间的距离。

  • 在我看来,我似乎必须计算“螺旋周长”(如果有这样的术语),以便沿螺旋线绘制均匀分布的点。

    您认为 2 * PI * radius 是否可以可靠地用于此计算?

    如果之前已完成,请显示一些代码示例!

    最佳答案

    好玩的小问题:)

    如果您仔细查看该图,则会清楚地说明该顺序:

    可能有很多解决方案来绘制这些图形,也许更优雅,但这是我的:

    您知道斜边是当前段数的平方根+1
    三角形的另一侧始终为1。

    您还知道角度的正弦(Math.sin)等于反边除以斜边。
    来自旧的羊膜SOH(正弦,对面,斜边),-CAH-TOA。

    Math.sin(angle) = opp/hyp
    

    您知道该角度的正弦值,您知道两个侧面,但是您还不知道该角度,但是您可以使用反正弦函数(Math.asin)
    angle = Math.asin(opp/hyp)
    

    现在,您知道了每个线段的角度,并注意到它随着每条线的增加而增加。

    现在,您已经有了一个角度和半径(斜边),可以将极坐标转换为笛卡尔公式,以将该角度,radius 对转换为 x,y 对。
    x = Math.cos(angle) * radius;
    y = Math.sin(angle) * radius;
    

    由于您要求使用 ActionScript 解决方案,因此Point类已经通过polar()方法为您提供了此功能。您传递给它一个半径和角度,它会在Point对象中返回x和y。

    这是绘制螺旋的小片段。您可以通过在Y轴上移动鼠标来控制段数。
    var sw:Number = stage.stageWidth,sh:Number = stage.stageHeight;
    this.addEventListener(Event.ENTER_FRAME,update);
    function update(event:Event):void{
        drawTheodorus(144*(mouseY/sh),sw*.5,sh*.5,20);
    }
    //draw points
    function drawTheodorus(segments:int,x:Number,y:Number,scale:Number):void{
        graphics.clear();
        var points:Array = getTheodorus(segments,scale);
        for(var i:int = 0 ; i < segments; i++){
            points[i].offset(x,y);
            graphics.lineStyle(1,0x990000,1.05-(.05+i/segments));
            graphics.moveTo(x,y);//move to centre
            graphics.lineTo(points[i].x,points[i].y);//draw hypotenuse
            graphics.lineStyle(1+(i*(i/segments)*.05),0,(.05+i/segments));
            if(i > 0) graphics.lineTo(points[i-1].x,points[i-1].y);//draw opposite
        }
    }
    //calculate points
    function getTheodorus(segments:int = 1,scale:Number = 10):Array{
        var result = [];
        var radius:Number = 0;
        var angle:Number = 0;
        for(var i:int = 0 ; i < segments ; i++){
            radius = Math.sqrt(i+1);
            angle += Math.asin(1/radius);//sin(angle) = opposite/hypothenuse => used asin to get angle
            result[i] = Point.polar(radius*scale,angle);//same as new Point(Math.cos(angle)*radius.scale,Math.sin(angle)*radius.scale)
        }
        return result;
    }
    

    本可以用更少的行写,但是我想将其分为两个函数:
    一个只处理数字,另一个处理画线。

    以下是一些屏幕截图:



    为了好玩,我使用ProcessingJS here添加了此版本。
    运行有点慢,所以我建议为此使用Chromium/Chrome。

    现在,您实际上可以在此处运行此代码(上下移动鼠标):

    var totalSegments = 850,hw = 320,hh = 240,segments;
    var len = 10;
    points = [];
    function setup(){
      createCanvas(640,480);
      smooth();
      colorMode(HSB,255,100,100);
      stroke(0);
      noFill();
      //println("move cursor vertically");
    }
    function draw(){
      background(0);
      translate(hw,hh);
      segments = floor(totalSegments*(mouseY/height));
      points = getTheodorus(segments,len);
      for(var i = 0 ; i < segments ; i++){
        strokeWeight(1);
        stroke(255-((i/segments) * 255),100,100,260-((i/segments) * 255));
        line(0,0,points[i].x,points[i].y);
        // strokeWeight(1+(i*(i/segments)*.01));
        strokeWeight(2);
        stroke(0,0,100,(20+i/segments));
        if(i > 0) line(points[i].x,points[i].y,points[i-1].x,points[i-1].y);
      }
    }
    function getTheodorus(segments,len){
      var result = [];
      var radius = 0;
      var angle = 0;
      for(var i = 0 ; i < segments ; i++){
        radius = sqrt(i+1);
        angle += asin(1/radius);
        result[i] = new p5.Vector(cos(angle) * radius*len,sin(angle) * radius*len);
      }
      return result;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>

    关于actionscript-3 - 解决均匀分布/均匀间隙螺旋点的算法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4349375/

    10-12 18:49