Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Importación de librerías
- import controlP5.*;
- import static javax.swing.JOptionPane.*;
- //Objetos de clase
- ControlP5 cp5;
- Knob myKnobA;
- Knob myKnobB;
- Orb orb;
- Orb orb2;
- Orb orb3;
- Orb orb4;
- Orb orb5;
- Orb orb6;
- Orb orb7;
- Orb orb8;
- Orb orb9;
- Orb orb10;
- //Enteros, floats y vectores
- PVector gravity = new PVector(0,0);
- int segments = 600;
- Ground[] ground = new Ground[segments];
- int radioModeThree = 170;
- int col = 255;
- int ncosas = 4;
- int radius = 100;
- int counter = 1;
- int sumar = 25;
- int tablade = 1;
- int prueba = 30;
- int modo = 5;
- int xa = 255;
- float sumangle = (2*PI)/ncosas;
- float angle = HALF_PI + PI + sumangle;
- float radio = 184;
- float tablaDel = 0;
- boolean overRect[] = new boolean[4];
- boolean pulsado[] = new boolean[4];
- boolean overButton = false;
- boolean overit = false;
- int x, y;
- float size = 1;
- int etapa = 0;
- int cont = 0;
- int contarmenu = 0;
- //Setup
- void setup(){
- size(400,400);
- background(204,255,255);
- textAlign(CENTER,CENTER);
- fill(0);
- stroke(0);
- textSize(7);
- cp5 = new ControlP5(this);
- //Las dos ruedas del modo 1
- myKnobA = cp5.addKnob("Servo")
- .setRange(1,120)
- .setValue(1)
- .setPosition(20,90)
- .setRadius(30)
- .setDragDirection(Knob.HORIZONTAL)
- .setCaptionLabel("Divisiones\ndel circulo")
- .setColorCaptionLabel(0)
- ;
- myKnobB = cp5.addKnob("TablaD")
- .setRange(1,20)
- .setValue(1)
- .setPosition(20,220)
- .setRadius(30)
- .setDragDirection(Knob.HORIZONTAL)
- .setCaptionLabel("Tabla de")
- .setColorCaptionLabel(0)
- ;
- //Modo 3
- PVector circle = new PVector(0,radioModeThree);
- orb = new Orb(200, 200, random(2,8));
- orb2 = new Orb(200, 200, random(2,8));
- orb3 = new Orb(200, 200, random(2,8));
- orb4 = new Orb(200, 200, random(2,8));
- orb5 = new Orb(200, 200, random(2,8));
- orb6 = new Orb(200, 200, random(2,8));
- orb7 = new Orb(200, 200, random(2,8));
- orb8 = new Orb(200, 200, random(2,8));
- orb9 = new Orb(200, 200, random(2,8));
- orb10 = new Orb(200, 200, random(2,8));
- //Creación de la forma de la esfera como objeto (modo 3)
- float[] peakHeights = new float[segments+1];
- float[] peakWidths = new float[segments+1];
- for (int i=0; i<peakHeights.length; i++){
- circle.rotate((-TWO_PI-(QUARTER_PI/4))/(peakHeights.length));
- peakWidths[i] = 200+circle.x;
- peakHeights[i] = 200+circle.y;
- }
- for (int i=0; i<segments; i++){
- ground[i] = new Ground(peakWidths[i], peakHeights[i], peakWidths[i+1], peakHeights[i+1]);
- }
- }
- //Función principal
- void draw(){
- //println("mouseX: " + mouseX + " mouseY: " + mouseY);
- for(int i = 0; i < 4; i++){
- if(pulsado[i] == true){
- modo = i+1;
- if(modo == 1){
- colorMode(RGB,255);
- background(204,255,255);
- strokeWeight(1);
- }
- if(modo == 2){
- tablaDel = 0;
- strokeWeight(1);
- }
- if(modo == 3){
- background(0);
- }
- if(modo == 4){
- rectMode(RADIUS);
- textSize(20);
- stroke(0);
- textAlign(CENTER, CENTER);
- x = 3*width/4;
- y = 3*height/4;
- }
- background(204,255,255);
- }
- }
- if(modo == 0){
- menu();
- }
- if(modo == 1){
- modo1();
- }
- if(modo == 2){
- modo2();
- textSize(9);
- fill(255);
- textAlign(CENTER,CENTER);
- text("Pulsa B en cualquier momento para regresar al menu",200,390);
- }
- if(modo == 3){
- modo3();
- textSize(9);
- text("Pulsa B en cualquier momento para regresar al menu",200,390);
- }
- if(modo == 4){
- modo4();
- textSize(9);
- text("Pulsa B en cualquier momento para regresar al menu",200,390);
- }
- if(modo == 5){
- animacion();
- }
- }
- //Reacción al presionar teclas
- void keyPressed(){
- if (key == 'D' || key == 'd'){
- Servo(int(myKnobA.getValue())+1);
- myKnobA.setValue(int(myKnobA.getValue())+1);
- }
- if (key == 'A' || key == 'a'){
- Servo(int(myKnobA.getValue())-1);
- myKnobA.setValue(int(myKnobA.getValue())-1);
- }
- if (key == 'W' || key == 'w'){
- TablaD(int(myKnobB.getValue())+1);
- myKnobB.setValue(int(myKnobB.getValue())+1);
- }
- if (key == 'S' || key == 's'){
- TablaD(int(myKnobB.getValue())-1);
- myKnobB.setValue(int(myKnobB.getValue())-1);
- }
- if(key == 'B' || key == 'b'){
- modo = 0;
- colorMode(RGB,255);
- background(204,255,255);
- strokeWeight(1);
- stroke(0);
- }
- if(key == 'i' || key == 'I'){
- modo = 5;
- size = 1;
- etapa = 0;
- cont = 0;
- contarmenu = -1;
- }
- if(key == ' ' && modo == 5){
- modo = 0;
- size = 1;
- etapa = 0;
- cont = 0;
- contarmenu = 0;
- }
- if(modo == 5) contarmenu += 1;
- }
- //Los 5 modos por separado
- void animacion(){
- myKnobA.hide();
- myKnobB.hide();
- if(etapa == 0){
- fill(204,255,255);
- noStroke();
- rect(0,0,width,height);
- stroke(0);
- textAlign(CENTER,CENTER);
- fill(0);
- textSize(9);
- text("Pulsa SPACE en cualquier momento para saltar la animación",200,390);
- textSize(size);
- text("Fractals, multiplication \ntables and light rays:\na Mandelbrot's tale",200,200);
- if(size < 30) size+=0.5;
- if(size == 30){
- etapa = 1;
- delay(4000);
- }
- }
- if(etapa == 1){
- fill(255,15);
- noStroke();
- rect(0,0,width,height);
- stroke(0);
- cont += 1;
- if(cont == 130){
- etapa = 2;
- //delay(1000);
- }
- }
- if(etapa == 2){
- fill(204,255,255);
- noStroke();
- rect(0,0,width,height);
- stroke(0);
- fill(0);
- textSize(30);
- text("¿Qué es un fractal?",width/2,50);
- textSize(10);
- text("Un fractal es un objeto geométrico cuya estructura básica,\nfragmentada o aparentemente irregular,se repite\n a diferentes escalas.\n\nEl propio término fue acuñado por\nBenoît Mandelbrot, cuyo fractal\nveremos en este programa.",width/2,170);
- textSize(12);
- text("En el caso del Conjunto de Mandelbrot,\nse define fácilmente con una fórmula:\nz(n-1) = z(n)² + C,\ndonde C es el número complejo que queremos conocer\nsi pertenece al conjunto o no.",width/2,300);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- if(contarmenu == 1){
- background(204,255,255);
- textSize(12);
- text("Existen infinitos conjuntos de Mandelbrot\ndependiendo del exponente que uses a la hora de calcularlo.\nAunque suele ser con exponente 2,\nse puede generalizar la fórmula.",width/2,height/4);
- textSize(13);
- text("Si buscas en Google podrás encontrar fácilmente\nimágenes de cualquier conjunto general\n de Mandelbrot.",width/2,250);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- }
- if(contarmenu == 2){
- etapa = 3;
- contarmenu = 0;
- delay(200);
- }
- }
- if(etapa == 3){
- fill(204,255,255);
- noStroke();
- rect(0,0,width,height);
- stroke(0);
- fill(0);
- textSize(30);
- text("¿Qué son las tablas\nde multiplicar?",width/2,100);
- textSize(13);
- text("Es broma...\nimagino que a estas las conocerás.\nPero, ¿alguna vez te has preguntado\nqué pasaría si las representáramos\ngráficamente?",width/2,230);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- if(contarmenu == 1){
- background(204,255,255);
- textSize(20);
- text("Para ello, dividiremos en varias partes\niguales un círculo como este:",width/2,60);
- noFill();
- circle(200,150,80);
- text("Por ejemplo:",width/2,230);
- circle(200,300,80);
- fill(0);
- circle(200,260,4);
- circle(200,340,4);
- circle(240,300,4);
- circle(160,300,4);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- }
- if(contarmenu == 2){
- background(204,255,255);
- textSize(12);
- text("Y luego uniremos cada punto\n con su correspondiente según\nla tabla que elijamos.",width/2,100);
- text("Por ejemplo:\nSi hiciéramos la tabla del 2 con 4 nodos\nel 1 se uniría con el 2,\nel 2 se uniría con el 4,\nel 3 con el 6\n y el 4 con el 8.\n\nAunque solo se divida en 4 nodos,\npodremos calcular dónde caerían el 6 y el 8\npor geometría.",width/2,250);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- }
- if(contarmenu == 3){
- background(204,255,255);
- textSize(13);
- text("Tranquilo si no estás entendiendo nada...\nPronto lo verás en acción y entenderás todo.",width/2,height/2);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- }
- if(contarmenu == 4){
- etapa = 4;
- contarmenu = 0;
- }
- }
- if(etapa == 4){
- fill(204,255,255);
- noStroke();
- rect(0,0,width,height);
- stroke(0);
- fill(0);
- textSize(30);
- text("Por último...\nRayos y reflexión.",width/2,80);
- textSize(13);
- text("Como tal vez conozcas si has estudiado\nalgo de física, cuando un rayo incide en\n una superficie se refleja con el mismo\nángulo con el que ha incidido\nrespecto a la normal, tal que así:",width/2,200);
- pushMatrix();
- translate(200,320);
- strokeWeight(2);
- line(-50,0,50,0);
- strokeWeight(1);
- stroke(0,0,255);
- arrow(-30,-40,0,0);
- stroke(255,0,0);
- arrow(0,0,30,-40);
- stroke(0);
- popMatrix();
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- if(contarmenu == 1){
- background(204,255,255);
- textSize(13);
- text("Pues bien, resulta sorprendente\nlo que pasa si lanzamos varios rayos\nen una superficie circular desde el centro...",width/2,200);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- }
- if(contarmenu == 2){
- background(204,255,255);
- textSize(17);
- text("Aunque parezca increíble,\nla figura que forman coincide\ncon el nodo principal\ndel conjunto de Mandelbrot!", 200,200);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- }
- if(contarmenu == 3){
- background(204,255,255);
- textSize(20);
- textAlign(CENTER,CENTER);
- text("¿Dónde está la gracia\no la relación aquí?",200, 60);
- textAlign(LEFT,CENTER);
- textSize(14);
- text("-No solo el conjunto de Mandelbrot con exponente 2\naparece en la tabla del 2, sino que TODOS\nlos conjuntos de Mandelbrot aparecen.\nEs decir, si buscas el conjunto de Mandelbrot\ncon exponente 3 y haces la tabla del 3\ncon el modo 1, verás que el módulo central coincide.\n\n-Aparecen, así, relacionados, tres\nfenómenos de ramas diferentes, como son\nlos fractales y las tablas de multiplicar (matemáticas)\ny la reflexión (óptica física).",20,230);
- textAlign(CENTER,CENTER);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- }
- if(contarmenu == 4){
- background(204,255,255);
- textSize(20);
- textAlign(CENTER,CENTER);
- text("A partir de aquí, podrás\nexperimentar por tí mismo...",200, 60);
- textAlign(LEFT,CENTER);
- textSize(14);
- text("-En el modo 1 podrás crear tus propias\ntablas de multiplicar y jugar con ellas.\n\n-En el modo 2 podrás ver cómo cambian las tablas\nen forma de animación.\n\n-En el modo 3 podrás ver, de forma colorida,\nla reflexión de rayos de luz en una superficie circular.\n\n-En el modo 4 podrás calificar el trabajo.",20,230);
- textAlign(CENTER,CENTER);
- textSize(9);
- text("(Pulsa cualquier tecla para continuar)",width/2,390);
- }
- if(contarmenu == 5){
- modo = 0;
- }
- }
- //println(etapa);
- }
- void menu(){
- colorMode(RGB);
- myKnobA.hide();
- myKnobB.hide();
- background(204,255,255);
- fill(0);
- boton(width/4+30,height/2-30,45,0);
- boton(3*width/4-30,height/2-30,45,3);
- boton(width/4+30,3*height/4,45,1);
- boton(3*width/4-30,3*height/4,45,2);
- textAlign(CENTER,CENTER);
- fill(0);
- textSize(12);
- text("Pulsa 'i' para volver a ver el tutorial",201,391);
- fill(0, 102, 204);
- text("Pulsa 'i' para volver a ver el tutorial",200,390);
- textSize(35);
- fill(0);
- text("Selecciona un modo:",201,51);
- fill(0, 102, 204);
- text("Selecciona un modo:",200,50);
- }
- void boton(float x, float y, float radius, int index){
- rectMode(RADIUS);
- fill(0);
- square(x+3,y+3,radius);
- if(mouseX > x-45 && mouseX < x+45 && mouseY < y + 45 && mouseY > y-45){
- overRect[index] = true;
- fill(0,128,255);
- }
- else{
- overRect[index] = false;
- fill(51, 102, 255);
- }
- if (pulsado[index] == true){
- noFill();
- noStroke();
- }
- square(x,y,radius);
- fill(0);
- textSize(16);
- text("Modo\n"+ (index+1),x,y);
- }
- void mousePressed(){
- if(modo == 0){
- for(int i = 0; i < 4; i++){
- if(overRect[i]) pulsado[i] = true;
- }
- }
- if(modo == 4) if(overButton == true) showMessageDialog(null, "Sabía que dirías que sí :D", "Info", INFORMATION_MESSAGE);
- }
- void mouseReleased(){
- for(int i = 0; i < 4; i++){
- pulsado[i] = false;
- }
- }
- void modo1(){
- myKnobA.show();
- myKnobB.show();
- textSize(7);
- //colorMode(RGB,0);
- stroke(0);
- if(counter <= ncosas){
- dibujarTabla();
- }
- textSize(10);
- text("Usa WASD para controlar las ruedas sin usar el ratón",200,20);
- textSize(9);
- strokeWeight(1);
- fill(0);
- text("Pulsa B en cualquier momento para regresar al menu",200,390);
- }
- void modo2(){
- myKnobA.hide();
- myKnobB.hide();
- colorMode(HSB, 360, 100, 100);
- textAlign(CENTER, CENTER);
- textSize(17);
- background(0);
- fill(255);
- text("Tabla del\n" + nfc(tablaDel,2),45,40);
- xa--;
- if(xa==0)xa=360;
- //println(xa);
- int total = int(map(mouseX,0, width, 0, 200));
- tablaDel += 0.008;
- pushMatrix();
- translate(width/2, height/2);
- stroke(xa, 255, 255);
- noFill();
- circle(0,0,radio*2);
- for(int i = 0; i < total; i++){
- PVector v = crearVector(i,total);
- fill(255);
- circle(v.x, v.y, 8);
- }
- for(int i = 0; i < total; i++){
- PVector a = crearVector(i,total);
- PVector b = crearVector(i * tablaDel,total);
- line(a.x,a.y,b.x,b.y);
- }
- popMatrix();
- }
- void modo3(){
- myKnobA.hide();
- myKnobB.hide();
- ////println("mousex: "+mouseX+" mousey: "+mouseY);
- noStroke();
- fill(0, 15);
- rect(0, 0, width, height);
- for (int i=0; i<segments; i++){
- orb.checkGroundCollision(ground[i]);
- orb2.checkGroundCollision(ground[i]);
- orb3.checkGroundCollision(ground[i]);
- orb4.checkGroundCollision(ground[i]);
- orb5.checkGroundCollision(ground[i]);
- orb6.checkGroundCollision(ground[i]);
- orb7.checkGroundCollision(ground[i]);
- orb8.checkGroundCollision(ground[i]);
- orb9.checkGroundCollision(ground[i]);
- orb10.checkGroundCollision(ground[i]);
- }
- beginShape();
- for (int i=0; i<segments; i++){
- vertex(ground[i].x1, ground[i].y1);
- vertex(ground[i].x2, ground[i].y2);
- }
- vertex(ground[segments-1].x2, height);
- vertex(ground[0].x1, height);
- endShape(CLOSE);
- orb.move();
- orb.display();
- orb2.move();
- orb2.display();
- orb3.move();
- orb3.display();
- orb4.move();
- orb4.display();
- orb5.move();
- orb5.display();
- orb6.move();
- orb6.display();
- orb7.move();
- orb7.display();
- orb8.move();
- orb8.display();
- orb9.move();
- orb9.display();
- orb10.move();
- orb10.display();
- stroke(200);
- noFill();
- strokeWeight(7);
- circle(width/2,height/2,radioModeThree*2);
- }
- void modo4(){
- background(255);
- //println(mouseY);
- textSize(20);
- //isitover(mouseX,mouseY);
- if(mouseX > x-90 && mouseX < x+90 && mouseY > y-20 && mouseY < y+20){
- do{
- x = int(random(110,width-110));
- y = int(random(210,height-20));
- isitover(x,y);
- }while(overit == true);
- ////println("x: " + x + " y: " + y);
- }
- boton(x,y,"No");
- boton(width/4,3*height/4,"Si");
- }
- void boton(int posx, int posy, String texto){
- fill(255);
- if(mouseX > posx-90 && mouseX < posx+90 && mouseY > posy-20 && mouseY < posy+20){
- stroke(0,0,255);
- overButton = true;
- }
- else{
- overButton = false;
- stroke(0);
- }
- rect(posx,posy,90,20);
- fill(0);
- text(texto,posx,posy);
- textSize(40);
- text("¿Pondrías un 10\na este trabajo?",width/2,120);
- textSize(20);
- }
- //Funciones utilizadas a lo largo de los modos (subordinadas)
- void isitover(int x, int y){
- //rect(x,y,90,20);
- if((x-89 > (width/4)-90 && x-89 < (width/4)+90 && y-19 > (3*height/4)-20 && y-19 < (3*height/4)+20)||(x+89 > (width/4)-90 && x+89 < (width/4)+90 && y-19 > (3*height/4)-20 && y-19 < (3*height/4)+20)||(x+89 > (width/4)-90 && x+89 < (width/4)+90 && y+19 > (3*height/4)-20 && y+19 < (3*height/4)+20)||(x-89 > (width/4)-90 && x-89 < (width/4)+90 && y+19 > (3*height/4)-20 && y+19 < (3*height/4)+20)){
- overit = true;
- }
- else overit = false;
- //println(overit);
- }
- PVector crearVector(float indice, float total){ //Para dividir un círculo en partes iguales (modo 1)
- float angle = map(indice % total, 0, total, 0, TWO_PI);
- PVector v = PVector.fromAngle(angle + PI);
- v.mult(radio);
- return v;
- }
- void Servo(int theValue){ //Rueda del número de divisiones (modo 1)
- background(204,255,255);
- fill(0);
- counter = 1;
- ncosas = theValue;
- sumangle = (2*PI)/ncosas;
- angle = HALF_PI + PI + sumangle;
- }
- void TablaD(int theValue){ //Rueda de la tabla de multiplicar (modo 1)
- background(204,255,255);
- fill(0);
- counter = 1;
- tablade = theValue;
- angle = HALF_PI + PI + sumangle;
- }
- void dibujarTabla(){ //Dibuja la tabla paso a paso
- pushMatrix();
- translate(1.1*width/2,height/2);
- circle(radius*sin(angle),radius*cos(angle),2);
- //if(counter*tablade<=ncosas){
- line(radius*sin(angle),radius*cos(angle),radius*sin((counter*tablade*sumangle)+(angle-counter*sumangle)),radius*cos((counter*tablade*sumangle)+(angle-counter*sumangle)));
- //}
- //println(counter*tablade + " -> " + counter*tablade*degrees(sumangle));
- text(counter,(radius+sumar)*sin(angle),(radius+sumar)*cos(angle));
- angle += sumangle;
- counter++;
- popMatrix();
- }
- void arrow(float x1, float y1, float x2, float y2) {
- line(x1, y1, x2, y2);
- pushMatrix();
- translate(x2, y2);
- float a = atan2(x1-x2, y2-y1);
- rotate(a);
- line(0, 0, -3, -3);
- line(0, 0, 3, -3);
- popMatrix();
- }
- //Clases
- class Orb {
- PVector position;
- PVector velocity;
- float r;
- Orb(float x, float y, float r_) {
- position = new PVector(x, y);
- velocity = new PVector(random(1,5), random(1,5));
- velocity.rotate(random(0,TWO_PI));
- r = r_;
- }
- void move() {
- velocity.add(gravity);
- position.add(velocity);
- if(position.x < 25 || position.x > 375){
- position.set(width/2,height/2);
- velocity.rotate(random(0,TWO_PI));
- }
- }
- void display() {
- colorMode(HSB, 360, 100, 100);
- col--;
- if(col==0)col=360;
- noStroke();
- fill(col,255,255);
- ellipse(position.x, position.y, r*2, r*2);
- colorMode(RGB,255);
- }
- void checkGroundCollision(Ground groundSegment) {
- float deltaX = position.x - groundSegment.x;
- float deltaY = position.y - groundSegment.y;
- float cosine = cos(groundSegment.rot);
- float sine = sin(groundSegment.rot);
- float groundXTemp = cosine * deltaX + sine * deltaY;
- float groundYTemp = cosine * deltaY - sine * deltaX;
- float velocityXTemp = cosine * velocity.x + sine * velocity.y;
- float velocityYTemp = cosine * velocity.y - sine * velocity.x;
- if (groundYTemp > -r && position.x >= groundSegment.x1 && position.x <= groundSegment.x2 ) {
- groundYTemp = -r;
- velocityYTemp *= -1.0;
- }
- if (groundYTemp > -r && position.x <= groundSegment.x1 && position.x >= groundSegment.x2 ) {
- groundYTemp = -r;
- velocityYTemp *= -1.0;
- }
- deltaX = cosine * groundXTemp - sine * groundYTemp;
- deltaY = cosine * groundYTemp + sine * groundXTemp;
- velocity.x = cosine * velocityXTemp - sine * velocityYTemp;
- velocity.y = cosine * velocityYTemp + sine * velocityXTemp;
- position.x = groundSegment.x + deltaX;
- position.y = groundSegment.y + deltaY;
- }
- }
- class Ground {
- float x1, y1, x2, y2;
- float x, y, len, rot;
- Ground(float x1, float y1, float x2, float y2) {
- this.x1 = x1;
- this.y1 = y1;
- this.x2 = x2;
- this.y2 = y2;
- x = (x1+x2)/2;
- y = (y1+y2)/2;
- len = dist(x1, y1, x2, y2);
- rot = atan2((y2-y1), (x2-x1));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement