• fullscreen
  • Hbouton.pde
  • Hslider.pde
  • diffraction_rectangle.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;
        }
      }
    }
    
    //diffraction_rectangle
    //Simulation de la répartition angulaire de l'éclairement obtenu par diffraction d'une onde plane par un obstacle rectangulaire axb. 
    //On se place dans le cadre de la diffraction de Fraunhoffer.
    //On peut voir l'influence de la source et de la géométrie de l'obstacle.
    //J.roussel 
    //http://perso.ensc-rennes.fr/jimmy.roussel/index.php
    //Oct 2009
    //A FAIRE : PAS DE ZOOM. DESSINER L'IMAGE GÉOMÉTRIQUE DANS LE PLAN FOCAL D'UNE LENTILLE
    //********************************************
    //Déclaration des variables (classe variable;)
    //********************************************
    
    int H;//demi largeur du diffractogramme
    int h;//demi-hauteur du "bandeau titre+echelle"
    int dimP;//largeur du panneau de commandes
    float a,b;// dimensions de la pupille diffractante
    float IR,IG,IB;//3 composantes RGB pour une raie spectrale
    int sat2=1;
    //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[] sliders=new Hslider[3];
    Hbouton[] boutons= new Hbouton[4];
    
    //police
    PFont fontA;
    //******** Initialisation ****************
    void setup() {
      size(550,400,P2D);
      frameRate(15);
      h=16;
      H=int(height/2-h);
      dimP=width-2*H;
      background(0);
      a=100;
      b=100;
      //curseurs et boutons
      sliders[0]=new Hslider(2*H+10,50,100,10,"largeur [µm] ",10,400);
      sliders[1]=new Hslider(2*H+10,100,100,10,"hauteur [µm] ",10,400);
      sliders[2]=new Hslider(2*H+10,280,100,10,"Saturation",1,50);
      boutons[0]=new Hbouton(2*H+10,150,10,10,"Sodium");
      boutons[1]=new Hbouton(2*H+10,170,10,10,"LASER He-Ne");
      boutons[2]=new Hbouton(2*H+10,190,10,10,"Lampe Hg");
      boutons[3]=new Hbouton(2*H+10,210,10,10,"Lumière blanche");
      boutons[A].locked=true;
      //Titres
      fontA = loadFont("Helvetica-24.vlw");
      textFont(fontA, 18);
      pushMatrix();
      translate(width/2,2*H+20);//centrage du titre sous l'interférogramme
      textAlign(CENTER);
      text("Diffraction à l'infini par une pupille rectangulaire",0,0);
       textAlign(CORNER);
      popMatrix();
     textFont(fontA, 12); 
    }
    
    //*******séquences*******************
    
    void draw() { 
      //********panneau de commandes************
      noStroke();
      fill(100);
    //  rect(2*H,0,dimP,2*H);
    rect(0,0,width,2*H+1);
       sat2=int(sliders[2].getVal());
       for (int i=0;i<sliders.length;i++){
        sliders[i].update();
      sliders[i].draw();}
      // a=slider1.getVal(); 
      boutonsUpdate(boutons);
      for (int i=0;i<boutons.length;i++){
        boutons[i].draw();}
      
      //********* tracé de l'interférogramme ************** 
      pushMatrix();
      translate(H,H);//centrage de l'origine du repère
      if (A==0){diffrac(source0,sliders[0].getVal(),sliders[1].getVal());}
      if (A==1){diffrac(source1,sliders[0].getVal(),sliders[1].getVal());}
      if (A==2){diffrac(source2,sliders[0].getVal(),sliders[1].getVal());}
      if (A==3){diffrac(source3,sliders[0].getVal(),sliders[1].getVal());}
      translate(0,-H+h);//echelle
      stroke(255);
      line(0,0,40,0);//1cm=40pixels
      textAlign(CORNER);
      text("1 cm",50,0);
      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 a1, float b1) {
    float phiX=PI*a1/l1*x1/4;
    float phiY=PI*b1/l1*y1/4;
    //float eclairement=constrain(sat2*sq(sinc(phiX)*sinc(phiY)),0,1);
    //return(eclairement);
    return(sat2*sq(sinc(phiX)*sinc(phiY)));
    }
    
    float sinc(float var){
    return (sin(var)/var);
    }
    
    void diffrac(float[] source,float aa, float bb){
      float lambdaK,eclairement;
      int N;
      N=source.length;
      for (int i=0;i<H;i++){
        for (int j=0;j<H;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,aa,bb);
            doseR+=IR*eclairement;
            doseG+=IG*eclairement;
            doseB+=IB*eclairement;      
          }
          stroke(doseR/N,doseG/N,doseB/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.