计算与中心点距离相关的椭圆大小 [英] Calculate ellipse size in relation to distance from center point

查看:51
本文介绍了计算与中心点距离相关的椭圆大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在每次折叠时实现缓慢的大小淡入.换句话说,当圆最大时,椭圆的大小将最大,反之,回缩则相反.到目前为止,我试图通过从中心点的距离重新映射 cSize 来实现这种影响,但是在此过程中的某个地方出了问题.目前,我的椭圆大小正在从小到大缓慢过渡,但内部椭圆明显更大.我希望所有椭圆之间的大小分布与中心点距离相等.

I want to achieve a slow fade in size on every collapse into itself. In other words, when the circle is at its biggest, the ellipses will be at the largest in size and conversely the opposite for the retraction. So far I am trying to achieve this affect by remapping the cSize from the distance of the center point, but somewhere along the way something is going wrong. At the moment I am getting a slow transition from small to large in ellipse size, but the inner ellipses are noticeably larger. I want an equal distribution of size amongst all ellipses in relation to center point distance.

我已将代码简化为 4 个椭圆,而不是一排椭圆行,以期简化此示例.这是在 for (int x = -50; x <= 50; x+=100) 中完成的.

I've simplified the code down to 4 ellipses rather than an array of rows of ellipses in order to hopefully simplify this example. This is done in the for (int x = -50; x <= 50; x+=100).

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

I've seen one or two examples that slightly does what I want, but is more or less static. This example is kind of similar because the ellipse size gets smaller or larger in relation to the mouse position

Distance2D

这是我正在尝试创建的椭圆网格的附加图,此外,我正在尝试按中心点缩放椭圆的方形网格".

Here is an additional diagram of the grid of ellipses I am trying to create, In addition, I am trying to scale that "square grid" of ellipses by a center point.

多个椭圆 + 按中心缩放

有什么指点吗?

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() 函数的值对我来说没有多大意义:

The values you're passing into the map() function don't make a lot of sense to me:

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

cSize 变量从 1 跳到 10 独立于其他任何东西.d 变量是每个椭圆到圆心的距离,但是对于每个椭圆来说都是静态的,因为您使用的是 rotate() 函数来移动"从未实际移动的圆.这仅基于 frameCount 变量,您从不使用它来计算椭圆的大小.

The cSize variable bounces from 1 to 10 independent of anything else. The d variable is the distance of each ellipse to the center of the circle, but that's going to be static for each one since you're using the rotate() function to "move" the circle, which never actually moves. That's based only on the frameCount variable, which you never use to calculate the size of your ellipses.

换句话说,椭圆的位置和它们的大小在您的代码中完全无关.

In other words, the position of the ellipses and their size are completely unrelated in your code.

您需要重构您的代码,以便大小基于距离.我看到这样做的两个主要选项:

You need to refactor your code so that the size is based on the distance. I see two main options for doing this:

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

Option 1: Right now you're moving the circles on screen using the translate() and rotate() functions. You could think of this as the camera moving, not the ellipses moving. So if you want to base the size of the ellipse on its distance from some point, you have to get the distance of the transformed point, not the original point.

幸运的是,Processing 为您提供了 screenX()screenY() 函数,用于确定一个点在变换后的位置.

Luckily, Processing gives you the screenX() and screenY() functions for figuring out where a point will be after you transform it.

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

Here's an example of how you might use it:

  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(),直接使用省略号的位置.

Option 2: Stop using translate() and rotate(), and use the positions of the ellipses directly.

您可以创建一个类来封装移动和绘制椭圆所需的所有内容.然后只需创建该类的实例并迭代它们.您需要一些基本的触发器来确定位置,但您可以直接使用它们.

You might create a class that encapsulates everything you need to move and draw an ellipse. Then just create instances of that class and iterate over them. You'd need some basic trig to figure out the positions, but you could then use them directly.

这是这样做的一个小例子:

Here's a little example of doing it that way:

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);
  }
}

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

Try clicking or dragging in this example. User interaction makes more sense to me using this approach, but which option you choose really depends on what fits inside your head the best.

这篇关于计算与中心点距离相关的椭圆大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