Applet que plotea la función de onda:



import java.awt.*;
import java.awt.event.*;
import java.applet.*;

class DibujaNivel extends Canvas{

  int puntos;
  double[] zona;
  double energiaNivel;
  int[] pts;
  double energiaPozo;
  //la x en el dibujo ira desde -xMax hasta x Max(distribucion de la pantalla:20-60-20)
  double xMax;
  double step;
  int n;

  public void establecerNivel(int nivel, double energin,double V0,double anchuraPozo){
    double kNivel;
    n=nivel;
    energiaNivel=energin;           //es negativa
    kNivel=Math.sqrt(2*(energiaNivel+V0));
    energiaPozo=V0;                 // la tomo positiva
    xMax=anchuraPozo*5.0/6.0;
    step=xMax/250.0;
    puntos = 501;
    zona= new double [501];
    double rho=Math.sqrt(-energiaNivel*2);

    pts = new int [501];
    double factor;
      if (Math.pow(-1,n+1)==1){
        factor=Math.exp(-anchuraPozo*rho/2.0)/Math.cos(-anchuraPozo*kNivel/2.0);
      }
      else{
        factor=Math.exp(-anchuraPozo*rho/2.0)/Math.sin(anchuraPozo*kNivel/2.0);
      }

    // las funciones las hago un poco a lo bruto, pues las voy a reescalar
    //despues en función de la altura del applet.
    // zona1: exponencial real con signo positivo
      for (int i=0; i < 100; i++) {
        double xreal=-xMax+i*step;
        zona[i]=Math.pow(-1,n+1)*Math.exp(rho*xreal);
      }
    // zona2: coseno para pares(n impar) seno para impares
      for (int i=100; i < 401; i++) {
        double xreal=-xMax+i*step;
        if (Math.pow(-1,n+1)==1){
          zona[i]=factor*Math.cos(kNivel*xreal);
        }
        else{
          zona[i]=factor*Math.sin(kNivel*xreal);
        }
      }
    //zona3: exponencial real con signo negativo
      for (int i=401; i < 501; i++) {
        double xreal=-xMax+i*step;
        zona[i]=Math.exp(-rho*xreal);
      }

    repaint();

  }

  public void paint(Graphics g){
       Dimension d=size();
       int anchuraMax =  d.width;

       int alturaMax = d.height;

       //traslado el origen
       g.translate((int)(anchuraMax*0.5),(int)(alturaMax*0.2));

       //dibujo pozo en negro
       g.setColor(Color.black);

       //lineas horizontales(3)
       g.drawLine(-(int)(anchuraMax*0.5),0,-(int)(anchuraMax*.3),0);
       g.drawLine((int)(anchuraMax*.3),0,(int)(anchuraMax*0.5),0);
       g.drawLine(-(int)(anchuraMax*0.3),(int)(0.6*alturaMax),(int)(anchuraMax*0.3),(int)(alturaMax*0.6));

       //lineas verticales(2)
       g.drawLine(-(int)(anchuraMax*0.3),0,-(int)(anchuraMax*0.3),(int)(0.6*alturaMax));
       g.drawLine((int)(anchuraMax*0.3),0,(int)(anchuraMax*0.3),(int)(0.6*alturaMax));

       if(n>0){
       //Ahora dibujamos el nivel en Verde
       g.setColor(Color.green);
       // la altura del nivel es:
       int altura= (int)((-1.0*energiaNivel/energiaPozo)*alturaMax*0.6);
       // linea horizontal que cruza el applet y que sevirá para dibujar sobre ella la función
       //de onda:
       g.drawLine(-(int)(anchuraMax*0.5),altura,(int)(anchuraMax*0.5),altura);
       //dibujamos la función. para que no se salga del applet vemos su maximo:
       double alturaMaximaOnda=0.0;
       for(int i=101; i < 401; i++){
         alturaMaximaOnda=Math.max(alturaMaximaOnda,Math.abs(zona[i]));
       }
       //Para ver si el peligro esta para arriba o por abajo minimizo las dos alturas;
       int distancia;

       if(n==1){
         distancia=altura;//en el primer nivel solo tendremos peligro por arriba
       }
       else{
         distancia=Math.min(altura,(int)(alturaMax*0.6-altura));
       }
      //para dibujar tengo esta distancia y el 20% de la pantalla que no es ocupado por el pozo
      //ahora hacemos lo más importante pasar de algo general a dibujar en la pantalla
       //diciendole a cada punto del plano energia-distancia donde se tiene que ir a la pantalla
       for(int i = 0; i < puntos; i++){
         pts[i] = (int)(-(zona[i]/alturaMaximaOnda) * (alturaMax*0.2+distancia)*.9 + altura);
       //cambio de signo pues el tonto que hizo Java no se le ocurrio otra cosa
         //que poner el eje Y hacia abajo ¡que más da que el resto del planeta
         //lo ponga para arriba?
       }
       g.setColor(Color.blue);
       double paso=anchuraMax/500.0;
       //una vez que hemos pasado de la funcion real a pixel solo queda dibujar
       for(int i=1; i <puntos;i++){
         int x1 = (int)((i-1)*paso-anchuraMax/2.0);
         int x2 = (int)(i*paso-anchuraMax/2.0);
         int y1 = pts[i-1];
         int y2 = pts[i];
         g.drawLine(x1,y1,x2,y2);

       }
  }
  }
}
// ahora viene el applet que es lo mas facil.


