首页 > 解决方案 > 在处理中使用 Java 绘制螺旋

问题描述

我有一个用我制作的 Processing 编写的 Java 程序,它在处理过程中画了一个螺旋,但我不确定某些代码行是如何工作的。我根据教程编写了它们。我在我不理解的行中添加了大写字母的注释。小写的注释是我理解的行。如果您了解这些行的工作原理,请用非常简单的术语解释!太感谢了。

void setup()
  {
    size(500,500);
    frameRate(15);
  }

  void draw()
  { 
    background(0); //fills background with black
    noStroke(); //gets rid of stroke

    int circlenumber = 999;// determines how many circles will be drawn 
    float radius = 5; //radius of each small circle
    float area = (radius) * (radius) * PI; //area of each small circle
    float total = 0; //total areas of circles already drawn
    float offset = frameCount * 0.01; //HOW DOES IT WORK & WHAT DOES IT DO

    for (int i = 1; i <= circlenumber; ++i) { // loops through all of the circles making up the pattern

      float angle = i*19 + offset; //HOW DOES IT WORK & WHAT DOES IT DO
      total += area; // adds up the areas of all the small circles that have already been drawn
      float amplitude = sqrt( total / PI ); //amplitude of trigonometric spiral
      float x = width/2 + cos(angle) * amplitude;//HOW DOES IT WORK & WHAT DOES IT DO

      float hue = i;//determines circle color based on circle number
      fill(hue, 44, 255);//fills circle with that color

      ellipse(x, 1*i, radius*2, radius*2); //draws circle
    }
  }

标签: javaprocessingdrawtrigonometry

解决方案


本质上,这是在做一个幅度变化的垂直余弦曲线。这是与程序正在执行的操作类似的链接。https://www.desmos.com/calculator/p9lwmvknkh

以下是按顺序对这些不同部分的解释。我将从我提供的链接中引用一些变量:

float offset = frameCount * 0.01

这样做是确定余弦曲线动画的速度。这是来自desmos的“a”值。为了让程序运行,每个椭圆必须在余弦函数中每帧改变一点点,以便它移动。frameCount是一个变量,用于存储动画/草图已运行的当前帧数,并且每帧都会上升,类似于动画的 a 值。

for (int i = 1; i <= circlenumber; ++i) {
      float angle = i*19 + offset;

这在这里负责确定当前椭圆应该离顶部多远,并通过拉伸因子进行修改。它每次都在增加,因此每个椭圆在余弦曲线上稍微更远一些。这相当于来自 desmos 的 5(y+a)。y 值是 i,因为它是因变量。之所以如此,是因为对于每个椭圆,我们需要确定它距顶部的距离以及距中心的距离。由于上述原因,偏移量是 a 值。

float x = width/2 + cos(angle) * amplitude

这将计算椭圆距屏幕中心的距离(x 中心,y 值由每个椭圆确定它是哪个椭圆)。width/2 只是简单地围绕中心线移动所有椭圆。如果您在 Desmos 上注意到,中心线是 y 轴。因为在处理中,如果某些东西离开屏幕(低于 0 或高于width),我们实际上看不到它,教程说要抵消它,所以整个事情都会显示出来。cos(angle)*amplitude 本质上是 Desmos 上的整个函数。cos(angle) 是余弦部分,而幅度是之前的东西。这可以被视为本质上只是因变量的缩放版本。在desmos上,我正在做的是sqrt(-y+4)教程基本上做了sqrt(25*i). 每一帧,总(面积)重置为 0。每次我们画一个圆,我们将它增加 pi * r^2(圆的面积)。这就是因变量 (i) 出现的地方。如果您注意到,他们会这样写float amplitude = sqrt( total / PI );,因此该区域的 pi 被抵消了。

要记住的一件事是圆圈实际上并没有向下移动,这完全是一种错觉。为了证明这一点,这里有一些修改后的代码,可以画线。如果你沿着这条线跟踪一个圆圈,你会注意到它实际上并没有向下移动。

void setup()
  {
    size(500,500);
    frameRate(15);
  }

  void draw()
  { 
    background(0); //fills background with black
    noStroke(); //gets rid of stroke

    int circlenumber = 999;// determines how many circles will be drawn 
    float radius = 5; //radius of each small circle
    float area = (radius) * (radius) * PI; //area of each small circle
    float total = 0; //total areas of circles already drawn
    float offset = frameCount * 0.01; //HOW DOES IT WORK & WHAT DOES IT DO

    for (int i = 1; i <= circlenumber; ++i) { // loops through all of the circles making up the pattern

      float angle = i*19 + offset; //HOW DOES IT WORK & WHAT DOES IT DO
      total += area; // adds up the areas of all the small circles that have already been drawn
      float amplitude = sqrt( total / PI ); //amplitude of trigonometric spiral
      float x = width/2 + cos(angle) * amplitude;//HOW DOES IT WORK & WHAT DOES IT DO

      float hue = i;//determines circle color based on circle number
      fill(hue, 44, 255);//fills circle with that color

      stroke(hue,44,255);
      if(i%30 == 0)
          line(0,i,width,i);

      ellipse(x, i, radius*2, radius*2); //draws circle
    }
  }

希望这有助于澄清一些理解问题。


推荐阅读