根据距中心点的距离计算椭圆大小

Calculate ellipse size in relation to distance from center point

我想在每次坍塌时实现尺寸的缓慢淡化。换句话说,当圆最大时,椭圆最大,反之则收缩。到目前为止,我试图通过从中心点的距离重新映射 cSize 来实现这种影响,但在某些地方出现了问题。目前,我的椭圆大小正在从小到大缓慢过渡,但内部椭圆明显更大。我希望所有椭圆的大小相对于中心点距离均匀分布。

我已将代码简化为 4 个省略号,而不是一排省略号,希望能简化此示例。这是在 for (int x = -50; x <= 50; x+=100).

中完成的

我见过一两个示例,它们稍微符合我的要求,但或多或​​少是静态的。这个例子有点相似,因为椭圆的大小相对于鼠标位置变小或变大

Distance2D

这是我要创建的椭圆网格的附加图表,此外,我试图通过中心点缩放 "square grid" 的椭圆。

Multiple ellipses + Scale by center

有什么指点吗?

float cSize;
float shrinkOrGrow;

void setup() {
    size(640, 640);
    noStroke();
    smooth();
    fill(255);
}

void draw() {
    background(#202020);
    translate(width/2, height/2);

    if (cSize > 10) {
      shrinkOrGrow = 0;
    } else if (cSize < 1 ) {
      shrinkOrGrow = 1;
}

    if (shrinkOrGrow == 1) {
      cSize += .1;
    } else if (shrinkOrGrow == 0) {
      cSize -= .1;
}
    for (int x = -50; x <= 50; x+=100) {
    for (int y = -50; y <= 50; y+=100) {
    float d = dist(x, y, 0, 0);    
    float fromCenter = map(cSize, 0, d, 1, 10);

  pushMatrix();
  translate(x, y);
  rotate(radians(d + frameCount));
  ellipse(x, y, fromCenter, fromCenter);
  popMatrix();
}
}
}

您传递给 map() 函数的值对我来说意义不大:

float fromCenter = map(cSize, 0, d, 1, 100);

cSize 变量从 1 反弹到 10,与其他任何因素无关。 d 变量是每个椭圆到圆心的距离,但是每个椭圆都将是静态的,因为您使用的是 rotate()作用于 "move" 圆圈,它实际上从未移动过。这仅基于 frameCount 变量,您永远不会用它来计算椭圆的大小。

换句话说,省略号的位置和它们的大小在您的代码中是完全不相关的。

您需要重构代码,使大小基于距离。我看到执行此操作的两个主要选项:

选项 1: 现在您正在使用 translate()rotate() 函数在屏幕上移动圆圈。您可以将其视为相机移动,而不是椭圆移动。所以如果你想根据椭圆到某个点的距离来确定椭圆的大小,你必须得到变换点的距离,而不是原始点的距离。

幸运的是,Processing 为您提供了 screenX()screenY() 函数,用于计算变换后点的位置。

这是您可以如何使用它的示例:

  for (int x = -50; x <= 50; x+=100) {
    for (int y = -50; y <= 50; y+=100) {
      pushMatrix();

      //transform the point
      //in other words, move the camera
      translate(x, y);
      rotate(radians(frameCount));

      //get the position of the transformed point on the screen
      float screenX = screenX(x, y);
      float screenY = screenY(x, y);

      //get the distance of that position from the center
      float distanceFromCenter = dist(screenX, screenY, width/2, height/2);

      //use that distance to create a diameter
      float diameter = 141 - distanceFromCenter;

      //draw the ellipse using that diameter
      ellipse(x, y, diameter, diameter);
      popMatrix();
    }
  }

选项2:停止使用translate()rotate(),直接使用省略号的位置。

您可以创建一个 class 来封装您需要移动和绘制椭圆的所有内容。然后只需创建 class 的实例并迭代它们。你需要一些基本的三角函数来计算位置,但你可以直接使用它们。

这里有一个这样做的小例子:

ArrayList<RotatingEllipse> ellipses = new ArrayList<RotatingEllipse>();

void setup() {
  size(500, 500);
  ellipses.add(new RotatingEllipse(width*.25, height*.25));
  ellipses.add(new RotatingEllipse(width*.75, height*.25));
  ellipses.add(new RotatingEllipse(width*.75, height*.75));
  ellipses.add(new RotatingEllipse(width*.25, height*.75));
}

void draw() {
  background(0);

  for (RotatingEllipse e : ellipses) {
    e.stepAndDraw();
  }
}

void mouseClicked() {
  ellipses.add(new RotatingEllipse(mouseX, mouseY));
}

void mouseDragged() {
  ellipses.add(new RotatingEllipse(mouseX, mouseY));
}

class RotatingEllipse {

  float rotateAroundX;
  float rotateAroundY;
  float distanceFromRotatingPoint;
  float angle;

  public RotatingEllipse(float startX, float startY) {

    rotateAroundX = (width/2 + startX)/2;
    rotateAroundY = (height/2 + startY)/2;

    distanceFromRotatingPoint = dist(startX, startY, rotateAroundX, rotateAroundY);

    angle = atan2(startY-height/2, startX-width/2);
  }

  public void stepAndDraw() {

    angle += PI/64;

    float x = rotateAroundX + cos(angle)*distanceFromRotatingPoint;
    float y = rotateAroundY + sin(angle)*distanceFromRotatingPoint;

    float distance = dist(x, y, width/2, height/2);
    float diameter = 50*(500-distance)/500;

    ellipse(x, y, diameter, diameter);
  }
}

在此示例中尝试单击或拖动。使用这种方法,用户交互对我来说更有意义,但是您选择哪个选项实际上取决于最适合您的想法。