Колеблющиеся значения

Я делаю некоторые эксперименты в обработке, и мне часто нужно int или float, который колеблется между двумя значениями, например, идет от 0 до 255 и затем возвращается к 0, увеличивая на 1 значение за раз. Я обычно пишу какой-то логический метод переключения, чтобы сделать это, но мне было интересно, есть ли более простой способ сделать это?

Мол, есть ли способ, где вы можете:

oscillate(0, 255, 1);

что делает то, что я описал выше?

3 ответа

Решение

Если вам нужен конкретный контроль над тем, как ваши колебания выполняются и рассчитываются, тогда ничто не сравнится с написанием ваших собственных функций. Но если вы ищете что-то встроенное, то проверьте sin() функция, которая является реализацией математической функции синуса. На самом деле, даже в своих собственных функциях я использую sin а также cos функции, предоставляемые процессингом. Просто поиграйте со значениями, на которые вы умножаете выходные данные функции, поскольку она колеблется между -1 и 1. Умножение ее на определенное число даст вам то, что вы хотите. И затем приведение его к int получит целочисленные значения

Примером этого sin() Функцию в действии можно увидеть здесь. Код со страницы воспроизводится здесь для справки:

// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com

// Example 13-6: Oscillation

float theta = 0.0;

void setup() {
  size(200,200);
  smooth();
}


void draw() {
  background(255);

  // The output of the sin() function oscillates smoothly between -1 and 1. 
  // By adding 1 we get values between 0 and 2. 
  // By multiplying by 100, we get values between 0 and 200 which can be used as the ellipse's x location.
  float x = (sin(theta) + 1) * width/2; 

  // We can also use Processing's "map()" function to achieve the same results
  // http://processing.org/reference/map_.html
  // float x = map(sin(theta),-1,1,0,width);

  // With each cycle, increment theta
  theta += 0.05;

  // Draw the ellipse at the value produced by sine
  fill(0);
  stroke(0);
  line(width/2,0,x,height/2);
  ellipse(x,height/2,16,16);
}

Мне нравятся волны... Это треугольная волна, я думаю...

Попробуй это:

int x;
void setup(){
  frameRate(6);
}

void draw(){

  println(sawWave (x, 4));
x++;
}

int sawWave(int value, int max){

 return (abs(abs( value% (max*2) - max) - max));
}

и вот еще несколько волн, которые вы можете использовать. Нажмите на эскиз, чтобы перейти к следующему...

PGraphics [] pg = new PGraphics[4];
int w_dim = 1000;
PFont font;
ArrayList<PVector> points = new ArrayList<PVector>();
float[] f;
float x, res = 1;
String expression = "";
int expr = 0;
float valInput;

void setup() {
  // golden ratio :P
  size(w_dim, int(w_dim/1.6180));
  smooth();
  background(255);

  pg[0] = createGraphics(width, height, JAVA2D);

  font = loadFont("STHeitiSC-Medium-48.vlw");

  //draw graph lines
  pg[0].beginDraw();
  pg[0].stroke(240);
  pg[0].line(0, height/2, width, height/2);
  pg[0].line(0, height/2 - 112, width, height/2 - 112);
  pg[0].line(0, height/2 + 112, width, height/2 + 112);
  pg[0].endDraw();
}

