import java.awt.Graphics; import java.awt.Color; import java.awt.Point; import java.awt.Rectangle; import Punto; import Muelle; import Malla; public class Sistema { private Punto[] ptos = null; private Muelle[] muelles = null; private Malla malla = null; private int fil = -1; private int col = -1; private double h,h2,h3,h6; private boolean autoZoom = false; private boolean verPuntos = true; private boolean verMuelles = true; private boolean estela = false; private int ptoSel = -1; private int ptoOsc = -1; public Sistema( ) { malla = new Malla(Malla.CUADRADA); h = 0.05; h2 = h/2.0; h3 = h/3.0; h6 = h/6.0; } public void setDimensiones( int tipo, int fil, int col ) { this.fil = fil; this.col = col; malla.setTipo(tipo); // Inicializacion de las posiciones ajusteInicial(); // Creacion del vector de puntos ptos = new Punto[ malla.numPuntos(fil,col) ]; for( int i = 0; i < ptos.length; i++ ) { ptos[i] = new Punto( malla.getPosPunto(i,fil,col) ); } // Establecer el rango de la pantalla ajusteAutomatico(); // Creacion del vector de muelles creaMuelles(); } public void creaMuelles( ) { muelles = new Muelle[ malla.numConexiones(fil,col) ]; int ip = 0; int im = 0; for( ; ip < ptos.length; ip++ ) { int[] vecinos = malla.getVecPunto(ip,fil,col); for( int j = 0; j < vecinos.length; j++, im++ ) { muelles[im] = new Muelle(ptos[ip],ptos[vecinos[j]]); } } } public void reiniciar( ) { for( int i = 0; i < ptos.length; i++ ) ptos[i].reiniciar(); } public void ajusteInicial( ) { Punto.minX = +1e100; Punto.maxX = -1e100; Punto.minY = +1e100; Punto.maxY = -1e100; } public void ajusteAutomatico( ) { double lx = Punto.maxX - Punto.minX; double ly = Punto.maxY - Punto.minY; double mx = (lx < 1e-6) ? 0.5 : 0.1*lx; double my = (ly < 1e-6) ? 0.5 : 0.1*ly; Punto.panX0 = Punto.minX - mx; Punto.panY0 = Punto.minY - my; Punto.paniLx = 1.0/(lx+2*mx); Punto.paniLy = 1.0/(ly+2*my); } public void setIncTpo( double dt ) { h = dt; h2 = h/2.0; h3 = h/3.0; h6 = h/6.0; } public void setCoefRec( double k ) { for( int i = 0; i < muelles.length; i++ ) muelles[i].setCoef(k); } public void setAmortig( double gamma ) { for( int i = 0; i < muelles.length; i++ ) muelles[i].setAmortig(gamma); } public void setPropsDibujo( boolean autoZoom, boolean verPuntos, boolean verMuelles, boolean estela ) { this.autoZoom = autoZoom; this.verPuntos = verPuntos; this.verMuelles = verMuelles; this.estela = estela; } public void calculaFuerzas( ) { for( int i = 0; i < muelles.length; i++ ) muelles[i].fuerzas(); } public synchronized void preparaIntegracion( ) { if( ptos == null ) return; for(int i = 0; i < ptos.length; i++) ptos[i].rungeKuttaPreparacion(); } public synchronized void integrar( ) { if( ptos == null ) return; int i; // Metodo Runge-Kutta for(i = 0; i < ptos.length; i++) ptos[i].rungeKuttaInic(); calculaFuerzas(); for(i = 0; i < ptos.length; i++) ptos[i].rungeKuttaIter(h6,h2); calculaFuerzas(); for(i = 0; i < ptos.length; i++) ptos[i].rungeKuttaIter(h3,h2); calculaFuerzas(); for(i = 0; i < ptos.length; i++) ptos[i].rungeKuttaIter(h3,h); calculaFuerzas(); for(i = 0; i < ptos.length; i++) ptos[i].rungeKuttaFinal(h6); } public void dibujar( Graphics g, int lx, int ly ) { if( ptos == null ) return; if( autoZoom ) ajusteAutomatico(); if( !estela ) { g.setColor(Color.white); g.fillRect(0,0,lx,ly); } for( int i = 0; i < ptos.length; i++ ) ptos[i].calculaPosicion(lx,ly); if( verMuelles ) for( int i = 0; i < muelles.length; i++ ) muelles[i].dibujar(g); if( verPuntos ) for( int i = 0; i < ptos.length; i++ ) ptos[i].dibujar(g,i == ptoSel); } public void dibujarVelocidad( Graphics g, int lx, int ly ) { if( ptos == null ) return; g.setColor(Color.white); g.fillRect(0,0,lx,ly); for( int i = 0; i < ptos.length; i++ ) ptos[i].calculaPosicion(lx,ly); for( int i = 0; i < ptos.length; i++ ) ptos[i].calculaPosVel(lx,ly); for( int i = 0; i < ptos.length; i++ ) ptos[i].dibujar(g,i == ptoSel); for( int i = 0; i < ptos.length; i++ ) ptos[i].dibujarVeloc(g); } public void dibujarMasa( Graphics g, int lx, int ly ) { if( ptos == null ) return; g.setColor(Color.white); g.fillRect(0,0,lx,ly); for( int i = 0; i < ptos.length; i++ ) ptos[i].calculaPosicion(lx,ly); for( int i = 0; i < ptos.length; i++ ) ptos[i].dibujar(g,i == ptoSel); for( int i = 0; i < ptos.length; i++ ) { double r = Math.log(ptos[i].masa)/Math.log(10.0); if(r<0) r = 1.0/(1.0-r); else r = r+1.0; int l = (int) Math.round(r*lx/6.0); g.setColor( ((i==ptoSel) ? Color.magenta : Color.lightGray) ); g.drawOval(ptos[i].panX-l,ptos[i].panY-l,2*l,2*l); } } public void dibujarConexiones( Graphics g, int lx, int ly ) { malla.dibujar(g,lx,ly); } public void pulsacionConexiones( Point pto, int lx, int ly ) { malla.pulsacion(pto,lx,ly); } public void azarPosiciones( ) { // Inicializacion de las posiciones ajusteInicial(); for( int i = 0; i < ptos.length; i++ ) ptos[i].azarPosicion(); ajusteAutomatico(); } public void azarVelocidades( ) { for( int i = 0; i < ptos.length; i++ ) ptos[i].azarVelocidad(); } public void azarMasas( ) { for( int i = 0; i < ptos.length; i++ ) ptos[i].azarMasa(); } public void tensionesNulas( ) { for( int i = 0; i < muelles.length; i++ ) muelles[i].tensionNula(); } public boolean selecPunto( Point p ) { int dmin = Math.abs(ptos[0].panX-p.x) + Math.abs(ptos[0].panY-p.y); ptoSel = 0; for( int i = 1; i < ptos.length; i++ ) { int d = Math.abs(ptos[i].panX-p.x) + Math.abs(ptos[i].panY-p.y); if( d < dmin ) { dmin = d; ptoSel = i; } } if( dmin < 10 ) { return(true); } else { ptoSel = -1; return(false); } } public boolean selecPtoVel( Point p ) { int dmin = Math.abs(ptos[0].panVx-p.x) + Math.abs(ptos[0].panVy-p.y); ptoSel = 0; for( int i = 1; i < ptos.length; i++ ) { int d = Math.abs(ptos[i].panVx-p.x) + Math.abs(ptos[i].panVy-p.y); if( d < dmin ) { dmin = d; ptoSel = i; } } if( dmin < 10 ) { return(true); } else { ptoSel = -1; return(false); } } public void muevePunto( Point p, int lx, int ly ) { if( ptoSel == -1 ) return; ptos[ptoSel].moverPos(p,lx,ly); } public void muevePtoVel( Point p, int lx, int ly ) { if( ptoSel == -1 ) return; ptos[ptoSel].moverVel(p,lx,ly); } public boolean deselecPunto( ) { if( ptoSel == -1 ) return(false); ptoSel = -1; return(true); } public String infoVel( ) { if( ptoSel == -1 ) return(""); double vx = ptos[ptoSel].q[2]; double vy = ptos[ptoSel].q[3]; double r = Math.sqrt(vx*vx+vy*vy); double a = 180.0*Math.atan2(-vy,vx)/Math.PI; if(a < 0) a += 360.0; a = Math.round(1000.0*a)/1000.0; return(" ["+((float) vx)+", "+((float) vy)+"] r = "+ ((float) r)+", ang = "+a+"\u00BA"); } public void setMasaPunto( double masa ) { if(ptoSel == -1) return; ptos[ptoSel].setMasa(masa); } public double getMasaPunto( ) { if(ptoSel == -1) return(0.0); return(ptos[ptoSel].masa); } public boolean setTipoPunto( Point p, int tipo ) { if( selecPunto(p) ) { ptos[ptoSel].setTipo(tipo); if( ptoOsc == ptoSel ) ptoOsc = -1; ptoSel = -1; return(true); } else { return(false); } } public void setTipoTodos( int tipo ) { for( int i = 0; i < ptos.length; i++ ) ptos[i].setTipo(tipo); ptoOsc = -1; } public boolean setPuntoOscilante( Point p, double a, double w, boolean ejex, boolean ejey, boolean imp ) { if( selecPunto(p) ) { ptos[ptoSel].setTipoOscilante(a,w,ejex,ejey,imp); ptoOsc = ptoSel; ptoSel = -1; return(true); } else { return(false); } } public void setAmplPtoOsc( double valor ) { if( ptoOsc == -1 ) return; ptos[ptoOsc].setAmplOsc(valor); } public void setFrecPtoOsc( double valor ) { if( ptoOsc == -1 ) return; ptos[ptoOsc].setFrecOsc(valor); } public void ampliar( Point pto, int lx, int ly ) { double x = Punto.panX0 + pto.x/(lx*Punto.paniLx); double y = Punto.panY0 + pto.y/(ly*Punto.paniLy); Punto.paniLx *= 1.5; Punto.paniLy *= 1.5; Punto.panX0 = x - 0.5/Punto.paniLx; Punto.panY0 = y - 0.5/Punto.paniLy; } public void reducir( Point pto, int lx, int ly ) { double x = Punto.panX0 + pto.x/(lx*Punto.paniLx); double y = Punto.panY0 + pto.y/(ly*Punto.paniLy); Punto.paniLx /= 1.5; Punto.paniLy /= 1.5; Punto.panX0 = x - 0.5/Punto.paniLx; Punto.panY0 = y - 0.5/Punto.paniLy; } }