//======================================================
// Numerical Analysis package in java
// shapes class
// This class convert graphic draw methods to
// plot coordinates and gives additional plotting methods
// Dr. Turhan Coban
// =====================================================
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.font.*;
import java.io.*;
import java.util.Locale;

public class shapes 
{Locale us=new Locale("US");          
final static float dash1[] = {10.0f};
final static float dash2[] = {10.0f,3.0f,3.0f};
final static float dash3[] = {10.0f,3.0f,3.0f};
final static float dash4[] = {5.0f,5.0f,5.0f};
char ch[]={'\u2295','\u2297','\u2299','\u229A','\u229B','\u229E','\u22A0','\u22A1','\u22B9','\u22C7'};
final static BasicStroke d1 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      5.0f, dash1, 3.0f);
final static BasicStroke d2 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      5.0f, dash2, 3.0f);
final static BasicStroke d3 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      5.0f, dash3, 3.0f);
final static BasicStroke d4 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      5.0f, dash4, 3.0f);
final static BasicStroke d5 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      5.0f, dash1, 2.0f);
final static BasicStroke d6 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      5.0f, dash2, 3.0f);
final static BasicStroke d7 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      5.0f, dash3, 3.0f);
final static BasicStroke d8 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      5.0f, dash4, 3.0f);
public Graphics2D g;
int xabsmin,yabsmin;
int absheight,abswidth;
double xmin,xmax,ymin,ymax;
public shapes(Graphics2D gi,int xabsmini  ,int yabsmini,
                            int abswidthi,int absheighti,
                            double xmini,double xmaxi,
                            double ymini,double ymaxi)
{
g=gi;
xabsmin=xabsmini;
yabsmin=yabsmini;
absheight=absheighti;
abswidth=abswidthi;
xmin=xmini;
xmax=xmaxi;
ymin=ymini;
ymax=ymaxi;	
}
public void drawLine(double x1,double y1,double x2,double y2)
{
// draw a line from (x1,y1) to (x2,y2)
        
        int xx1,xx2,yy1,yy2;
	    xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);
        xx2=(int)(xabsmin+(x2-xmin)/(xmax-xmin)*abswidth);
	    yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);
        yy2=(int)(yabsmin+absheight-(y2-ymin)/(ymax-ymin)*absheight); 
        //System.out.println("xx1="+xx1+"xx2="+xx2+"yy1="+yy1+"yy2="+yy2+"xabsmin="+xabsmin+"yabsmin="+yabsmin+"abswidth="+abswidth+"absheight="+absheight+"xmin="+xmin+"xmax="+xmax+"ymin="+ymin+"ymax="+ymax);
        g.draw(new Line2D.Double( xx1,yy1,xx2,yy2));       
}  //end of drawLine
public void drawPolyline(double x1[],double y1[])
{
// draw a line from (x1,y1) to (x2,y2)
        int points=x1.length;
        int xPoints[]=new int[points];
        int yPoints[]=new int[points];
        int xx1,yy1;	            
        for(int i=0;i<points;i++)
        {
          xx1=(int)(xabsmin+(x1[i]-xmin)/(xmax-xmin)*abswidth);
          yy1=(int)(yabsmin+absheight-(y1[i]-ymin)/(ymax-ymin)*absheight);    
        xPoints[i]=xx1;
        yPoints[i]=yy1;
	    }
        g.drawPolyline(xPoints,yPoints,points);
}  //end of drawPolyLine
public  void drawChar(char ch,double x1,double y1)
{
    // draws a single character at (x1,y1)
        char ch1[]=new char[1];
        ch1[0]=ch;
        int h=g.getFontMetrics().getHeight();
        int des=g.getFontMetrics().getDescent();
        int dh=h/2-des;
        int w=g.getFontMetrics().charWidth(ch);
        int xx1,yy1;
           xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth)-w/2;
           yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)+dh;   
        g.drawChars(ch1,0,1,xx1,yy1);
}  //end of PlotShapes.drawChar
public void drawChars(char ch[],int firstspace,int numberofchars,
                                double x1,double y1)
{
        int xx1,yy1;
           xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);
           yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);   
        g.drawChars(ch,firstspace,numberofchars,xx1,yy1);
}  //end of PlotShapes.drawChars

