import java.awt.Graphics; import java.awt.Color; import java.awt.Point; public class Punto { // Tipos de punto public static final int NORMAL = 0; public static final int HORIZONTAL = 1; public static final int VERTICAL = 2; public static final int FIJO = 3; public static final int IMPULSOR = 4; public static final int OSCILANTE = 5; // Rango de visualizacion de la pantalla public static double panX0 = 0.0; public static double panY0 = 0.0; public static double paniLx = 1.0; public static double paniLy = 1.0; // Valores maximo y minimo de las posiciones public static double minX = +1e100; public static double maxX = -1e100; public static double minY = +1e100; public static double maxY = -1e100; // Fuerzas actuantes public double fx,fy; // Masa public double masa = 1.0; private double im = 1.0; // Posicion y velocidad public double[] q = new double[4]; public double[] qc = new double[4]; private double[] qs = new double[4]; // Posicion y velocidad inicial private double[] qi = new double[4]; // Posicion en la pantalla public int panX; public int panY; public int panVx; public int panVy; // Tipo de punto private int tipo = NORMAL; // Parametros de punto oscilante private double t, iniX, iniY, ampl, frec, fase, semiper; private boolean oscHor, oscVer; public Punto(double x, double y) { q[0] = x; q[1] = y; q[2] = 0.0; q[3] = 0.0; fx = 0.0; fy = 0.0; iniX = q[0]; iniY = q[1]; t = 0.0; chequeaLimites(); } public Punto( double[] p ) { q[0] = p[0]; q[1] = p[1]; q[2] = 0.0; q[3] = 0.0; fx = 0.0; fy = 0.0; iniX = q[0]; iniY = q[1]; t = 0.0; chequeaLimites(); } public void reiniciar( ) { q[0] = qi[0]; q[1] = qi[1]; q[2] = qi[2]; q[3] = qi[3]; iniX = q[0]; iniY = q[1]; fx = 0.0; fy = 0.0; t = 0.0; chequeaLimites(); } public void chequeaLimites( ) { if( q[0] < minX ) minX = q[0]; if( q[0] > maxX ) maxX = q[0]; if( q[1] < minY ) minY = q[1]; if( q[1] > maxY ) maxY = q[1]; } public void setMasa( double m ) { masa = m; im = 1.0/masa; } public void calculaPosicion( int lx, int ly ) { panX = (int) Math.round(lx*(q[0]-panX0)*paniLx); panY = (int) Math.round(ly*(q[1]-panY0)*paniLy); } public void calculaPosVel( int lx, int ly ) { panVx = (int) Math.round(lx*(q[0]+q[2]-panX0)*paniLx); panVy = (int) Math.round(ly*(q[1]+q[3]-panY0)*paniLy); } public void moverPos( Point p, int lx, int ly ) { q[0] = panX0 + p.x/(lx*paniLx); q[1] = panY0 + p.y/(ly*paniLy); if( (tipo == IMPULSOR) || (tipo == OSCILANTE) ) { iniX = q[0]; iniY = q[1]; } chequeaLimites(); } public void moverVel( Point p, int lx, int ly ) { q[2] = panX0 + p.x/(lx*paniLx) - q[0]; q[3] = panY0 + p.y/(ly*paniLy) - q[1]; } public void dibujar( Graphics g, boolean selec ) { if(selec) g.setColor(Color.red); else switch(tipo) { case NORMAL: g.setColor(Color.blue); break; case HORIZONTAL: case VERTICAL: g.setColor(Color.green); break; case FIJO: g.setColor(Color.darkGray); break; case IMPULSOR: g.setColor(Color.cyan); break; case OSCILANTE: g.setColor(Color.pink); break; } g.fillOval(panX-3,panY-3,7,7); if( tipo == HORIZONTAL ) { g.setColor(Color.blue); g.drawLine(panX-3,panY,panX+3,panY); } if( tipo == VERTICAL ) { g.setColor(Color.blue); g.drawLine(panX,panY-3,panX,panY+3); } } public void dibujarVeloc( Graphics g ) { g.setColor(Color.magenta); g.drawLine(panX,panY,panVx,panVy); g.drawOval(panVx-2,panVy-2,4,4); } public void rungeKuttaPreparacion( ) { qi[0] = q[0]; qi[1] = q[1]; qi[2] = q[2]; qi[3] = q[3]; } public void rungeKuttaInic( ) { qs[0] = q[0]; qs[1] = q[1]; qs[2] = q[2]; qs[3] = q[3]; qc[0] = q[0]; qc[1] = q[1]; qc[2] = q[2]; qc[3] = q[3]; fx = 0.0; fy = 0.0; } public void rungeKuttaIter( double hs, double hc ) { if( tipo == FIJO ) return; if( tipo == IMPULSOR ) { if(t+hc>semiper) return; if(oscHor) qc[0] = iniX + ampl*Math.sin(frec*(t+hc)); if(oscVer) qc[1] = iniY - ((oscHor) ? ampl*Math.cos(frec*(t+hc)) : ampl*Math.sin(frec*(t+hc))); return; } if( tipo == OSCILANTE ) { if(oscHor) qc[0] = iniX + ampl*Math.sin(frec*(t+hc)); if(oscVer) qc[1] = iniY - ((oscHor) ? ampl*Math.cos(frec*(t+hc)) : ampl*Math.sin(frec*(t+hc))); return; } if( tipo != VERTICAL ) { qs[0] += hs*qc[2]; qs[2] += hs*fx*im; qc[0] = q[0] + hc*qc[2]; qc[2] = q[2] + hc*fx*im; } if( tipo != HORIZONTAL ) { qs[1] += hs*qc[3]; qs[3] += hs*fy*im; qc[1] = q[1] + hc*qc[3]; qc[3] = q[3] + hc*fy*im; } fx = fy = 0.0; } public void rungeKuttaFinal( double h ) { if( tipo == FIJO ) { chequeaLimites(); return; } if( tipo == IMPULSOR ) { t += h; if(t>semiper) return; if(oscHor) q[0] = iniX + ampl*Math.sin(frec*t); if(oscVer) q[1] = iniY - ((oscHor) ? ampl*Math.cos(frec*t) : ampl*Math.sin(frec*t)); chequeaLimites(); return; } if( tipo == OSCILANTE ) { t += h; if(oscHor) q[0] = iniX + ampl*Math.sin(frec*t); if(oscVer) q[1] = iniY - ((oscHor) ? ampl*Math.cos(frec*t) : ampl*Math.sin(frec*t)); chequeaLimites(); return; } if( tipo != VERTICAL ) { q[0] = qs[0] + h*qc[2]; q[2] = qs[2] + h*fx*im; } if( tipo != HORIZONTAL ) { q[1] = qs[1] + h*qc[3]; q[3] = qs[3] + h*fy*im; } chequeaLimites(); } public void azarPosicion( ) { if( tipo == FIJO ) return; if( tipo == IMPULSOR ) return; if( tipo == OSCILANTE ) return; if(tipo != VERTICAL) q[0] = panX0 + Math.random()/paniLx; if(tipo != HORIZONTAL) q[1] = panY0 + Math.random()/paniLx; chequeaLimites(); } public void azarVelocidad( ) { if( tipo == FIJO ) return; if( tipo == IMPULSOR ) return; if( tipo == OSCILANTE ) return; if(tipo != VERTICAL) q[2] = 2*Math.random()-1.0; if(tipo != HORIZONTAL) q[3] = 2*Math.random()-1.0; } public void azarMasa( ) { double e = 10.0*Math.random()-5.0; setMasa( Math.pow(10.0,e) ); } public void setTipo( int tipo ) { this.tipo = tipo; } public void setTipoOscilante( double a, double w, boolean hor, boolean ver, boolean impulsor ) { tipo = (impulsor) ? IMPULSOR : OSCILANTE; oscHor = hor; oscVer = ver; ampl = a; frec = 2.0*Math.PI*w; semiper = 1.0/(2.0*w); iniX = q[0]; iniY = q[1]; t = 0.0; } public void setAmplOsc( double valor ) { ampl = valor; } public void setFrecOsc( double valor ) { frec = 2.0*Math.PI*valor; semiper = 1.0/(2.0*valor); } }