void draw() {
  frame.setTitle(nf(frameRate, 2, 2));

  /*XXXXXX*/

  background(255);

  x +=res;
  float xR = radians(x); 


  switch (expr) {

  case 0:
    valInput = sin(xR);
    expression = "y = sin(x)";
    break;

  case 1:
    valInput = sin(tan(xR)*pow(sin(xR), 10));
    expression = "y = sin(tan(x)*sin(x)ˆ10";
    break;

  case 2:
    valInput = pow(sin(xR*PI), 12);
    expression = "y = (sin(x*PI))ˆ12";
    break;

  case 3:
    valInput   = cos(sin(xR*3)+xR*3);
    expression = "cos(sin(x*3)+x*3";
    break;

  case 4:
    valInput   = x%100/100;
    expression = "(x%100/100)";
    break;

  case 5:
    valInput   = sin(tan(cos(xR)*1.2));
    expression = "sin(tan(cos(x)*1.2";
    break;

  case 6:
    valInput   = cos(xR)*sin(xR);
    expression = "cos(x)*sin(x)";
    break;

  case 7:
    valInput   = sin(xR)*sin(xR*1.5);
    expression = "cos(x)*sin(x*1.5)";
    break;

  case 8:
    valInput   = sin(tan(xR)*0.05);
    expression = "sin(tan(x)*0.05";
    break;

  case 9:
    valInput   = cos(sin(xR*3))*sin(xR*0.2);
    expression = "cos(sin(x*3))*sin(x*2)";
    break;

  case 10:
    valInput   = sin(pow(8, sin(xR)));
    expression = "sin(8ˆsin(x))";
    break;

  case 11:
    valInput   = sin(exp(cos(xR*0.8))*2);
    expression = "sin(eˆcos(x*0.8)*2";
    break;

  case 12:
    valInput   = sin(xR-PI*tan(xR)*0.01);
    expression = "sin(x-PI*tan(x)*0.01";
    break;

  case 13:
    valInput   = pow(sin(xR*PI), 12);
    expression = "sin(x*PI)ˆ12";
    break;

  case 14:
    valInput   = cos(sin(xR)*tan(xR*PI)*PI/8);
    expression = "cos(sin(x)*tan(x*PI)*PI/8";
    break;

  case 15:
    valInput   = cos(sin(xR*3)+xR*3);
    expression = "cos(sin(x*3))+x*3";
    break;

  case 16:
    valInput   = pow(abs(sin(xR*2))*0.6, sin(xR*2))*0.5;
    expression = "|(sin(x*2)*0.6)ˆsin(x*2)*0.5|";
    break;

  case 17:
    valInput   = abs(xR % (2) - 1);
    expression = "|x%2-1|";
    break;

  case 18:
    valInput   = sin(xR)*tan(xR)*0.1;
    expression = "sin(x)*tan(x)*0.1";
    break;

  case 19:
    valInput   = sin(tan(xR)); 
    expression = "sin(tan(x))";
    break;

  case 20:
    valInput   = (cos(xR) * sin(xR*30) )* 0.3;
    expression = "(cos(x) * sin(x*30))*0.3";
    break;

  case 21:
    valInput   = cos(xR*(xR*0.5));
    expression = "cos(x*(x*0.5))";
    break;

  case 22:
    valInput   = cos(xR) * (tan(xR*0.5)*0.1);
    expression = "cos(x)* tan(x*0.5)*0.1";
    break;

  case 23:
    valInput   = sqrt(abs(sin(xR))); 
    expression = "squareRoot(|sin(x)|)";
    break;

  case 24:
    valInput   = sqrt(abs(sin(xR)*sin(xR*2))); 
    expression = "squareRoot(|sin(x)*sin(x*2)|)";
    break;

  case 25:
    valInput   = sqrt(abs(sin(xR)*sin(xR*10)));  
    expression = "squareRoot(|sin(x)*sin(x*10)|)";
    break;

  case 26:
    valInput   = tan(sin(xR)*cos(xR*3)); 
    expression = "tan(sin(x)*cox(x)";
    break;
  case 27:
    valInput   = sin(tan(cos(xR)));
    expression = "sin(tan(cos(x))";
    break;
  }

  //float value = 
  // float value = 
  //float value = 
  //float value = 
  //float value 
  //float value 


  //println (value);

  //drawExpression(0, 0, width, height, value, "");
  image(pg[0], 0, 0);
  drawExpression(0, 0, width, height, valInput, x, expression);
}