public void drawString(String s,double x1,double y1)
{
           int xx1,yy1;
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);}   
        g.drawString(s,xx1,yy1);

}  //end of PlotShapes.drawString
public void drawString(String s[],double x1,double y1,double dy)
{
    // draws a serial of Strings starting at (x1,y1)
    // increasing with dy each time
        double xx1,yy1;
        int n=s.length;
        xx1=x1;
        for(int i=0;i<n;i++)
        {   yy1=y1-i*dy;
	        if(s[i]!="") drawString(s[i],xx1,yy1);
            else break;
	    }
}
public void drawString(String s[],int plottypes[],double x1,double y1,double dx,double dy)
{
    // draws a serial of plot characters and then Strings starting at (x1,y1)
    // increasing with dy each time
        double x[]=new double[2];
        double y[]=new double[2];
        int h=g.getFontMetrics().getHeight();
        int w=h-2;
        int xx1,yy1;
        int n=s.length;
        double xx2=x1+2*dx;
        double y2=y[0];
        double yy2=0;
        for(int i=0;i<n;i++)
        {  if(s[i]!="")
           {
	       x[0]=x1;
           x[1]=x1+dx;
           y[0]=y1-i*dy;
           y[1]=y1-i*dy;
           yy2=y[0]-(xmax-xmin)/50.0;
           //drawPlotLine(int plottypei,double xi[],double yi[])
           drawPlotLine(plottypes[i],x,y);
           drawString(s[i],xx2,yy2);
           }
           else break;
       }
}  //end of PlotShapes.drawStrings
  
public void drawRect(double x1,double y1,int rectwidth,int rectheight)
{
// draw a rectangle starting at (x1,y1)
// with dimensions of (rectwidth,rectheight)
           int xx1,yy1;
           xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-rectwidth/2);
           yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-rectheight/2);              
        g.draw(new Rectangle2D.Double(xx1,yy1,rectwidth,rectheight));
}//end of drawRect

public void drawBar(double x1,double y1)
{
// draw a rectangle starting at (x1,y1)
// with dimensions of (rectwidth,rectheight)
           int xx1,yy1;
           double barheight; 
           double barwidth=abswidth/300;
           xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-barwidth/2.0);
           yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);
           barheight =(int)((y1-ymin)/(ymax-ymin)*absheight);
           g.draw(new Rectangle2D.Double(xx1,yy1,barwidth,barheight));
}//end of drawBar


public void fillBar(double x1,double y1)
{
          int xx1,yy1;
           double barheight; 
           double barwidth=abswidth/300;
           xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-barwidth/2.0);
           yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);
           barheight =(int)((y1-ymin)/(ymax-ymin)*absheight);
           g.fill(new Rectangle2D.Double(xx1,yy1,barwidth,barheight));
}//end of fillBar

public void fillRect(double x1,double y1,int rectwidth,int rectheight)
{
// draw a rectangle starting at (x1,y1)
// with dimensions of (rectwidth,rectheight)
// draw a rectangle starting at (x1,y1)
// with dimensions of (rectwidth,rectheight)
           int xx1,yy1;
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-rectwidth/2);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-rectheight/2);}              
           g.fill(new Rectangle2D.Double(xx1,yy1,rectwidth,rectheight));
}

public void drawEllipse(double x1,double y1,int width,int height)
{
//      draw an oval with the centre of (x1,y1)
//      with dimension of (width,height)
           int xx1,yy1;
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-width/2);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-height/2);}         
        g.draw(new Ellipse2D.Double(xx1,yy1,width,height));      
}//end of drawRect

public void fillEllipse(double x1,double y1,int width,int height)
{
//      draw an oval with the centre of (x1,y1)
//      with dimension of (width,height)
           int xx1,yy1;
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-width/2);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-height/2);}         
        g.fill(new Ellipse2D.Double(xx1,yy1,width,height));
}//end of drawRect

public void drawPolygon(double x1,double y1,int radius,int side)
{
//draw a polygon of n sides n=3(trinagle),n=4(dimond)....
        double Pi=Math.PI;
        int xvalues[]=new int[side+1];
        int yvalues[]=new int[side+1];
        GeneralPath polygon=new GeneralPath(GeneralPath.WIND_EVEN_ODD,
        xvalues.length);
        double angle_increase;
        double angle;
        angle_increase=2.0*Pi/side;
        angle=Pi/2.0;
        for(int i=0;i<=side;i++)
        {
           {xvalues[i]=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth+radius*Math.cos(angle));}
           {yvalues[i]=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-radius*Math.sin(angle));}          
          angle+=angle_increase;
          if(i==0)
          {
          xvalues[side]=xvalues[i];yvalues[side]=yvalues[i];
          polygon.moveTo(xvalues[0],yvalues[0]);
          }
          else
          {
           polygon.lineTo(xvalues[i],yvalues[i]);
          }          
        }
        g.draw(polygon);
}//end of drawPolygon

public void fillPolygon(double x1,double y1,int radius,int side)
{
//draw a polygon of n sides n=3(trinagle),n=4(dimond)....
//draw a polygon of n sides n=3(trinagle),n=4(dimond)....
        double Pi=Math.PI;
        int xvalues[]=new int[side+1];
        int yvalues[]=new int[side+1];
        GeneralPath polygon=new GeneralPath(GeneralPath.WIND_EVEN_ODD,
        xvalues.length);
        double angle_increase;
        double angle;
        angle_increase=2.0*Pi/side;
        angle=Pi/2.0;
        for(int i=0;i<=side;i++)
        {
           {xvalues[i]=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth+radius*Math.cos(angle));}
           {yvalues[i]=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-radius*Math.sin(angle));}          
          angle+=angle_increase;
          if(i==0)
          {
          xvalues[side]=xvalues[i];yvalues[side]=yvalues[i];
          polygon.moveTo(xvalues[0],yvalues[0]);
          }
          else
          {
           polygon.lineTo(xvalues[i],yvalues[i]);
          }          
        }
        g.fill(polygon);
}//end of fillPolygon

public void drawStar(double x1,double y1,int radius,int side)
{
   double teta=2.0*Math.PI/side;
   double R=radius;
   double r=radius*0.35;
   int xvalues[]=new int[2*side+2];
   int yvalues[]=new int[2*side+2];
   GeneralPath polygon=new GeneralPath(GeneralPath.WIND_EVEN_ODD,
   xvalues.length);
   double teta1,teta2;
   for(int i=0;i<=side;i++)
   {
     teta1=teta*i+Math.PI/2.0;
     teta2=teta/2.0+teta1;
     xvalues[2*i]= (int)(Math.floor(xabsmin+(x1-xmin)/
          (xmax-xmin)*abswidth+R*Math.cos(teta1)));
     xvalues[2*i+1]= (int)(Math.floor(xabsmin+(x1-xmin)/
          (xmax-xmin)*abswidth+r*Math.cos(teta2)));

     yvalues[2*i]= (int)(Math.floor(yabsmin+absheight-(y1-ymin)/
          (ymax-ymin)*absheight-R*Math.sin(teta1)));
     yvalues[2*i+1]= (int)(Math.floor(yabsmin+absheight-(y1-ymin)/
          (ymax-ymin)*absheight-r*Math.sin(teta2)));
            
     if(i==side)
     {
     xvalues[2*i]=xvalues[0];
     yvalues[2*i]=yvalues[0];     
     }
   }

   for(int i=0;i<=2*side;i++)
   {
          if(i==0)
          {
          polygon.moveTo(xvalues[0],yvalues[0]);
          }
          else
          {
           polygon.lineTo(xvalues[i],yvalues[i]);
          }
   }
   g.draw(polygon);

}//end of drawStar

public void fillStar(double x1,double y1,int radius,int side)
{
   double teta=2.0*Math.PI/side;
   double R=radius;
   double r=radius*0.35;
   int xvalues[]=new int[2*side+2];
   int yvalues[]=new int[2*side+2];
   GeneralPath polygon=new GeneralPath(GeneralPath.WIND_EVEN_ODD,
   xvalues.length);
   double teta1,teta2;
   for(int i=0;i<=side;i++)
   {
     teta1=teta*i+Math.PI/2.0;
     teta2=teta/2.0+teta1;
     xvalues[2*i]= (int)(Math.floor(xabsmin+(x1-xmin)/
          (xmax-xmin)*abswidth+R*Math.cos(teta1)));
     xvalues[2*i+1]= (int)(Math.floor(xabsmin+(x1-xmin)/
          (xmax-xmin)*abswidth+r*Math.cos(teta2)));

     yvalues[2*i]= (int)(Math.floor(yabsmin+absheight-(y1-ymin)/
          (ymax-ymin)*absheight-R*Math.sin(teta1)));
     yvalues[2*i+1]= (int)(Math.floor(yabsmin+absheight-(y1-ymin)/
          (ymax-ymin)*absheight-r*Math.sin(teta2)));           
     if(i==side)
     {
     xvalues[2*i]=xvalues[0];
     yvalues[2*i]=yvalues[0];     
     }
   }

   for(int i=0;i<=2*side;i++)
   {
          if(i==0)
          {
          polygon.moveTo(xvalues[0],yvalues[0]);
          }
          else
          {
           polygon.lineTo(xvalues[i],yvalues[i]);
          }
   }
   g.fill(polygon);
}//end of drawStar


public void drawXTic(int ticNumber,double ticHeight,int ticSide)
{
        //draw a series of x axis tics
        double dtic=(xmax-xmin)/ticNumber;
        double x1=xmin;
        double y1=ymin;
        double dy;
        dy=ticHeight;        
        int xx1,yy1,yy2,yy3;
        for(int i=0;i<=ticNumber;i++)
        {	    
        xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);
	    yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);
	    yy2=(int)(yabsmin+absheight-(y1-dy-ymin)/(ymax-ymin)*absheight); 
	    yy3=(int)(yabsmin+absheight-(y1+dy-ymin)/(ymax-ymin)*absheight); 
	    if(ticSide==0)
            {g.draw(new Line2D.Double( xx1,yy1,xx1,yy2));}
         else
            {g.draw(new Line2D.Double( xx1,yy1,xx1,yy3));}
            x1=x1+dtic;
        }
}

public void drawYTic(int ticNumber,double ticWidth,int ticSide)
{
        //draw a series of y axis tics
        double dtic=(ymax-ymin)/ticNumber;
        double x1=xmin;
        double y1=ymin;
        double dx;
        dx=ticWidth;        
        double xx1,xx2,xx3,yy1;
        for(int i=0;i<=ticNumber;i++)
        {
        {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} 
	    xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);
	    xx2=(int)(xabsmin+(x1-dx-xmin)/(xmax-xmin)*abswidth);
	    xx3=(int)(xabsmin+(x1+dx-xmin)/(xmax-xmin)*abswidth);      
	      if(ticSide==0)
          {g.draw(new Line2D.Double( xx1,yy1,xx2,yy1));}
          else
          {g.draw(new Line2D.Double( xx1,yy1,xx3,yy1));}
          y1=y1+dtic;
        }
}

public void drawYTic1(int ticNumber,double ticWidth,int ticSide)
{
        //draw a series of second y axis tics
        double dtic=(ymax-ymin)/ticNumber;
        double x1=xmin;
        double y1=ymin;
        double dx;
        dx=ticWidth;        
        double xx1,xx2,xx3,yy1;
        for(int i=0;i<=ticNumber;i++)
        {
        {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} 
	    xx1=(int)(xabsmin+abswidth+(x1-xmin)/(xmax-xmin)*abswidth);
	    xx2=(int)(xabsmin+abswidth+(x1-dx-xmin)/(xmax-xmin)*abswidth);
	    xx3=(int)(xabsmin+abswidth+(x1+dx-xmin)/(xmax-xmin)*abswidth);      
	      if(ticSide==0)
          {g.draw(new Line2D.Double( xx1,yy1,xx3,yy1));}
          else
          {g.draw(new Line2D.Double( xx1,yy1,xx2,yy1));}
          y1=y1+dtic;
        }
}

public void drawXGrid(int ticNumber)
{
        //draw x gridlies |||||||
        double dtic=(xmax-xmin)/ticNumber;
        double x1=xmin;
        for(int i=0;i<=ticNumber;i++)
        {
          drawLine(x1,ymin,x1,ymax);
          x1=x1+dtic;
        }
}

public void drawYGrid(int ticNumber)
{
        //draw y gridlines =====
        double dtic=(ymax-ymin)/ticNumber;
        double y1=ymin;
        for(int i=0;i<=ticNumber;i++)
        {
          drawLine(xmin,y1,xmax,y1);
          y1=y1+dtic;
        }
}

public static String timetoString(double x)
{
int h=(int)x;
String h1="";
if(h<10) h1="0"+h;
else h1=""+h;
double x1=(x-h)*60;
int m=(int)(x1);
String m1="";
if(m<10) m1="0"+m;
else m1=""+m;
int s=(int)((x1-m)*60);
String s1;
if(s<10) s1="0"+s;
else s1=""+s;
String s2=h1+":"+m1+":"+s1;
return s2;	
}
public void drawXString(int ticNumber)
{
        //draw x numbers
        Locale en=new Locale("US");
        double dtic=(xmax-xmin)/ticNumber;
        double x1=xmin;
        double y1=ymin;
        int xx1,yy1;
 
        String s;
        s="  ";
        for(int i=0;i<=ticNumber;i++)
        {  
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-abswidth/40.0);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight+absheight/20.0);} 
           s=timetoString(x1); //String.format(en,"%7.5g",x1);              
          g.drawString(s,xx1,yy1);
          x1=x1+dtic;
        }
}  

public void drawXNumbers(int ticNumber)
{
        //draw x numbers
        Locale en=new Locale("US");
        double dtic=(xmax-xmin)/ticNumber;
        double x1=xmin;
        double y1=ymin;
        int xx1,yy1;
 
        String s;
        s="  ";
        for(int i=0;i<=ticNumber;i++)
        {  
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-abswidth/40.0);}
  
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight+absheight/20.0);} 
           s=String.format(en,"%7.5g",x1);              
          g.drawString(s,xx1,yy1);
          x1=x1+dtic;
        }
}


public void drawYNumbers(int ticNumber)
{
        // draw y  numbers for first y axis
        Locale en=new Locale("US");
        double dtic=(ymax-ymin)/ticNumber;
        double x1=xmin;
        double y1=ymin;
         int xx1,yy1;
        String s;
        s="  ";
        for(int i=0;i<=ticNumber;i++)
        {
           {xx1=(int)(xabsmin-abswidth/12.0);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)+5;} 
           s=String.format(en,"%6.4g",y1);           
           g.drawString(s,xx1,yy1);
          y1=y1+dtic;
        }
}

public void drawYNumbers1(int ticNumber)
{
        // draw y for second y axis numbers
        Locale en=new Locale("US");
        double dtic=(ymax-ymin)/ticNumber;
        double x1=xmin;
        double y1=ymin;
         int xx1,yy1;
        String s;
        s="  ";
        for(int i=0;i<=ticNumber;i++)
        {
           {xx1=(int)(xabsmin+abswidth*1.02);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)+5;} 
           s=String.format(en,"%6.4g",y1);           
           g.drawString(s,xx1,yy1);
          y1=y1+dtic;
        }
}

public void drawXLabel(String xLabel)
{
    // draw x labels
    double x1=xmin+(xmax-xmin)/2.0;
    double y1=ymin;
     int xx1,yy1;
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight+abswidth/20.0);} 
    g.drawString(xLabel,xx1,yy1);
}

public void drawYLabel(String yLabel)
{
    // draw y labels
     AffineTransform origTransform = g.getTransform();
    double x1;
    double y1=ymax-(ymax-ymin)/2.0;
     int xx1,yy1;
           {x1=xmin-(xmax-xmin)/10.0;xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} 
           g.translate(xx1,yy1);
           g.rotate(3.0*Math.PI/2.0);
           g.drawString(yLabel,0,0);
           g.setTransform(origTransform);
}

public void drawYLabel1(String yLabel)
{
    // draw y labels
     AffineTransform origTransform = g.getTransform();
    double x1;
    double y1=ymax-(ymax-ymin)/2.0;
     int xx1,yy1;
           {x1=xmax+(xmax-xmin)/10.0;xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);}
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} 
           g.translate(xx1,yy1);
           g.rotate(3.0*Math.PI/2.0);
           g.drawString(yLabel,0,0);
           g.setTransform(origTransform);
}

public void drawLabel(String Label)
{
    //draw graphic label
    double x1=xmin+(xmax-xmin)/2.0;
    double y1=ymax;
    g.drawString(Label,(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth),
            (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)-(int)(abswidth/40.0));
}

public void drawAdditionalLabel(String s,double x1,double y1)
{
    //draw Additional graphic label
   drawString(s,x1,y1);
}

public void drawMouse(String ss,double xi,double yi)
{ if((xi>=xmin && xi<=xmax) && (yi>=ymin && yi<=ymax)) { String s=String.format(us,"%2s[%7.3f , %7.3f]",ss,xi,yi);drawString(s,xi,yi); }}

public void drawMouse(String ss[],double xi1,double yi1,double xi2,double yi2)
{   String s[]=new String[2];
    double dy=(ymax-ymin)/30.0;
	if((xi1>=xmin && xi1<=xmax) && (yi1>=ymin && yi1<=ymax)) 
	{ s[0]=String.format(us,"%4s[%7.3f , %7.3f]",ss[0],xi1,yi1);
	  s[1]=String.format(us,"%4s[%7.3f , %7.3f]",ss[1],xi2,yi2);
	  drawString(s,xi1,yi1,dy); 
	}
}

public void drawPlotLine(int plottypei,double xi[],double yi[])
{
int i=0;
int plottype[]=new int[1];
plottype[0]=plottypei;
int ni=xi.length;
int n[]=new int[1];
n[0]=ni;
double x[][]=new double[1][ni];
double y[][]=new double[1][ni];
for(int j=0;j<ni;j++)
{x[0][j]=xi[j];y[0][j]=yi[j];}
drawPlotLines(i,plottype,x,y);	
}

public void drawPlotLines(int i,int plottype[],double x[][],double y[][])
{ 
    int j;
//draw lines
    int n=x[i].length;
    if((plottype[i] >= 0) && (plottype[i] < 10) )
    {      
	   switch ( plottype[i] )
       {
        case 0 : g.setStroke(new BasicStroke(1.0f));break;
        case 1 : g.setStroke(d1);break;
	    case 2 : g.setStroke(d2);break;
        case 3 : g.setStroke(d3);break;
        case 4 : g.setStroke(d4);break; 
        case 5 : g.setStroke(new BasicStroke(2.0f));break;
        case 6 : g.setStroke(d5);break;
        case 7 : g.setStroke(d6);break;
        case 8 : g.setStroke(d7);break;
        case 9 : g.setStroke(d8);break;
        };
      for(j=0;j<n-1;j++)
        {
        if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
        {
        if((x[i][j+1]>=xmin && x[i][j+1]<=xmax) &&
           (y[i][j+1]>=ymin && y[i][j+1]<=ymax))
           {
           drawLine(x[i][j],y[i][j],x[i][j+1],y[i][j+1]);
           }
        else if(x[i][j+1]>xmax)
           {
              double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]);
              double  a=y[i][j]-b*x[i][j];
              drawLine(x[i][j],y[i][j],xmax,(a+b*xmax));
           }
        else if(y[i][j+1]>ymax)
           {
              double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]);
              double a=y[i][j]-b*x[i][j];
              drawLine(x[i][j],y[i][j],(ymax-a)/b,ymax);
           }
        else if(x[i][j+1]>xmax && y[i][j+1]>ymax)
           {
              double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]);
              double a=y[i][j]-b*x[i][j];
              drawLine(x[i][j],y[i][j],(ymax-a)/b,(a+b*xmax));
           }
        }
        else if((x[i][j+1]>=xmin && x[i][j+1]<=xmax )
          && (y[i][j+1]>=ymin && y[i][j+1]<=ymax))
        {
           if(x[i][j]<xmin)
           {
              double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]);
              double  a=y[i][j+1]-b*x[i][j+1];
              drawLine(xmin,(a+b*xmin),x[i][j+1],y[i][j+1]);
           }
           if(y[i][j]<ymin)
           {
              double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]);
              double  a=y[i][j+1]-b*x[i][j+1];
              drawLine((ymin-a)/b,ymin,x[i][j+1],y[i][j+1]);
           }
        }
        }//end of for(j=0
      g.setStroke(new BasicStroke(1.0f));
      }//end of if(plottype
