carnot.java

carnot.java — Java source code, 31 kB (32.634 bytes)

Dateiinhalt

import java.applet.Applet;
import java.awt.*;
import java.math.*;

public class carnot extends Applet
    implements Runnable
{

    public void init()
    {
  		setBackground(bgColor);
        for(int i = 0; i < STR.length; i++)
            if((rts = getParameter(STR[i])) != null)
                STR[i] = new String(rts);

        SP = STR[6];
        SV = STR[7];
        SPV = "T  ";
        Panel panel = new Panel();
		Panel speed = new Panel();
		
        Font neu = new Font("Dialog",3,14); 
		panel.setFont(neu);
		speed.setFont(neu);
		
		panel.add(new Label(STR[2]));
        panel.add(gammaField = new TextField("1.67"));
        panel.add(new Button(STR[0]));
        panel.add(bs = new Button(STR[1]));
		speed.add(new Label("Speed"));
		speed.add(new Button("-"));
		speed.add(new Button("+"));
        	
		if(STR[8].compareTo("Question") == 0)
            panel.add(new Label("R=0.0821"));
        else
            panel.add(new Label(STR[8]));
        		
		add("West",speed);
		add("East", panel);
			
        area = size();
        area.height -= yOffset;
        reset(true);
    }
//===========================================================================
    public boolean action(Event event, Object obj)
    {
        if(event.target instanceof Button)
        {
            String s = (String)obj;
            if(s.equals(STR[0]))
                reset(true);
            else
            if(s.equals(STR[1]))
                restart();
            else
            if(s.equals("-"))          //
			{  if(tscale<3050)	
                tscale *= 1.25D;  
			}
            else                       //increase of the speed of animation  
            if(s.equals("+"))
			{
			  if(tscale>328)	
                tscale /= 1.25D;
			}							//
        } else
        if(event.target == gammaField)
            if(Double.valueOf(gammaField.getText()).doubleValue() > 1.0D)
                reset(true);
            else
                gammaField.setText(String.valueOf(gamma));
        return true;
    }
//===========================================================================	

    void restart()
    {
        if(phase != 2)
        {
            return;
        } else
        {
			Font old, neu, new2;
			old=gb.getFont();
			neu=new Font("TimesRoman",1,16);  //set the font (the writing to be bigger)
			gb.setFont(neu);  
			
            time = 0.0D;
            stage = 0;
            Vx = (double)VL * vscale;
            Py = PVmin / Vx;
            HeatH = PVmax * Math.log((double)VH / (double)Vmin);
            c = new Color((float)(PVmin / PVmax), 0.7F, 0.0F);
            denom = PVmax - PVmin;
            str1 = STR[3];
            gb.setColor(Color.blue);
            gb.clearRect(ws, 3 * chy, area.width - ws - 2, chy);
			new2=new Font("TimesRoman",1,20);  
            gb.setFont(new2);
			gb.drawString(stre, ws+410, chy+10);  
			gb.setFont(neu);
            doing = true;
            ma = (double)(Vmax - Vmin) / 2D;
            mw = (int)(ma * 2D);
            mx = area.width - mw / 2;
            my = w + w / 4;
            ml = (double)(mx - (Vmin + width + xbar)) - ma;
            mla = ma * ma - ml * ml;
            running = true;
            bs.disable();
						
			gb.setFont(old); 
			return;
        }
    }
//===========================================================================
    public void reset(boolean flag)
    {
        running = false;
        doing = false;
        phase = 0;
        xmin = 5;
        gamma = Double.valueOf(gammaField.getText()).doubleValue();
        str1 = STR[3];
        bs.enable();
        clear();
        if(flag)
            ts = time = 0.0D;
        repaint();
    }
//===========================================================================
    public void start()
    {
        if(animThread == null)
        {
            animThread = new Thread(this);
            animThread.start();
        }
        lastTime = startTime = System.currentTimeMillis();
        time = 0.0D;
    }
//======= convert "double" to string in order to be able to display its value
    String d2String(double d)
    {
        float f = (float)((double)(int)(100D * d) / 100D);
        String s = String.valueOf(f);
        if(s.indexOf(".") == -1)
            s += ".0";
        return s;
    }
//======= convert "int" to string ===========================================
    String int2String(int i)
       { String s = String.valueOf(i); return s; }
//===========================================================================

    public void stop()
    {
        animThread = null;
        running = false;
    }
//===========================================================================
    public void run()
    {
        Thread.currentThread().setPriority(1);
        while(Thread.currentThread() == animThread) 
        {
            delta = System.currentTimeMillis() - lastTime;
            lastTime += delta;
            if(running)
                advanced((double)(delta) / tscale);
            startTime += delay;
            try
            {
                Thread.sleep(Math.max(0L, startTime - System.currentTimeMillis()));
            }
            catch(InterruptedException interruptedexception) { }
        }
    }
//==========================================================================
//======= used to display Pressure, Volume on the graphic ==================
    void PVlabel(double d, double d1, boolean flag)
    {
        g.setColor(Color.black);
        if(flag)
            g.clearRect(ws, 1, area.width - ws - 2, 3 * chy);
		Font old, neu;
		old=g.getFont();
		neu=new Font("TimesRoman",1,18);  //0-n, 1-bold, 2-ital, 3- b+i.
		
		g.setColor(Color.lightGray);
		g.fill3DRect(ws+47,chy-7,70,22,false);
		g.setColor(Color.white);
		g.fillRect(ws+49,chy-5,66,18);
		
		g.setColor(Color.lightGray);
		g.fill3DRect(ws+47,2*chy+3,70,22,false);
		g.setColor(Color.white);
		g.fillRect(ws+49,2*chy+5,66,18);
		
		g.setColor(Color.lightGray);
		g.fill3DRect(ws+47,3*chy+13,70,22,false);
		g.setColor(Color.white);
		g.fillRect(ws+49,3*chy+15,66,18);
		
		g.setColor(Color.black);
		g.setFont(neu);
		    g.drawString(SP, ws+30, chy+10); 
			g.drawString(SV, ws+30 , 2*chy+20);
			g.drawString(SPV, ws+30 , 3*chy+30);
		
			g.drawString(d2String(d), ws+65, chy+10); 
			g.drawString(d2String(d1), ws+65 , 2*chy+20);
			if (Temperature==0) g.drawString(d2String((d * d1) / RR), ws+55, 3*chy+30);
			 else g.drawString(d2String(Temperature), ws+55, 3*chy+30);
			
			g.drawString("[atm]", ws+123, chy+10); 
			g.drawString("[ l ]", ws+123 , 2*chy+20);
			g.drawString("[ K ]", ws+123 , 3*chy+30);
			
		g.setFont(old); 
    }
//===========================================================================
    void advanced(double d)
    {
		double po=0;
		int culoare=0;
		Color c1=new Color(0,0,0);
		float cul1=0;
		
		
		time += d;
        switch(stage){
        default: break;

        case 0: 				 
            Vx -= v1 * d;
			if(V_0<Vx)	V_0=Vx;
			
            xx = (int)(Vx / vscale);
            if(xx < Vmin)
            {   xx = Vmin;
                stage++;
                str1 = STR[3];
			}
            yy = PY[VL - xx];
            Py = (double)(w - yy) * pscale;
			//compute the temperature
			double g=gamma-1.0;
			Temperature = (PVmin/RR)*Math.pow(V_0/Vx,g);
			po=Math.pow(V_0/Vx,g);
			culoare=1;
			
        break;

        case 1: 
            Vx += v2 * d;
            xx = (int)(Vx / vscale);
            if(xx > VH)
            {
                xx = VH;
                stage++;
                str1 = STR[4];
            }
            Py = PVmax / Vx;
            yy = w - (int)(Py / pscale);
            //compute the temperature
			Temperature = PVmax/RR;
			V_2=Vx;
			culoare=2;
			cul1=(float)(Math.abs(Py * Vx - PVmin) / denom);	    
			break;

        case 2: 
            Vx += v1 * d;
						
            xx = (int)(Vx / vscale);
            if(xx > Vmax)
            {
                xx = Vmax;
                stage++;
                str1 = STR[5];
            }
            yy = PY2[Vmax - xx];
            Py = (double)(w - yy) * pscale;
            //compute the temperature
			Temperature = (PVmax/RR)*Math.pow(V_2/Vx,gamma-1);
			culoare=4;
			break;

        case 3: 
            Vx -= v2 * d;
            xx = (int)(Vx / vscale);
            if(xx < VL)
            {
                xx = VL;
                stage = 0;
                str1 = STR[4];
            }
            Py = PVmin / Vx;
			yy = w - (int)(Py / pscale);
			//compute the temperature
			Temperature = PVmin/RR;
			culoare=3;
			cul1=(float)(Math.abs(Py * Vx - PVmin) / denom);	    
            break;
        }
		
        refresh();
		
		Font old, neu;   
		old=g.getFont();
		neu=new Font("TimesRoman",1,16);  
		g.setFont(neu);
		
        g.drawString(str1, ws+30, w); 
		
		g.setFont(old);
		
        clrs = (float)(Math.abs(Py * Vx - PVmin) / denom);
        clrs2 = (float)((double)clrs / 2D);
		
		if (clrs<0.0)   //value of parameters might go over 1 or under 0, so we check 
		 clrs=-clrs;
		if (clrs>1.0)
		 do
		  clrs=clrs/2;
		   while(clrs>1.0);
		
		if (clrs2<0.0)
		 clrs2=-clrs2;
		if (clrs2>1.0)
		 do
		  clrs2=clrs2/2;
		   while(clrs2>1.0);
        
		if (cul1<0.0)
		 cul1=-cul1;
		if (cul1>1.0)
		 do
		  cul1=cul1/2;
		   while(cul1>1.0);
        
		float cul2=(float)((double)clrs / 2D);
		
		if((culoare==1)||(culoare==2))
		{
			c=new Color(clrs,clrs2,0.6F);
		    c1 = new Color(cul1,cul2,0.6F);
		}
        if((culoare==3)||(culoare==4))
		{
		  c=new Color(clrs,clrs2,0.7F);
		  c1 = new Color(cul1,cul2,0.7F);
		}
				
		g.setColor(c);
        g.fillRect(0, w, xx, 200);
		
		//The vertical PISTON
		
		g.setColor(Color.black);
		g.fillRect(w+310,xx+100,16,70);
		g.fillOval(w+310,xx+165,16,10);
		
		g.setColor(Color.green);
		
		g.fillOval(w+218,xx+90,202,40);
		g.fillRect(w+218,xx+70,202,40);
		g.setColor(c);
		g.fillOval(w+218,xx+70,202,40);
		g.fillRect(w+219,90,200,xx);
		
		g.setColor(Color.gray);		
		g.fillOval(w+218,70,202,40);
		g.setColor(Color.black);
		g.drawOval(w+218,70,202,40);
		g.fillRect(w+217,90,2,Vmax+23);
		g.fillRect(w+419,90,2,Vmax+23);
		
		g.drawArc(w+218,xx+70,202,40,180,180); 
		g.drawArc(w+218,xx+90,202,40,180,180);
		g.drawArc(w+218,Vmax+91,202,40,180,180);
		g.drawArc(w+218,Vmax+92,202,40,180,180);
		//the sideway tanks
		if((culoare==1)||(culoare==4))
		 g.setColor(Color.gray);
	 	  else if(culoare==2)
		   g.setColor(c1);
		    else if(culoare==3)
		     g.setColor(c1);
		
		g.fillRect(w+202,90,15,(int)(8*(Vmax+23)/10));
		g.fillRect(w+421,90,15,(int)(8*(Vmax+23)/10));
		g.setColor(Color.black);
		
		
		//The PRESSURE display
		
		g.drawOval(w+80,180,80,80);
		
		g.setColor(Color.blue);
		g.drawLine(w+80,220,w+160,220);
		g.drawLine(w+120,220,w+120,180);
		g.drawLine(w+120,220,w+120-(int)(40*Math.sin(Math.PI/13)),260-(int)(80*Math.sin(Math.PI/13)*Math.sin(Math.PI/26)));
		g.drawLine(w+120,220,w+120+(int)(40*Math.sin(Math.PI/13)),260-(int)(80*Math.sin(Math.PI/13)*Math.sin(Math.PI/26)));
		g.drawLine(w+120,220,w+120-(int)(40*Math.sin(Math.PI/4)),220+(int)(40*Math.sin(Math.PI/4)));
		g.drawLine(w+120,220,w+120+(int)(40*Math.sin(Math.PI/4)),220+(int)(40*Math.sin(Math.PI/4)));
		g.drawLine(w+120,220,w+120-(int)(40*Math.sin(Math.PI/4)),220-(int)(40*Math.sin(Math.PI/4)));
		g.drawLine(w+120,220,w+120+(int)(40*Math.sin(Math.PI/4)),220-(int)(40*Math.sin(Math.PI/4)));
		g.setColor(Color.lightGray);
		g.fillOval(w+85,185,70,70);
		
		neu=new Font("TimesRoman",1,14);
		g.setFont(neu);
		g.setColor(Color.black);
		
		g.drawString("5.5",w+60,225);
		g.drawString("18.5",w+164,225);
		g.drawString("12",w+114,177);
		g.drawString("0",w+112-(int)(40*Math.sin(Math.PI/13)),274-(int)(80*Math.sin(Math.PI/13)*Math.sin(Math.PI/26)));
		g.drawString("24",w+118+(int)(40*Math.sin(Math.PI/13)),274-(int)(80*Math.sin(Math.PI/13)*Math.sin(Math.PI/26)));
		g.drawString("2.25",w+95-(int)(40*Math.sin(Math.PI/4)),232+(int)(40*Math.sin(Math.PI/4)));
		g.drawString("21.75",w+120+(int)(40*Math.sin(Math.PI/4)),232+(int)(40*Math.sin(Math.PI/4)));
		g.drawString("8.75",w+95-(int)(40*Math.sin(Math.PI/4)),218-(int)(40*Math.sin(Math.PI/4)));
		g.drawString("15.25",w+122+(int)(40*Math.sin(Math.PI/4)),218-(int)(40*Math.sin(Math.PI/4)));
		neu=new Font("TimesRoman",1,15);
		g.setFont(neu);
		g.setColor(Color.blue);
		g.drawString("Pressure",w+92,160);
		//the part with the movement of the arrow on the screen
		double l1,x1,y1,x2,y2,xx1,yy1,xx2,yy2;
		
		g.setColor(Color.red);
		g.drawLine(w+120,220,w+120 - (int)(40*Math.sin((Math.PI/13)*(Py+1))),220 + (int)(40*Math.cos((Math.PI/13)*(Py+1))));
		l1=20/Math.cos(Math.PI/12);
		y1=220+l1*(Math.cos((Math.PI/12)+((Math.PI/13)*(Py+1))));
		y2=220+l1*(Math.cos((-Math.PI/12)+((Math.PI/13)*(Py+1))));
		x1=w+120-l1*(Math.sin((Math.PI/12)+((Math.PI/13)*(Py+1))));
		x2=w+120-l1*(Math.sin((-Math.PI/12)+((Math.PI/13)*(Py+1))));
		xx1=(x1+w+120 - (int)(40*Math.sin((Math.PI/13)*(Py+1))))/2;
		xx2=(x2+w+120 - (int)(40*Math.sin((Math.PI/13)*(Py+1))))/2;
		yy1=(y1+220 + (int)(40*Math.cos((Math.PI/13)*(Py+1))))/2;
		yy2=(y2+220 + (int)(40*Math.cos((Math.PI/13)*(Py+1))))/2;
		int a[]={w+120 - (int)(40*Math.sin((Math.PI/13)*(Py+1))),(int)(xx1),(int)(xx2)},b[]={220 + (int)(40*Math.cos((Math.PI/13)*(Py+1))),(int)(yy1),(int)(yy2)};
		g.fillPolygon(a,b,3);
		g.setColor(Color.black);
		g.fillOval(w+118,218,4,4);
		
		//The TEMPERATURE display
		
		g.drawOval(w+480,180,80,80);
		
		g.setColor(Color.blue);
		g.drawLine(w+480,220,w+560,220);
		g.drawLine(w+520,220,w+520,180);
		g.drawLine(w+520,220,w+520-(int)(40*Math.sin(Math.PI/13)),260-(int)(80*Math.sin(Math.PI/13)*Math.sin(Math.PI/26)));
		g.drawLine(w+520,220,w+520+(int)(40*Math.sin(Math.PI/13)),260-(int)(80*Math.sin(Math.PI/13)*Math.sin(Math.PI/26)));
		g.drawLine(w+520,220,w+520-(int)(40*Math.sin(Math.PI/4)),220+(int)(40*Math.sin(Math.PI/4)));
		g.drawLine(w+520,220,w+520+(int)(40*Math.sin(Math.PI/4)),220+(int)(40*Math.sin(Math.PI/4)));
		g.drawLine(w+520,220,w+520-(int)(40*Math.sin(Math.PI/4)),220-(int)(40*Math.sin(Math.PI/4)));
		g.drawLine(w+520,220,w+520+(int)(40*Math.sin(Math.PI/4)),220-(int)(40*Math.sin(Math.PI/4)));
		g.setColor(Color.lightGray);
		g.fillOval(w+485,185,70,70);
		
		neu=new Font("TimesRoman",1,12);
		g.setFont(neu);
		g.setColor(Color.black);

		double Tmax=PVmax/RR;
		double Tmin=PVmin/RR;
		g.drawString(int2String( (int) ( (5.5*(Tmax+20-Tmin)) / 24+Tmin-10) ),w+455,225);
		g.drawString(int2String((int)((18.5*(Tmax+20-Tmin))/24+Tmin-10)),w+564,225);
		g.drawString(int2String((int)((12*(Tmax+20-Tmin))/24+Tmin-10)),w+510,177);
		g.drawString(int2String((int)(Tmin-10)),w+507-(int)(40*Math.sin(Math.PI/13)),274-(int)(80*Math.sin(Math.PI/13)*Math.sin(Math.PI/26)));
		g.drawString(int2String((int)(Tmax+10)),w+520+(int)(40*Math.sin(Math.PI/13)),274-(int)(80*Math.sin(Math.PI/13)*Math.sin(Math.PI/26)));
		g.drawString(int2String((int)((2.25*(Tmax+20-Tmin))/24+Tmin-10)),w+495-(int)(40*Math.sin(Math.PI/4)),232+(int)(40*Math.sin(Math.PI/4)));
		g.drawString(int2String((int)((21.75*(Tmax+20-Tmin))/24+Tmin-10)),w+520+(int)(40*Math.sin(Math.PI/4)),232+(int)(40*Math.sin(Math.PI/4)));
		g.drawString(int2String((int)((8.75*(Tmax+20-Tmin))/24+Tmin-10)),w+495-(int)(40*Math.sin(Math.PI/4)),218-(int)(40*Math.sin(Math.PI/4)));
		g.drawString(int2String((int)((15.25*(Tmax+20-Tmin))/24+Tmin-10)),w+522+(int)(40*Math.sin(Math.PI/4)),218-(int)(40*Math.sin(Math.PI/4)));
		neu=new Font("TimesRoman",1,15);
		g.setFont(neu);
		g.setColor(Color.blue);
		g.drawString("Temperature",w+475,160);
		//the part with the movement of the arrow on the screen

		g.setColor(Color.red);
		g.drawLine(w+520,220,w+520 - (int)(40*Math.sin((Math.PI/13)*( ((Temperature-Tmin+10)/(/*Tmin-10+*/((Tmax-Tmin+20)/24))) + 1 ))),220 + (int)(40*Math.cos((Math.PI/13)*( ((Temperature-Tmin+10)/(/*Tmin-10+*/((Tmax-Tmin+20)/24))) + 1 ))));
		l1=20/Math.cos(Math.PI/12);
		y1=220+l1*(Math.cos((Math.PI/12)+((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))));
		y2=220+l1*(Math.cos((-Math.PI/12)+((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))));
		x1=w+520-l1*(Math.sin((Math.PI/12)+((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))));
		x2=w+520-l1*(Math.sin((-Math.PI/12)+((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))));
		xx1=(x1+w+520 - (int)(40*Math.sin((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))))/2;
		xx2=(x2+w+520 - (int)(40*Math.sin((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))))/2;
		yy1=(y1+220 + (int)(40*Math.cos((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))))/2;
		yy2=(y2+220 + (int)(40*Math.cos((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))))/2;
		int a1[]={w+520 - (int)(40*Math.sin((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))),(int)(xx1),(int)(xx2)},b1[]={220 + (int)(40*Math.cos((Math.PI/13)*( ((Temperature-Tmin+10)/(((Tmax-Tmin+20)/24))) + 1 ))),(int)(yy1),(int)(yy2)};
		g.fillPolygon(a1,b1,3);

		g.setColor(Color.black);
		g.fillOval(w+518,218,4,4);
		
		//Up to here we draw the two displays: PRESSURE and TEMPERATURE
        
		g.fillOval(xx - size, yy - size, size2, size2);/* this draws the moving dot*/
        
		switch(stage)  
        {
        default: break;
        case 1: 
            g.setColor(Color.red);  
            g.fillRect(xx, w, width, w2);
            Heat = PVmax * Math.log((double)xx / (double)Vmin);
            g.setColor(Color.yellow);
            g.fillRect(xxs = xx - (int)Heat, w3, (int)Heat, barH);
            xx += width;
            break;

        case 0: 
        case 2: 
            g.setColor(Color.blue);
            g.fillRect(xx, w, width, w2);
            if(stage == 2)
            {   g.setColor(Color.yellow);
                g.fillRect(xxs = xx - (int)HeatH, w3, (int)HeatH, barH);
            }
            xx += width;
            break;

        case 3: 
            g.setColor(Color.green);
            g.fillRect(xx, w, width, w2);  
            g.setColor(Color.yellow);
            Heat = PVmin * Math.log((double)Vmax / (double)xx);
            g.fillRect(xxs = xx - (int)(HeatH - Heat), w3, (int)HeatH, barH);
            xx += (int)Heat; 
            break;
        }
		
        g.setColor(Color.red);
        g.drawString("Q", xxs, w3 + chy);
        g.setColor(Color.black);
        g.fillRect(xx, w3, xbar, barH); 
        PVlabel(Py, Vx, false); 
        repaint();
    }
//===========================================================================
    public boolean mouseDown(Event event, int i, int j)
    {
		
        if((j -= yOffset) < 0)
            return false;
        if(event.modifiers == 4)
            rightClick = true;
        else
            rightClick = false;
        if(doing)
            running = !running;
        if(phase < 2)
        {
            if(phase == 0 && Math.abs(j - Ymin) < 3)
            {
                moving = true;
                return true;
            }
            Vx = (double)i * vscale;
            Py = (double)(w - j) * pscale;
		    if(Py * Vx >= PVmin)
            {
                gb.setColor(Color.blue);
                if(phase == 0)
                {			
					Font old, neu;   
					old=gb.getFont();
					neu=new Font("TimesRoman",1,16); 
					gb.setFont(neu); //
					
					PVmin = Py * Vx;
                    Vxs = Vx;   
                    drawPolygon_2(gb, PX, PY, k);  
                    gb.setColor(Color.red);
                    gb.drawString("T1", VL - fm.stringWidth("T1"), j + chy);
                    drawPolygon_2(gb, PX2, PY2, k2 - 1); 
                    gb.setColor(Color.gray);
                    gb.drawLine(Vmin, 0, Vmin, w);  
                    gb.setColor(Color.blue);
					Font new2=new Font("TimesRoman",1,20); 
                    gb.setFont(new2);  
					gb.drawString(stre, ws+410, chy+10);   
					
					gb.setFont(old);  
                } else
                {
					Font old, neu;   
					old=gb.getFont();
					neu=new Font("TimesRoman",1,16);  
					gb.setFont(neu);
		
					
	                drawPolygon_2(gb, PX2, PY2, k2 - 1);
                    gb.setColor(Color.red);
                    gb.drawString("T2", VH, PY2[k2 - 1]);
                    gb.setColor(Color.gray);
                    gb.drawLine(Vmax, 0, Vmax, w); 
					
					gb.setFont(old);
                }
                xmin = i;
                phase++;
                repaint();
            }
        }
        
		
		return true;
    }
//===========================================================================
    public boolean mouseDrag(Event event, int i, int j)
    {
        if((j -= yOffset) < 0)
            return false;
        if(moving && j < w / 2 && j > 5)
        {
            Ymin = j;
            refresh();
            g.setColor(Color.cyan);
		    g.drawLine(0, Ymin, w, Ymin);
            g.setColor(Color.cyan);
			g.drawString("Pmax=" + d2String((double)(w - j) * pscale), ws, chy);
			repaint();
        }
        return true;
    }
//===========================================================================
    public boolean mouseUp(Event event, int i, int j)
    {
        if((j -= yOffset) < 0)
            return false;
        if(doing && !rightClick)
            running = !running;
        moving = false;
        return true;
    }
//===========================================================================
    public boolean mouseMove(Event event, int i, int j)
    {
        if((j -= yOffset) < 0 || running)
            return false;
        if(i > 5 && i < w && j < w && j > Ymin + 10)
        {
            Vx0 = (double)i * vscale;
            Py0 = (double)(w - j) * pscale;
			Temperature=0;V_0=0;tscale=1000D;
            if(phase < 2 && Vx0 * Py0 >= PVmin)
            {
                Vx = Vx0;
                Py = Py0;
                double d2 = i;
                switch(phase)
                {
                case 0: 
                    refresh();
                    PVlabel(Py, Vx, false);  
                    
					double d;
                    PVr1 = d = Py * Math.pow(Vx, gamma);
                    double d3 = Py / pscale;
                    Vmin = (int)(Math.pow(d / ((double)(w - Ymin) * pscale), 1.0D / gamma) / vscale) + 1;
                    if(Vmin < 10)
                        Vmin = xmin;
					
                    k = 0;
                    VL = i;
                    for(int l = i; l >= Vmin;)
                    {
                        PX[k] = l;
                        PY[k] = w - (int)(d3 * Math.pow(d2 / (double)l, gamma));
                        l--;
                        k++;
                    }

                    g.setColor(Color.blue);
	                drawPolygon_2(g, PX, PY, k - 1); 
                    PVmax = (w - Ymin) * Vmin;
					double d5 = i * (w - j);
                    k2 = 0;
                    for(int i1 = Vmin; i1 < w;)
                    {
                        PX2[k2] = i1;
                        PY2[k2] = w - (int)(PVmax / (double)i1);
                        i1++;
                        k2++;
                    }

                    for(int j1 = w - 1; j1 >= i;)
                    {
                        PX2[k2] = j1;
                        PY2[k2] = w - (int)(d5 / (double)j1);
                        j1--;  
                        k2++;
                    }

                    g.setColor(Color.red);
                    drawPolygon_2(g, PX2, PY2, k2 - 1); 
                    g.setColor(Color.green);
					
					Font old, neu;   
					old=g.getFont();
					neu=new Font("TimesRoman",1,16); 
					g.setFont(neu); 
	
					
                    g.fillRect(i, w, width, w2);
                    g.fillOval(xx = i - size, yy = j - size, size2, size2);
                    g.setColor(Color.white);
                    g.drawLine(Vmin, w, Vmin, area.height);
                    g.setColor(Color.black);
                    g.fillRect(i += width, w3, xbar, barH);
					Font new2=new Font("TimesRoman",1,20);
					g.setFont(new2);
                 	g.drawString(stre = STR[11] + "=" + d2String(100D - (100D * d5) / PVmax) + "%", ws+410, chy+10);
                    
					g.setFont(old); 
					
					
					xmove = i + xbar;
                    PVmax *= pscale * vscale;
                    repaint();
                    break;

                case 1: 
                    if(Vx >= Vxs)
                    {
                        refresh();
                        PVlabel(Py, Vx, false);
                        Vmax = i;
                        Py = PVmin / Vx;
                        double d1;
                        PVr2 = d1 = Py * Math.pow(Vx, gamma);
                        VH = (int)(Math.pow(d1 / PVmax, 1.0D / (gamma - 1.0D)) / vscale) + 1;
                        double d4 = Py / pscale;
                        k2 = 0;
                        for(int k1 = i; k1 >= VH;)
                        {
                            PX2[k2] = k1;
                            PY2[k2] = w - (int)(d4 * Math.pow(d2 / (double)k1, gamma));
                            k1--;
                            k2++;
                        }

                        g.setColor(Color.blue);
                        drawPolygon_2(g, PX2, PY2, k2 - 1);
                        g.setColor(Color.white);
                        g.drawLine(Vmin, w, Vmin, area.height);
                        g.drawLine(Vmax, w, Vmax, area.height);
                        g.setColor(Color.green);
                        g.fillRect(xmin, w, width, w2);
                        g.fillOval(xx, yy, size2, size2);
                        g.setColor(Color.black);
                        g.fillRect(i = xmin + width, w3, xbar, barH);
                        xmove = i + xbar;
                        repaint();
                    }
                    break;
                }
            } else
            {

				repaint();
				
            }
        }
        return true;
    }
//===========================================================================
    void clear()
    {
        if(g == null)
        {
            w = (area.height * 2) / 3;
            ws = w + 5;
            w2 = area.height - 2;
            w3 = ((w + w2) - barH) / 2;
            x0 = w;
            y0 = w;
            bgImage = createImage(area.width, area.height);
            PX = new int[w + 1];
            PY = new int[w + 1];
            PX2 = new int[2 * w + 1];
            PY2 = new int[2 * w + 1];
            gb = bgImage.getGraphics();
            fgImage = createImage(area.width, area.height);
            g = fgImage.getGraphics();
            fm = gb.getFontMetrics();
            chy = fm.getHeight();
        }
		PVmin = (double)w * pscale;
        gb.setColor(bgColor);
        gb.fillRect(0, 0, area.width, area.height);
        gb.setColor(Color.gray);
        gb.drawLine(0, yy = w - (int)(1.0D / vscale), w, yy);
        gb.setColor(Color.white);
        for(int j = w - 10; j > 0; j -= 10)
        {
            double d = w * j;
            int i = j;
            for(k = 0; i < w; k++)
            {
                PX[k] = i;
                PY[k] = w - (int)(d / (double)i);
                i++;
            }

            drawPolygon(gb, PX, PY, k - 1);  //this is for drawing the isotherms
        }

        gb.setColor(Color.black);
		gb.drawRect(0, 0, w, w);
        yy = w - ticWidth;
        for(int l = w; l > 0; l -= 10)
        {
            gb.drawLine(0, l, ticWidth, l);
            gb.drawLine(xx = w - l, w, xx, yy);
        }

        gb.setColor(Color.blue);
        
		Font neu, old;
		old=gb.getFont();
		neu=new Font("TimesRoman",1,16);  
		gb.setFont(neu);
		
		gb.drawString(STR[6], 2 * ticWidth, chy);
        gb.drawString(STR[7], w - fm.stringWidth(STR[7]), w - 2 * ticWidth);
		
		
		gb.setFont(old);
        
		refresh();
    }
//===========================================================================
    void drawPolygon(Graphics g1, int ai[], int ai1[], int i)
    {
        int j = ai[0];
        int l = ai1[0];			
		for(int i1 = 1; i1 < i; i1++)  
			g1.drawLine(j, l, j = ai[i1], l = ai1[i1]);
   }
//===========================================================================
    void drawPolygon_2(Graphics g1, int ai[], int ai1[], int i)
    {
        int j = ai[0];
        int l = ai1[0];			
		for(int i1 = 1; i1 < i; i1++)
			{
			g1.drawLine(j, l, j = ai[i1], l = ai1[i1]);
			g1.drawLine(j+1, l+1, j = ai[i1]+1, l = ai1[i1]+1);
			}
    }
//===========================================================================
    public void paint(Graphics g1)
    {
        update(g1);
    }
//===========================================================================
    void refresh()
    {
        g.drawImage(bgImage, 0, 0, this);
        g.setColor(Color.black);
    }
//===========================================================================
    public void update(Graphics g1)
    {
        if(!moving)
        {
            g.setColor(Color.cyan);
            g.drawLine(0, Ymin, w, Ymin);
        }
        g1.drawImage(fgImage, 0, yOffset, this);
    }
//===========================================================================
	public carnot()
    {
        yOffset = 40;
        time = 0.0D;
        ts = 0.0D;
        bgColor = Color.lightGray;
        doing = false;
        running = false;
        startTime = 0L;
        delay = 50L;
        tscale = 1000D;
        RR = 0.08200622368661907D;
        v1 = 5D;       
        v2 = 1.0D;
        rightClick = false;
        moving = false;
        phase = 0;
        xbar = 20;
        VL = 10;
        VH = 20;
        size = 4;  
        size2 = 2 * size; 
        Ymin = 10;        
        barH = 20;
        barW = 50;
        width = 20;   
        ticWidth = 3;
        vscale = 0.10000000000000001D;
        pscale = 0.050000000000000003D;
    }

//=================   here we have the variables
    int yOffset;
    TextField gammaField;
    double time;
    double ts;
    Dimension area;
    Image bgImage;
    Image fgImage;
    Graphics gb;
    Graphics g;
    Color bgColor;
    String rts;
    String STR[] = {
        "Reset", "Start", "CPCV", "isothermal2", "adiabatic", "isothermal1", "P", "V", "Question", "Punit", 
        "Vunit", "e", "Tunit"
    };
    String SP;
    String SV;
    String SPV;
    Button bs;
    int xx;
    int yy;
    int xmin;
    double gamma;
    int mw;
    int mx;
    int my;
    double mr;
    double ml;
    double ma;
    double mr0;
    double mla;
    boolean doing;
    boolean running;
    Thread animThread;
    long startTime;
    long lastTime;
    long delay;
    long delta;
    double HeatH;
    double denom;
    double tscale;
    double RR;
    int stage;
    double v1;
    double v2;
    double Heat;
    float clrs;
    float clrs2;
    Color c;
    String str1;
    int xxs;
    int xmove;
    double cs;
    double sc;
    int xp;
    int yp;
    boolean rightClick;
    boolean moving;
    int phase;
    int xbar;
    double Py;
    double Vx;
    double Py0;
    double Vx0;
    int Vmin;
    int Vmax;
    int VL;
    int VH;
    int size;
    int size2;
    int Ymin;
    double PVr1;
    double PVr2;
    double Vxs;
    String stre;
    FontMetrics fm;
    int chy;
    int x0;
    int y0;
    int w;
    int w2;
    int w3;
    int ws;
    int barH;
    int barW;
    int width;
    int ticWidth;
    double vscale;
    double pscale;
    double PVmin;
    double PVmax;
    int PX[];
    int PY[];
    int PX2[];
    int PY2[];
    int k;
    int k2;
	double Temperature=0;
	double V_0=0;
	double V_2=0;
}