• fullscreen
  • Hbouton.pde
  • Hslider.pde
  • lame_air2.pde
  • //Classe de bouton
    class Hbouton
    {
      int width, height;// largeur et hauteur du bouton
      int xpos, ypos;     // positions du bouton
      boolean over;       // la souris est-elle sur le bouton ?
      boolean locked;     // le bouton est il ans l'état ON ?
      String label;  
      color couleurOn=color(169,111,217);
      color couleurOff=color(255,255,255);
    
    
      Hbouton (int xp, int yp, int sw, int sh, String lb) {
        width = sw;
        height = sh;
        xpos = xp;
        ypos = yp;
        label=lb;
        over=false;
        locked=false;
      }
    
    
      void draw() {
        rectMode(CORNER);
        if (over && !locked )
        {
          stroke(couleurOn);
          fill(couleurOn);
          rect(xpos, ypos, width, height);
          fill(couleurOff);
          text(label,xpos+width+10,ypos+height);
        }
        if (locked)
        {
          stroke(couleurOn);
          fill(couleurOn);
          rect(xpos, ypos, width, height);
          text(label,xpos+width+10,ypos+height);
        }
        if(!over && !locked){
          stroke(couleurOff);
          fill(couleurOff);
          rect(xpos, ypos, width, height);
         text(label,xpos+width+10,ypos+height);
        }
        }
    
    }
    
    
    //Classe de curseur horizontal valeur réelle
    class Hslider
    {
      int swidth, sheight;    // largeur et hauteur du curseur
      int xpos, ypos;         // positions de l'extrémité gauche de la barre du curseur
      int spos, newspos;    // x position du curseur
      float val,valMin,valMax,valPrec; //valeur associée à la position du curseur comprise entre valmin et valmax
      boolean over;           // is the mouse over the slider?
      boolean locked;
      String label;
    
      Hslider (int xp, int yp, int sw, int sh, String lb, float vMin, float vMax) {
        swidth = sw;
        sheight = sh;
        xpos = xp;
        ypos = yp-sheight/2;
        spos = xpos + swidth/2;
        newspos = spos;
        valMin = vMin;
        valMax = vMax;
        val = valMin + (spos-xpos)*(valMax-valMin)/swidth;
        valPrec = val;
        label=lb;
      }
    
      void update() {
        if(over()) {
          over = true;
        } else {
          over = false;
        }
        if(mousePressed && over) {
          locked = true;
        }
        if(!mousePressed) {
          locked = false;
        }
        if(locked) {
          newspos = rampe(mouseX, xpos, xpos+swidth);
        }
        if(abs(newspos - spos) > 1) {
          spos = spos + (newspos-spos)/2;
          val = valMin + (spos-xpos)*(valMax-valMin)/swidth;
        }
      }
    
      int rampe(int xx, int xxMin, int xxMax) {
        return min(max(xx, xxMin), xxMax);
      }
    
      boolean over() {
        if(mouseX >= xpos && mouseX <= xpos+swidth &&
        mouseY >= ypos-sheight/2 && mouseY <= ypos+sheight/2) {
          return true;
        } else {
          return false;
        }
      }
    
      void draw() {
        rectMode(CENTER);
        stroke(0);
          line(xpos,ypos,swidth+xpos,ypos);
       for(int i=1;i<2;i++){
           stroke(163,105,211,200-100*(i-1));
          line(xpos,ypos+i,swidth+xpos,ypos+i);
          line(xpos,ypos-i,swidth+xpos,ypos-i);
        }
        if(over || locked) {
          fill(163,105,211,120);
          stroke(255,255,255);
        } else {
          stroke(163,105,211);
          fill(255,255,255);
          }
        rect(spos, ypos, sheight, sheight);
        fill(0);
        text(label,xpos,ypos-sheight);
        text(val,xpos,ypos+2*sheight);
        rectMode(CORNER);
      }
    
      float getVal() {
        // donne la valeur associée au curseur.
        return val;
      }
      boolean change() {
        if(valPrec!=val) {
           valPrec=val;return true;
        } else {
          return false;
        }
      }
    }
    
    //lame_air
    //Franges d'égale inclinaison simulées : Une source éclaire un interféromètre de Michelson configuré en lame d'air.
    //La simulation montre l'interférogramme obtenu sur un écran situé à la distance D=1m. On peut voir l'influence de la source et du décalage optique.
    //J.roussel 
    //http://perso.ensc-rennes.fr/jimmy.roussel/index.php
    //Sept 2009
    
    //********************************************
    //Déclaration des variables (classe variable;)
    //********************************************
    
    int L; //largeur de l'écran
    int H;
    int h;//hauteur du "bandeau titre+echelle"
    int dimInterf; //dimension de l'interférogramme
    float decalage; // decalage optique  c'est-à-dire l'épaisseur de la lame d'air
    float D;//distance ecran-lame d'air
    float IR,IG,IB;//3 composantes RGB pour une raie spectrale
    //sources
    //lumiere blanche
    float source3[]={380,400,420,440,460,480,500,520,540,560,600,620,640,660,680,700,720,740,760,780};
    //sodium
    float source0[]={589,589.6};
    //laser rouge He-Ne
    float source1[]={632.8};
    //mercure
    float source2[]={435.8,546,576.9,579};
    int A=0; //numéro de la source activée
    
    //curseurs horizontaux et boutons
    Hslider slider1;
    Hbouton[] boutons= new Hbouton[4];
    //police
    PFont fontA;
    //******** Initialisation ****************
    void setup() {
      size(550,400,P2D);
      frameRate(15);
      L=width;
      H=int(height/2);
      h=32;
      dimInterf=height-h;
      background(0);
      D=1.;
      //curseurs et boutons
      slider1=new Hslider(2*H,300,100,10,"décalage optique [mm] ",-0.3,0.3);
      boutons[0]=new Hbouton(2*H,100,10,10,"Sodium");
      boutons[1]=new Hbouton(2*H,120,10,10,"LASER He-Ne");
      boutons[2]=new Hbouton(2*H,140,10,10,"Lampe Hg");
      boutons[3]=new Hbouton(2*H,160,10,10,"Lumière blanche");
      boutons[A].locked=true;
      //Titres et echelles
      fontA = loadFont("Helvetica-24.vlw");
      textFont(fontA, 18);
      pushMatrix();
      translate(H,2*H-h/2+5);//centrage du titre sous l'interférogramme
      textAlign(CENTER);
      text("Franges d'égale inclinaison",0,0);
      translate(dimInterf/2,0);//centrage de l'échelle sous le panneau
      textFont(fontA, 12);
      stroke(255);
      line(0,0,10,0);//1cm=10pixels
      textAlign(CORNER);
      text("1 cm",20,0);
      popMatrix(); 
    }
    
    //*******séquences*******************
    
    void draw() { 
      //********panneau de commandes************
      noStroke();
      fill(100);
      rect(dimInterf,0,L-dimInterf,2*H-h);
      slider1.update();
      slider1.draw();
      decalage=slider1.getVal(); 
      boutonsUpdate(boutons);
      for (int i=0;i<boutons.length;i++){
        boutons[i].draw();}
      
      //********* tracé de l'interférogramme ************** 
      pushMatrix();
      translate(dimInterf/2,dimInterf/2);//centrage de l'origine du repère
      if (A==0){traceFranges(source0,decalage);}
      if (A==1){traceFranges(source1,decalage);}
      if (A==2){traceFranges(source2,decalage);}
      if (A==3){traceFranges(source3,decalage);}
      
      popMatrix(); 
    }
    //************** Mise à jour de l'état des boutons *************
    void boutonsUpdate(Hbouton[] x)
    {int kmax=x.length;
       for (int k=0;k<kmax;k++){
         if (mouseX >= x[k].xpos && mouseX <= x[0].xpos+x[k].width && 
          mouseY >= x[k].ypos && mouseY <= x[k].ypos+x[k].height)
          { x[k].over= true;
          if(mousePressed){x[k].locked=true;A=k;
           for(int i=0;i<k;i++){
           x[i].locked=false;}
           for(int i=k+1;i<kmax;i++){
           x[i].locked=false;} 
           }
           }
          else{x[k].over=false;}
      }
    }
    
    //********* procédure de conversion lambda->RGB ****************
    void lambdaToRgb(float x)
    { 
      float R=1;
      float G=1;
      float B=1;
      float sat=1;
      if(x<440. && x>=380.){
        R=(440.-x)/60;
        G=0;
        B=1.;
      }
      if(x<490. && x>=440.){
        R=0;
        G=(x-440.)/50.;
        B=1.;
      }
      if(x<510. && x>=490.){
        R=0;
        G=1.;
        B=(510.-x)/20.;
      }
      if(x<580. && x>=510.){
        R=(x-510.)/70.;
        G=1.;
        B=0;
      }
      if(x<645. && x>=580.){
        R=1;
        G=(645.-x)/65.;
        B=0;
      }
      if(x<780. && x>=645.){
        R=1.;
        G=0;
        B=0;
      }
      if(x>700.){
        sat=0.3+0.7*(780.-x)/80.;
      }
      if(x<420.){
        sat=0.3+0.7*(x-380.)/40.;
      }
      IR=(255*sat*R);
      IG=(255*sat*G);
      IB=(255*sat*B);
    }
    //donne l'éclairement en un point M(x,y) de l'écran situé à la distance D de la lame d'air.
    // x et y sont en pixel et la longueur d'onde en nm
    float eLambda(int x1,int y1,float l1, float e1) {
    float a1=(2*e1*1000000/l1)%1;
    float a2=(sq(x1)+sq(y1))*e1/(l1*sq(D));
    float phi =2*PI*(a1-a2);
      return(1+cos(phi));
    }
    
    
    void traceFranges(float[] source,float e2){
      float lambdaK,eclairement;
      int N;
      N=source.length;
      for (int i=0;i<dimInterf/2;i++){
        for (int j=0;j<dimInterf/2;j++){
         float doseR=0;
         float doseG=0;
          float doseB=0;
          for (int k=0;k<N;k++){
            lambdaK=source[k];
            lambdaToRgb(lambdaK);
            eclairement=eLambda(i,j,lambdaK,e2);
            doseR+=IR*eclairement;
            doseG+=IG*eclairement;
            doseB+=IB*eclairement;      
          }
          stroke(doseR/(2*N),doseG/(2*N),doseB/(2*N));
          point(i,j);
          point(-i,j);
          point(i,-j);
          point(-i,-j);
        }
      }
    }
    
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Jimmy Roussel
    You need to login/register to comment.