//draw characters
    else if(plottype[i]>=10 && plottype[i]<=19)
      {
        for(j=0;j<n;j++)
        {
          if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
             { drawChar(ch[plottype[i]-10],x[i][j],y[i][j]); }
        }//end of for(j=0;
      }//end else if(plottype[i]==10..19)
//draw rectangles
    else if(plottype[i]==20)
      {
        for(j=0;j<n;j++)
        {
          if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
              { drawRect(x[i][j],y[i][j],abswidth/100,absheight/80); }
        }//end of for(j=0;
      }//end else if(plottype[i]==20)
      else if(plottype[i]==21)
      {
        for(j=0;j<n;j++)
        {
          if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
              { fillRect(x[i][j],y[i][j],abswidth/100,abswidth/80); }
        }//end of for(j=0;
      }//end else if(plottype[i]==20)
//draw circle
    else if(plottype[i]==22)
      {
        for(j=0;j<n;j++)
        {
          if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
            { drawEllipse(x[i][j],y[i][j],abswidth/100,absheight/80); }
        }//end of for(j=0;
      }//end else if(plottype[i]==22)
    else if(plottype[i]==23)
      {
        for(j=0;j<n;j++)
        {
          if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
            { fillEllipse(x[i][j],y[i][j],abswidth/100,absheight/80); }
        }//end of for(j=0;
      }//end else if(plottype[i]==21)  
    else if(plottype[i]>=24 && plottype[i]<=27)
      {
	    
        for(j=0;j<n;j++)
        { if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
             {
	          drawPolygon(x[i][j],y[i][j],abswidth/100,(plottype[i]-21));
             }
        }//end of for(j=0;
      }//end else if(plottype[i]==24..27)
      else if(plottype[i]>=28 && plottype[i]<=31)
      {
	    
        for(j=0;j<n;j++)
        { if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
             {
	          fillPolygon(x[i][j],y[i][j],abswidth/100,(plottype[i]-25));
             }
        }//end of for(j=0;
      }//end else if(plottype[i]==24..27)   
   else if(plottype[i]>=32 && plottype[i]<=35)
      {
	    
        for(j=0;j<n;j++)
        { if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
             {
	          drawStar(x[i][j],y[i][j],abswidth/100,(plottype[i]-29));
             }
        }//end of for(j=0;
      }   
   else if(plottype[i]>=36 && plottype[i]<=39)
      {	    
        for(j=0;j<n;j++)
        { if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
             {
	          fillStar(x[i][j],y[i][j],abswidth/100,(plottype[i]-33));
             }
        }//end of for(j=0;
      }     
   else if(plottype[i]==40)
      {
	    
        for(j=0;j<n;j++)
        { if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
             {
	          drawBar(x[i][j],y[i][j]);
             }
        }//end of for(j=0;
      }            
   else if(plottype[i]==41)
      {
	    
        for(j=0;j<n;j++)
        { if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
             {
	          fillBar(x[i][j],y[i][j]);
             }
        }//end of for(j=0;
      }                  
}   
}