简体   繁体   中英

Understanding How a Circle is Formed in Processing

import ddf.minim.*;

Minim minim;
AudioPlayer player;
PImage img;

void setup() {
  size(728, 546);

  minim = new Minim(this);

  player = minim.loadFile("Bassnectar_-_Magical_World_feat.wav");
  player.play();
  img= loadImage("cat-in-shades-.jpg");
}

void draw() {


  image(img, 0, 0);
  tint(0, 100, 150);
  stroke(255);

  strokeWeight(4);
  float a = 0;

  float angle = (2*PI) / 200;


  for(int i=0; i < player.bufferSize() - 1; i++) {

   //player.mix.get(i) is a value between [-1,1]

    float x = 250 + cos(a) * (20 * player.mix.get(i) + 100);
    float x2 = 540 + cos(a) * (20 * player.mix.get(i) + 100);    

    float y = 230 + sin(a) * (20 * player.mix.get(i) + 100);
    float y2 = 240 + sin(a) * (20 * player.mix.get(i) + 100);


    float xFinal = 250 + cos(a+angle) * (20 * player.mix.get(i+1) + 100);
    float x2Final = 540 + cos(a+angle) * (20 * player.mix.get(i+1) + 100);


    float yFinal = 230 + sin(a+angle) * (20 * player.mix.get(i+1) + 100);    
    float y2Final = 240 + sin(a+angle) * (20 * player.mix.get(i+1) + 100);    


    line(x,y,xFinal,yFinal);
    line(x2,y2,x2Final,y2Final);

    a += angle;

  }

}

void stop() {
  player.close();
  minim.stop();

  super.stop();
}

The following code above is for creating an audio visualizer in Processing with the Minim library. For some reason I'm struggling to see how a circle is formed within the the code's for loop. In general I'm also trying to break down the code and get a deeper understanding for what is going on. I am confused about the following: 'float x = 250 + cos(a) * (20 * player.mix.get(i) + 100);' Is the 20 times and plus 100 used to scale up the sample? If so then why does the circle visualizer not display when I get rid of the 20 times and just have plus 20000? Is the 250 used for placement of the start point of the line on the x-axis within the background image? Lastly, why is the variable 'angle' needed? When I take it out I notice the visualizer is not as smooth as there looks to be a division between the quadrants.
I have been playing around with this code, and can't find too many examples with detailed explanations so any help would be appreciated. Thank you.

The first thing you need to do is understand basic trigonometry better. There are a ton of resources out there: try googling "sin cos tutorial" or "sin and cos for game development" or "sohcahtoa" for a bunch of results.

But basically, if you have a start point, a rotation, and a distance, you can figure out where the end point is using sin and cos . The basic formula for calculating an end point is this:

endX = startX + cos(rotation)*distance;
endY = startY + sin(rotation)*distance;

Your code is using this formula to find points around a circle so that it can draw lines between them to draw the circle. Each line section of the circle is 2 of the end points.

The angle variable is used to specify how far apart those points are. The smaller you make it, the more "circle-y" it will look. The larger you make it, the more you'll be able to see the straight lines that make up the circle.

It might be easier to work with a simpler example:

void setup(){
  size(500, 500);
}

void draw(){
  background(0);

  //draw white
  stroke(255);

  //the start point- try changing this to mouseX and mouseY
  float centerX = width/2;
  float centerY = height/2;

  //the distance from the start point
  float radius = 100;

  //how far apart the points are
  float angleIncrement = 30;

  //loop to go around the circle. Try changing it to 180 to see what happens.
  for(float angleInDegrees = 0; angleInDegrees <= 360; angleInDegrees+=angleIncrement){

    //the first "end point" is the start point of the line
    float startX = centerX + cos(radians(angleInDegrees))*radius;
    float startY = centerY + sin(radians(angleInDegrees))*radius;

    //the second "end point" is the end point of the line
    //notice that we're adding the angleIncrement to the angle to get the next point
    float endX = centerX + cos(radians(angleInDegrees+angleIncrement))*radius;
    float endY = centerY + sin(radians(angleInDegrees+angleIncrement))*radius;

    //draw the line
    line(startX, startY, endX, endY);

  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM