home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / demos / xgas / molecule.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  3.3 KB  |  126 lines

  1. /*
  2.  * molecule.c
  3.  *   xgas: Copyright 1990 Larry Medwin: @(#)molecule.c    1.1 2/9/90
  4.  *   Larry Medwin -- Dec. 18, 1989
  5.  *   Larry Medwin -- Jan. 22, 1991: addMolecules()
  6.  */
  7.  
  8. #include "xgas.h"
  9.  
  10. /*
  11.  *  ADD MOLECULES
  12.  *
  13.  *  Place molecules with the mouse buttons:
  14.  *    MB 1: one molecule
  15.  *    MB 2: as many as possible
  16.  *  Pick a random angle to start trajectory.
  17.  *
  18.  *  Drawing Molecules:
  19.  *    This routine must guarantee that:
  20.  *        Molecules are drawn exactly once in their new position.
  21.  *        The "current" allPos array is updated with this position.
  22.  *        nmolecules is updated consistently.
  23.  */
  24. void addMolecule( w, data, event)
  25.     Widget w;
  26.     LabData *data;
  27.     XEvent *event;
  28. {
  29.     Molecule *mol;
  30.     float v;
  31.     float theta;
  32.     Coord pos;
  33.  
  34.     /* Do we still have room for this one? */
  35.     if( data->nmolecules >= data->maxMolecules) {
  36.     return;
  37.     }
  38.  
  39.     /* Find a place for it in the "global data" structure */
  40.     mol = &data->molecules[ data->nmolecules ];
  41.  
  42.     /* Get starting point from mouse position */
  43.     /*    data->scale.x has units of pixels/mm */
  44.     pos.x = event->xbutton.x / data->scale.x;
  45.     pos.y = event->xbutton.y / data->scale.y;
  46.  
  47.     /* Init temperature of molecule (JUST A TEST: always set to one temp. */
  48.     mol->temperature = data->chamber[0].temperature;
  49.  
  50.     /* Pick a random angle */
  51.     theta = frand( 0.0, TWO_PI);
  52.  
  53.     /* Scale the velocities by the kinetic energy */
  54.     v = vEquilibrium( mol->temperature);
  55.     mol->yCoeff[1] = sin( theta ) * v;
  56.     mol->xCoeff[1] = cos( theta ) * v;
  57.  
  58.     /* Form the equations of motion */
  59.     mol->xCoeff[0] = pos.x;
  60.     mol->yCoeff[0] = pos.y;
  61.  
  62.     /* Fake last collision: use current location as collisionPos */
  63.     mol->collisionPos.x = pos.x;
  64.     mol->collisionPos.y = pos.y;
  65.     mol->collisionTime = data->time;
  66.  
  67.     /* Which box are we in? (wall[4].end[1] is far corner of box 0) */
  68.     if( pos.x == data->chamber[0].walls[4].end[1].x) {
  69.  
  70.     /* starting in hole; which way are we moving? */
  71.     if( mol->xCoeff[1] > 0.0) {
  72.         mol->thisBox = 1;
  73.     }
  74.     else {
  75.         mol->thisBox = 0;
  76.     }
  77.     }
  78.     else if( pos.x < data->chamber[0].walls[4].end[1].x) {
  79.     mol->thisBox = 0;
  80.     }
  81.     else {
  82.     mol->thisBox = 1;
  83.     }
  84.     if (mol->thisBox != 0 && mol->thisBox != 1) {
  85.     error("In addMolecule(): couldn't pick a box.", 0);
  86.     }
  87.  
  88.     /* next collision? */
  89.     mol->collisionWall = NULL;
  90.     findNextCollision( mol, data);
  91.  
  92.     /* Add molecule to the allPos array of all molecule positions */
  93.     data->allPos[ data->nmolecules*2 +  data->timestep % 2 ].x
  94.     = (short) event->xbutton.x;
  95.     data->allPos[ data->nmolecules*2 + data->timestep % 2 ].y
  96.     = (short) event->xbutton.y;
  97.  
  98.     /* Draw it in its initial position */
  99.     XFillRectangle( XtDisplay(w), XtWindow(w), data->MoleculeGC,
  100.     (int) data->allPos[ data->nmolecules*2 + data->timestep % 2 ].x,
  101.     (int) data->allPos[ data->nmolecules*2 + data->timestep % 2 ].y,
  102.     (int) MOLECULE_SIZE, (int) MOLECULE_SIZE);
  103.  
  104.     /* Increment number of molecules */
  105.     data->nmolecules += 1;
  106. }
  107.  
  108. void addMolecules( w, data, event)
  109.     Widget w;
  110.     LabData *data;
  111.     XEvent *event;
  112. {
  113.     int i;
  114.  
  115.     switch (event->xbutton.button) {
  116.     case 1:        addMolecule( w, data, event);
  117.             break;
  118.     case 2:        for (i=data->nmolecules; i<data->maxMolecules; i++)
  119.                 addMolecule( w, data, event);
  120.             break;
  121.     default:
  122.             break;
  123.     }
  124. }
  125.  
  126.