/*
Onde - algorithme de simulation pour SimuApplet

Copyright (C) 2002 Observatoire de Paris-Meudon

Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier conformément aux dispositions de la Licence Publique Générale GNU, telle que publiée par la Free Software Foundation ; version 2 de la licence, ou encore (à votre choix) toute version ultérieure.

Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans même la garantie implicite de COMMERCIALISATION ou D'ADAPTATION A UN OBJET PARTICULIER. Pour plus de détail, voir la Licence Publique Générale GNU .

Vous devez avoir reçu un exemplaire de la Licence Publique Générale GNU en même temps que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation Inc., 675 Mass Ave, Cambridge, MA 02139, Etats-Unis.
*/

import java.util.Vector;

import simu.*;

/**
 * Algorithme de simulation pour SimuLab.
 * Propagation d'une onde.
 * compilation: javac -source 1.2 -target 1.1 -encoding ISO-8859-1 -classpath SimuLab.jar Onde.java
 */
public class Onde extends SimuApplet {

    double[][] tmasque;
    int dx=200, dy=200, dz;
    double[][] z0;
    double w;
    int tps;
    double[][] champ;

    public Onde() {
        appletDoc("onde_doc.xml");
        /* nouvelle version de SimuLab : les paramètres sont dans le fichier XML
        ParamIn l = new ParamIn();
        l.type = "nombre";
        l.label = "long_onde";
        l.titre = "longeur d'onde";
        l.unit = "m";
        l.acquisition = "champ";
        l.defaut = "100";
        addParamIn(l);
        ParamIn v = new ParamIn();
        v.type = "nombre";
        v.label = "vitesse";
        v.titre = "vitesse de propagation";
        v.unit = "m/s";
        v.acquisition = "champ";
        v.defaut = "2";
        addParamIn(v);
        ParamIn d = new ParamIn();
        d.type = "nombre";
        d.label = "direction";
        d.titre = "direction de propagation de l'onde";
        d.unit = "degrés";
        d.acquisition = "champ";
        d.defaut = "45";
        addParamIn(d);       
        
        // paramètres de sortie
        ParamOut chp = new ParamOut();
        chp.type = "tableau";
        chp.label = "champ";
        addParamOut(chp);

        // options d'affichage
        Affichage p = new Affichage();
        p.type = "image";
        p.titre = "propagation d'une onde plane";
        String[][]pparams = {{"champ"}};
        p.params = pparams;
        p.imgdimx = dx;
        p.imgdimy = dy;
        addAffichage(p);
        */
    }


// calcul en image (utilisé avec affichage image)
    public void initCalculLive(ListeValeurs in) throws SimuException {
        double kx, ky, T;
        double[][] rx;
        double[][] ry;
        
        double long_onde = in.lireDouble("long_onde");
        double vitesse = in.lireDouble("vitesse");
        double direction = in.lireDouble("direction");
        
        tmasque = new double[dx][dy];
        for (int i=0; i<dx; i++) {
            for(int j=0; j<dy; j++){
                tmasque[i][j] = 1;
            }
        }
        
        T = long_onde / vitesse;
        w = 2 * Math.PI / T;
        dz = (int)(Math.abs(T));
        rx = new double[dx][dy];
        ry = new double[dx][dy];
        z0 = new double[dx][dy];
        kx = Math.cos(direction * Math.PI/180) * 2 * Math.PI / long_onde;
        ky = Math.sin(direction * Math.PI/180) * 2 * Math.PI / long_onde;
        for (int i=0; i<dx; i++) {
            for (int j=0; j<dy; j++) {
                rx[i][j] = i;
                ry[i][j] = j;
                z0[i][j] = kx*rx[i][j] + ky*ry[i][j];
            }
        }
        tps = 0;
        champ = new double[dx][dy];
    }
    
    public ListeValeurs calculLive() throws SimuException {
        ListeValeurs out = new ListeValeurs();
        onde_plane();
        for (int i=0; i<dx; i++) {
            for (int j=0; j<dy; j++) {
                champ[i][j] = 255*champ[i][j];
            }
        
        }
        out.ajouter("champ", champ);
        tps++;
        return out;
    }
    
    public void onde_plane() {
        int tpsmod = tps % dz;
        for (int i=0; i<dx; i++)
            for (int j=0; j<dy; j++)
                champ[i][j] = (Math.cos(w * tpsmod - z0[i][j]) * tmasque[i][j] + 1) / 2;
    }
    
    public ListeValeurs calcul(ListeValeurs in) throws SimuException {
        throw new SimuException("calcul n'est pas implémenté dans Onde: " +
            "utiliser calculLive à la place");
    }

}