void mouseReleased() {

  //background(255);
  pg[0].beginDraw();
  pg[0].background(255);
  pg[0].stroke(240);
  pg[0].strokeWeight(1);
  pg[0].line(0, height/2, width, height/2);
  pg[0].line(0, height/2 - 112, width, height/2 - 112);
  pg[0].line(0, height/2 + 112, width, height/2 + 112);
  pg[0].endDraw();
  x=0;
  expr= (expr+1)%29;
  println (expr);
}




void drawExpression (float _x, float y, float w, float h, float value_y, float value_x, String _expression)
{
  float v_center = h/2;
  float h_center = w/2;


  float pos_x = _x + value_x;
  float pos_y = (v_center + (-value_y * h/5));
  // points.add(new PVector(pos_x, pos_y));

  for (PVector p:points) {
    //point(p.x, p.y);
  }

  //draw wave
  pg[0].beginDraw();
  pg[0].stroke(0);
  pg[0].strokeWeight(2);

  pg[0].point(pos_x, pos_y);
  pg[0].endDraw();


  //erase this area 
  float v_size  = v_center - v_center/2;
  noStroke();
  fill(255, 0, 0);
  rect( _x, _x, w, v_size);



  float el_x = h_center + (-value_y * w/4);
  float el_y = v_size / 2;

  float c = map (value_y, -1, 1, 255, 0);
  float s = map (value_y, -1, 1, 2, 80);

  //draw pulse ellipse;
  fill(c);
  noStroke();
  fill(240);
  ellipse( w/2, el_y, s, s);


  //draw horizontal ellipse
  stroke(150, 200);
  strokeWeight(10);
  noFill();
  ellipse( el_x, el_y, 40, 40);

  // write value
  textFont(font, 20);
  fill(100);
  String st_y  = nfs(value_y, 3, 4);
  text("y = ", h_center - textWidth("y =")-200, 438);
  text(st_y, h_center - 200, 438);

  String st_x  = nfs( value_x, 3, 4);

  float line2_x1 =  h_center - textWidth("x = ") + 200 - textWidth(st_x) ;

  fill(100);
  text("x = ", line2_x1, 438);
  text(st_x, h_center + 200 - textWidth(st_x), 438);

  float line_x1 = line2_x1;

  float line_y = 438;
  float line2_y = 438;
  float line_x2 = h_center - textWidth("y =")-200;



  strokeWeight(0.5);
  stroke(220);

  line(line2_x1, line2_y, pos_x, pos_y);

  line(pos_x, 169, pos_x, 390);
  line(0, pos_y, width, pos_y);

  line(line_x2, line_y, pos_x, pos_y);

  stroke(200);
  line(line_x1, line_y, line_x1 + textWidth("x =" + st_x) + 4, line_y);
  line(h_center - textWidth("y =") - 200, line2_y, h_center - 200 + textWidth( st_y), line2_y);


  stroke(80);
  strokeWeight(6);
  point(pos_x, pos_y);

  //write expression
  textSize(25);
  fill(200);
  noStroke();
  text(_expression, width/2 - textWidth(_expression)/2, height - 10);
}

Простейший способ осциллирования переменной - использование библиотеки анимации для анимации. Это просто определить время и значение END анимации для конкретной переменной:

aniA = new Ani(this, 1.5, "x", 255);

Если вы хотите вернуться с 255 на 0, просто установите режим на "Ani.YOYO" и установите "repeat":

aniA.setPlayMode(Ani.YOYO);
aniA.repeat();

Таким образом, все колебания будут выглядеть так:

import de.looksgood.ani.*;

Ani aniA;
float y = 0;

void setup() {
  size(200,200);
  smooth();
  Ani.init(this);  
  aniA = new Ani(this, 1.5, "y", 200, Ani.QUAD_IN_OUT);
  aniA.setPlayMode(Ani.YOYO);
  aniA.repeat();
}

void draw() {
  background(255);
  fill(0);
  stroke(0);

  line(width/2,0,y,height/2);
  ellipse(y,height/2,16,16);
}

Вы также можете указать различные варианты смягчения для анимации здесь

Другие вопросы по тегам