Anterior

Procedimiento numérico

Raíces de una ecuación trascendente

Calcular la raíz de la ecuación trascendente

3 2 ( ϕ L R )=tan( ϕ 2 )

en el intervalo el ángulo π<φ<2π

public class Funcion extends Ecuacion{
    double L;
    final double R=1.0;
    public Funcion(double longitud){
      this.L=longitud;
    }
    public double f(double x){
        double y=3*(L/R-x)/2+Math.tan(x/2);
        return y;
    }
}

Ecuación diferencial de segundo orden

Resolver la ecuación diferencial de segundo orden

d 2 ϕ d t 2 = R (LRϕ) ( g R cosϕ+ ( dϕ dt ) 2 )

por procedimientos numéricos con las siguientes condiciones iniciales: en el instante t=0, φ=0, dφ/dt=0.

public class Estado {
    double t;
    double x;
    double v;
    public Estado(double t, double x, double v) {
        this.t=t;
        this.x=x;
        this.v=v;
    }
}
public abstract class RungeKutta {
    double h;
    RungeKutta(double h){
      this.h=h;
    }
    public void resolver(Estado e)throws NumeroInfinito{
//variables auxiliares
	    double k1=0.0, k2=0.0, k3=0.0, k4=0.0;
	    double l1=0.0, l2=0.0, l3=0.0, l4=0.0;
//condiciones iniciales
	    double x=e.x;
	    double v=e.v;
	    double t=e.t;
   try{
		    k1=h*v;
		    l1=h*f(x, v, t);

		    k2=h*(v+l1/2);
		    l2=h*f(x+k1/2, v+l1/2, t+h/2);

		    k3=h*(v+l2/2);
		    l3=h*f(x+k2/2, v+l2/2, t+h/2);

		    k4=h*(v+l3);
		    l4=h*f(x+k3, v+l3, t+h);
    }catch(NumeroInfinito ex){
          throw ex;
    }

//nuevo estado del sistema
		    x+=(k1+2*k2+2*k3+k4)/6;
		    v+=(l1+2*l2+2*l3+l4)/6;
	  
//cambia el estado de la partícula
	    e.x=x;
	    e.v=v;
	    e.t=t+h;
    }
    abstract public double f(double x, double v, double t) throws NumeroInfinito;
}
public class Sistema extends RungeKutta{
    double L;
    final double R=1.0;
    public Sistema(double longitud, double h){
      super(h);
      this.L=longitud;
    }
    public double f(double x, double v, double t) throws NumeroInfinito{
         if((L-R*x)<0.001) throw new NumeroInfinito("Número muy grande");
         double y=(9.8*Math.cos(x)/R+v*v)*R/(L-R*x);
         return y;
    }

}

class NumeroInfinito extends Exception {
  public NumeroInfinito(String s) {
         super(s);
  }
}
public class MiCanvas extends Canvas {
     final double R=1.0;
     double L=6.0;
     double xCM=L, yCM=-R;
     double t;
     final double dt=0.005;
     Polygon pol=new Polygon();
     double x0, y0, v0x, v0y;
     double angLimite;
     int tipo=1;
//objetos
   Estado estado=new Estado(0.0, 0.0, 0.0);
   Sistema sistema=null;
   Funcion f;
   //...
 void setNuevo(double longitud){
     this.L=longitud;
     estado=new Estado(0.0, 0.0, 0.0);
     sistema=new Sistema(longitud, dt);
     xCM=L;
     yCM=-R;
     angLimite=2*Math.PI;
     f=new Funcion(longitud);
     try{
              angLimite=f.puntoMedio(Math.PI+0.1, 2*Math.PI);
     }catch(Exception e){
            System.out.println(e.getMessage());
     }
     t=0.0;
     tipo=1;
 }

 void mover(){
      switch (tipo){
          case 1:
            try{
                sistema.resolver(estado);
            }catch(Exception ex){
                //se detiene el movimiento de la la partícula
                tipo=3;
                return;
            }
          double r=Math.sqrt((L-R*estado.x)*(L-R*estado.x)+R*R);
            double angulo=Math.atan2(((L-R*estado.x)*Math.sin(estado.x)-
R*Math.cos(estado.x)), ((L-R*estado.x)*Math.cos(estado.x)+R*Math.sin(estado.x))); xCM=r*Math.cos(angulo); yCM=-r*Math.sin(angulo); if(estado.x>=angLimite){ v0x=-(L-R*estado.x)*estado.v*Math.sin(estado.x); v0y=-(L-R*estado.x)*estado.v*Math.cos(estado.x); x0=xCM; y0=yCM; //tiro parabólico tipo=2; t=0.0; } break; case 2: xCM=x0+v0x*t; yCM=y0+v0y*t-4.9*t*t; if(yCM<-10) //se detiene el movimiento de la partícula; t+=dt; break; default: break; } repaint(); }

Al resolver la ecuación diferencial el denominador (L-) se hace cero cuando la cuerda se enrolla completamente. La aceleración d2φ/dt2 tiende a infinito. Cuando esto ocurre la función f de la clase derivada Sistema lanza (throw) una excepción. La función resolver miembro de la clase base RungeKutta llama repetidamente a la función f. Estas llamadas se han de colocar dentro de un bloque try... catch. Cuando se produce la excepción el bloque catch la captura y vuelve la lanzarla (throw) hacia la clase MiCanvas, cuya función miembro mover llama a resolver. La llamada a esta función se ha de poner en el interior de un bloque try...catch. En el bloque catch se detiene el movimiento de la partícula que queda pegada al cilindro cuando la cuerda se enrolla completamente.

Anterior