Processing:Примеры/Эллипсы-пружины

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Описание[1]

Зажмите кнопкой мыши на каком-либо эллипсе, потяните его в сторону и отпустите. Когда вы отпустите мышку, эллипс начнет быстро двигаться к своей исходной позиции. Каждый эллипс ведет себя немного по-разному.

Пример

int num = 3; 
Spring[] springs = new Spring[num]; 

void setup() {
  size(640, 360);
  noStroke(); 
  springs[0] = new Spring(240, 260, 40, 0.98, 8.0, 0.1, springs, 0); 
  springs[1] = new Spring(320, 210, 120, 0.95, 9.0, 0.1, springs, 1); 
  springs[2] = new Spring(180, 170, 200, 0.90, 9.9, 0.1, springs, 2);
}

void draw() {
  background(51); 

  for (Spring spring : springs) { 
    spring.update(); 
    spring.display();
  }
}

void mousePressed() {
  for (Spring spring : springs) { 
    spring.pressed();
  }
}

void mouseReleased() {
  for (Spring spring : springs) { 
    spring.released();
  }
}

class Spring { 
  // значения экрана: 
  float xpos, ypos;
  float tempxpos, tempypos; 
  int size = 20; 
  boolean over = false; 
  boolean move = false; 

  // константы для симуляции пружины:
  float mass;       // масса 
  float k = 0.2;    // константа пружины 
  float damp;       // затухание
  float rest_posx;  // позиция покоя X 
  float rest_posy;  // позиция покоя Y 

  // переменные симуляции пружины:
  //float pos = 20.0; // позиция 
  float velx = 0.0;   // скорость по оси X
  float vely = 0.0;   // скорость по оси Y 
  float accel = 0;    // ускорение 
  float force = 0;    // сила 

  Spring[] friends;
  int me;

  // конструктор:
  Spring(float x, float y, int s, float d, float m, 
  float k_in, Spring[] others, int id) { 
    xpos = tempxpos = x; 
    ypos = tempypos = y;
    rest_posx = x;
    rest_posy = y;
    size = s;
    damp = d; 
    mass = m; 
    k = k_in;
    friends = others;
    me = id;
  } 

  void update() { 
    if (move) { 
      rest_posy = mouseY; 
      rest_posx = mouseX;
    } 

    force = -k * (tempypos - rest_posy);  // f=-ky 
    accel = force / mass;                 // задаем ускорение,
                                          // f=ma == a=f/m 
    vely = damp * (vely + accel);         // задаем скорость 
    tempypos = tempypos + vely;           // обновляем позицию 

    force = -k * (tempxpos - rest_posx);  // f=-ky 
    accel = force / mass;                 // задаем ускорение,
                                          // f=ma == a=f/m 
    velx = damp * (velx + accel);         // задаем скорость 
    tempxpos = tempxpos + velx;           // обновляем позицию 


    if ((overEvent() || move) && !otherOver() ) { 
      over = true;
    } else { 
      over = false;
    }
  } 

  // проверяем, находится ли курсор над этим эллипсом:
  boolean overEvent() {
    float disX = tempxpos - mouseX;
    float disY = tempypos - mouseY;
    if (sqrt(sq(disX) + sq(disY)) < size/2 ) {
      return true;
    } else {
      return false;
    }
  }

  // делаем так, чтобы не был активен никакой другой эллипс:
  boolean otherOver() {
    for (int i=0; i<num; i++) {
      if (i != me) {
        if (friends[i].over == true) {
          return true;
        }
      }
    }
    return false;
  }

  void display() { 
    if (over) { 
      fill(153);
    } else { 
      fill(255);
    } 
    ellipse(tempxpos, tempypos, size, size);
  } 

  void pressed() { 
    if (over) { 
      move = true;
    } else { 
      move = false;
    }
  } 

  void released() { 
    move = false; 
    rest_posx = xpos;
    rest_posy = ypos;
  }
}

См.также

Внешние ссылки