public class DibujaNivel2 extends Applet {
// construimos un canvas de estos para pintar;
  DibujaNivel nivelDibujado= new DibujaNivel();
//añadimos etiquetas y campos de texto para tomar y mostrar datos
  TextField V0Text = new TextField(5);
  Label V0Label = new Label("V0");
  TextField a = new TextField(5);
  Label aLabel = new Label ("eV.    Ancho del pozo");
  TextField niveles = new TextField(5);
  Label nivelesLabel = new Label ("A.   Niveles");
  Label nivelBuscar = new Label ("El nivel ");
  TextField nivel = new TextField(5);
  Label knivelLabel = new Label(" tiene una energia:");
  Label unidad= new Label("eV");
  TextField nivelBuscado = new TextField(15);
// definimos estas vaiables aqui pues van a ser necesarias en muchos de los metodos
  double k0,V0,anchuraPozo;

  public void init(){
  //para colocar todo en los lugares cardinales de la pantalla se da la siguiente orden:
    setLayout(new BorderLayout());
  //ordenamos por paneles y lo colocamos todo bonico;
    Panel datoPanel=new Panel();
    Panel resultados = new Panel();
    Button dibu= new Button("Dibuja");
    add("Center",nivelDibujado);
    datoPanel.add(V0Label);
    datoPanel.add(V0Text);
    datoPanel.add(aLabel);
    datoPanel.add(a);
    datoPanel.add(nivelesLabel);
    datoPanel.add(niveles);
    resultados.add(nivelBuscar);
    resultados.add(nivel);
    resultados.add(knivelLabel);
    resultados.add(nivelBuscado);
    resultados.add(unidad);
    resultados.add(dibu);
    add("North",datoPanel);
    add("South",resultados);
  // inicializamos con unos parametros para que el java no me de problemas con excepciones
    //el poder de Java se vuelve contra el ignorante
    V0Text.setText("10");
    a.setText("6");
    niveles.setText("4");
    nivel.setText("1");
 //dibujamos el pozo solamente de principio, para ello nos llevamos todo fuera de pantalla menos el pozo
    nivelDibujado.establecerNivel(-1,-1000.0,100.0,1.0);
  }
//ahora veamos el motor
  public boolean action(Event e, Object o){
    //el unico evento posible es que alguien pulse intro en un campo de texto pero me da igual los parametros
    //hago cosas y cuando me harto devuelvo true y el applet se queda reposando;

    //cojo V0 de su panel
//    V0=Double.parseDouble(V0Text.getText());
    int EnteroV0 = Integer.parseInt(V0Text.getText());
    V0=EnteroV0/27.2;
    //calculo k0 que falta me hace
    k0=Math.sqrt(2*V0);
    //hago lo mismo con la anchura:
//    anchuraPozo=Double.parseDouble(a.getText());
    int EnteroAnc = Integer.parseInt(a.getText());
    anchuraPozo=EnteroAnc/.52917;
    //calculamos el numero de niveles
    int numeroNiveles = 1+ (int)(k0*anchuraPozo/Math.PI);
    // se lo decimos al que esta jugando para que no de mucho el follon;
    niveles.setText(String.valueOf(numeroNiveles));

    //tomamos el nivel a buscar
    int n=Integer.parseInt(nivel.getText());
    //vemos que es valido
    if (n > 0 && n < (numeroNiveles+1)){
      //nos aprovechamos que sabemos donde va a estar mas o menos y por el metodo de la bisección
      //todo funciona bien mas o menos
      double kredNivel = buscanivel(1.0*(n-1),1.0*n);
      double energiaNivelUa=Math.pow(kredNivel*Math.PI/anchuraPozo,2)/2-V0;
      double energiaNivel=energiaNivelUa*27.2;
      //esceribimos el resultado para calmar la curiosidad del navegante
      nivelBuscado.setText(String.valueOf(energiaNivel));
      // y por fin aprovechamos la potencia de la clase de arriba con el metodo establecerNivel
      nivelDibujado.establecerNivel(n,energiaNivelUa,V0,anchuraPozo);

    }
    //para que haga lo que debe reconducimos al navegador
    else{ nivelBuscado.setText("cabrito!!!");}
    //ya nos casamos de hacer cosas y por tanto para que se este quieto:
    return true;
  }

// parte sencilla como en culaquier otro lenguaje
  public int factorial(int n){
    if (n==1) return 1;
    else return n*factorial(n-1);

  }

//método que busca la energía del nivel por bisección:
  public double buscanivel(double left, double right){
//tomo este error yo para no ser demasiado quisquilloso
     if (Math.abs(right-left)<0.001){ return ((right+left)/2.0);}
//utilizo recursividad
      if ((f(right)*f((right+left)/2.0))<0){
        return buscanivel(((right+left)/2.0),right);}
      else{
        return buscanivel(left,((right+left)/2.0));}
  }
//este metodo es la funcion de la que quiero calcular los ceros
  public double f(double kred){
    double a=anchuraPozo;
    double kreal=Math.PI*kred/a;
    if (Math.tan(kreal*a/2.0)>0){
      return Math.abs(Math.cos(kreal*a/2.0))-kreal/k0;
    }
    else{
      return Math.abs(Math.sin(kreal*a/2.0))-kreal/k0;
    }

  }

}










Alojado en Hosting :: LMI