根据距中心点的距离计算椭圆大小
Calculate ellipse size in relation to distance from center point
我想在每次坍塌时实现尺寸的缓慢淡化。换句话说,当圆最大时,椭圆最大,反之则收缩。到目前为止,我试图通过从中心点的距离重新映射 cSize 来实现这种影响,但在某些地方出现了问题。目前,我的椭圆大小正在从小到大缓慢过渡,但内部椭圆明显更大。我希望所有椭圆的大小相对于中心点距离均匀分布。
我已将代码简化为 4 个省略号,而不是一排省略号,希望能简化此示例。这是在 for (int x = -50; x <= 50; x+=100).
中完成的
我见过一两个示例,它们稍微符合我的要求,但或多或少是静态的。这个例子有点相似,因为椭圆的大小相对于鼠标位置变小或变大
这是我要创建的椭圆网格的附加图表,此外,我试图通过中心点缩放 "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);
}
}
在此示例中尝试单击或拖动。使用这种方法,用户交互对我来说更有意义,但是您选择哪个选项实际上取决于最适合您的想法。
我想在每次坍塌时实现尺寸的缓慢淡化。换句话说,当圆最大时,椭圆最大,反之则收缩。到目前为止,我试图通过从中心点的距离重新映射 cSize 来实现这种影响,但在某些地方出现了问题。目前,我的椭圆大小正在从小到大缓慢过渡,但内部椭圆明显更大。我希望所有椭圆的大小相对于中心点距离均匀分布。
我已将代码简化为 4 个省略号,而不是一排省略号,希望能简化此示例。这是在 for (int x = -50; x <= 50; x+=100).
中完成的我见过一两个示例,它们稍微符合我的要求,但或多或少是静态的。这个例子有点相似,因为椭圆的大小相对于鼠标位置变小或变大
这是我要创建的椭圆网格的附加图表,此外,我试图通过中心点缩放 "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);
}
}
在此示例中尝试单击或拖动。使用这种方法,用户交互对我来说更有意义,但是您选择哪个选项实际上取决于最适合您的想法。