Как сделать так, чтобы размер эллипса автоматически становился все меньше и меньше при обработке
Я создаю что-то, используя классы, чтобы привыкнуть к ним, и я пытаюсь получить размер эллипса, который я нарисовал, чтобы он становился все меньше и меньше, чтобы он выглядел более интерактивным, однако я не знаю, что код для реализации.
Я показал код, который я использую ниже;
void setup()
{
size(640, 480);
}
void draw()
{
background(255);
for (int i = height-50; i > 0; i-= 20)
{
fill(random(255), random(255), random(255));
ellipse(width/2, height/2, i, i);
}
}
2 ответа
Просто чтобы добавить к отличному ответу Кевина, вот несколько вариантов одной и той же идеи (отслеживание, увеличивается ли размер или нет).
Первый подход предполагает использование переменной скорости роста, которая просто переворачивает знак при достижении предела. Если размер слишком мал (нижний предел) или слишком велик (верхний предел), изменение знака (умножение скорости роста на -1) изменит рост на уменьшение и наоборот:
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 1.5;
void setup()
{
size(640, 480);
}
void draw()
{
//if the size is either too small, or too big, flip the size speed sign (if it was positive (growing) - make it negative (shrink) - and vice versa)
if(size < minSize || size > maxSize) {
sizeSpeed *= -1;
}
//increment the size with the size speed (be it positive or negative)
size += sizeSpeed;
background(255);
fill(random(255), random(255), random(255));
ellipse(width/2, height/2, size,size);
}
Обратите внимание, что движение довольно линейное. Поскольку вы хотите увеличивать и уменьшать круг с течением времени, вы можете получить более плавную анимацию, используя функцию sin(). Он принимает угол в качестве аргумента и на основе значения угла возвращает значение от -1,0 до 1,0. Вы можете использовать функцию map(), чтобы переназначить этот диапазон до желаемого размера эллипса:
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
void setup()
{
size(640, 480);
}
void draw()
{
size = map(sin(frameCount * sizeSpeed),-1.0,1.0,minSize,maxSize);
background(255);
fill(random(255), random(255), random(255));
ellipse(width/2, height/2, size,size);
}
Обновление В терминах классов вы можете начать инкапсуляцию переменных, используемых для рисования эллипса в классе. Синтаксис не так сложен:
- Использовать
class
ключевое слово, затем имя класса (верхний регистр по соглашению) и добавление членов класса в{}
- область применения классов - Создайте экземпляр класса, используя
new
ключевое слово и использование.
запись для доступа к членам экземпляра
Вот действительно простой пример, использующий выше:
Ellipse e = new Ellipse();
void setup()
{
size(640, 480);
}
void draw()
{
e.size = map(sin(frameCount * e.sizeSpeed),-1.0,1.0,e.minSize,e.maxSize);
background(255);
fill(random(255), random(255), random(255));
ellipse(width/2, height/2, e.size,e.size);
}
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
}
Это хорошее и простое начало, но часть для рисования не инкапсулирована. Так же, как вы объявляете и используете переменные в классе, вы можете объявлять и использовать функции. Вот основной пример простого перемещения функции рисования эллипса в функцию:
Ellipse e = new Ellipse();
void setup()
{
size(640, 480);
}
void draw()
{
background(255);
e.render();
}
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
void render(){
size = map(sin(frameCount * sizeSpeed),-1.0,1.0,minSize,maxSize);
fill(random(255), random(255), random(255));
ellipse(width/2, height/2, size,size);
}
}
Как вы заметили, теперь требуется 2 строки для инициализации и рендеринга эллипса из основного эскиза. Есть еще вещи, которые можно улучшить. Если создается второй эллипс, x и y одинаковы, поэтому они затеняют друг друга. Добавление свойств x,y к классу будет означать, что каждый экземпляр будет иметь независимые координаты. На аналогичной ноте, frameCount
является глобальным, что означает, что каждый эллипс использует один и тот же угол / размер. Мы также можем сделать это независимым.
Ellipse e1 = new Ellipse(320,240);
Ellipse e2 = new Ellipse(20,20);
void setup()
{
size(640, 480);
}
void draw()
{
background(255);
e1.render();
e2.render();
}
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
//position
float x,y;
//internal frameCount replacement
int tick;
//constructor
Ellipse(float x,float y){
this.x = x;//copy x argument value to the instance (this) x property
this.y = y;//copy x argument value to the instance (this) x property
}
void render(){
tick++;
size = map(sin(tick * sizeSpeed),-1.0,1.0,minSize,maxSize);
fill(random(255), random(255), random(255));
ellipse(x,y, size,size);
}
}
Обратите внимание, мы также добавили конструктор. Конструктор очень особенный: он как точка входа в новый экземпляр. Всякий раз, когда вы создаете новый экземпляр класса, вызывается конструктор, который обычно инициализирует данные. В предыдущем примере явно не определялся конструктор, но Processing предоставляет один без аргументов по умолчанию. Чтобы продвинуть вышеупомянутые концепции на шаг вперед, мы создадим конструктор с координатами x,y:
Ellipse e1 = new Ellipse(320,240);
Ellipse e2 = new Ellipse(20,20);
void setup()
{
size(640, 480);
}
void draw()
{
background(255);
e1.render();
e2.render();
}
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
//position
float x,y;
//internal frameCount replacement
int tick;
//constructor
Ellipse(float x,float y){
this.x = x;//copy x argument value to the instance (this) x property
this.y = y;//copy x argument value to the instance (this) x property
}
void render(){
tick++;
size = map(sin(tick * sizeSpeed),-1.0,1.0,minSize,maxSize);
fill(random(255), random(255), random(255));
ellipse(x,y, size,size);
}
}
Это очень быстрый обзор. Для получения более подробной информации обязательно ознакомьтесь с руководством по объектам Дэниела Шиффмана.
Имея это в виду, вы можете использовать ArrayList для создания новых эллипсов во время выполнения и иметь несколько забавных рандомизированных параметров эллипса:
ArrayList<Ellipse> ellipses = new ArrayList<Ellipse>();
void setup()
{
size(640, 480);
ellipses.add(new Ellipse(width / 2, height / 2));
}
void draw()
{
background(255);
for(Ellipse e : ellipses){
e.render();
}
}
//add an ellipse every 5th frame if mouse is dragged
void mouseDragged(){
if(frameCount % 5 == 0) ellipses.add(new Ellipse(mouseX,mouseY));
}
//remove all ellipses if SPACE is pressed
void keyPressed(){
if(key == ' ') ellipses.clear();
}
//ellipse class
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
//position
float x,y;
//internal frameCount replacement
int tick;
int fill;
//constructor
Ellipse(float x,float y){
this.x = x;//copy x argument value to the instance (this) x property
this.y = y;//copy x argument value to the instance (this) x property
fill = color(random(32,192));
sizeSpeed = random(0.025,0.01);
maxSize = random(120,240);
}
void render(){
tick++;
size = map(sin(tick * sizeSpeed),-1.0,1.0,minSize,maxSize);
fill(fill);
ellipse(x,y, size,size);
}
}
Вам просто нужно сохранить ширину и высоту вашего круга в переменной, используйте эту переменную в draw()
функции, а затем измените его, когда вы хотите изменить размер круга.
Вот пример программы, которая меняет размер круга при щелчке мышью:
float radius = 50;
void setup(){
size(500, 500);
ellipseMode(RADIUS);
}
void mouseClicked(){
radius = 250.0*mouseX/width;
}
void draw(){
background(0);
ellipse(width/2, height/2, radius, radius);
}
Вот пример программы, которая автоматически увеличивает и уменьшает круг:
float radius = 0;
boolean grow = true;
void setup() {
size(500, 500);
ellipseMode(RADIUS);
}
void draw() {
if (grow) {
radius++;
if (radius == 250) {
grow = false;
}
} else {
radius--;
if (radius == 0) {
grow = true;
}
}
background(0);
ellipse(width/2, height/2, radius, radius);
}
Но идея в обоих примерах одинакова: просто сохраните радиус окружности в переменной, измените эту переменную, чтобы изменить размер, и используйте эту переменную, чтобы нарисовать круг.