//======================================================
// Numerical Analysis package in java
// PlotShapes 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 PlotShapesSW 
{
public Graphics2D g;
int xabsmin,yabsmin;
int absheight,abswidth;
double xmin,xmax,ymin,ymax;
public int xlog,ylog;
double xminmaxlog,yminmaxlog;
Font f;
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};

final static BasicStroke d1 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      3.0f, dash1, 2.0f);
final static BasicStroke d2 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      3.0f, dash2, 2.0f);
final static BasicStroke d3 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      3.0f, dash3, 2.0f);
final static BasicStroke d4 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      3.0f, dash4, 2.0f);
final static BasicStroke d5 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      3.0f, dash1, 2.0f);
final static BasicStroke d6 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      3.0f, dash2, 2.0f);
final static BasicStroke d7 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      3.0f, dash3, 2.0f);
final static BasicStroke d8 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, 
                                                      BasicStroke.JOIN_MITER, 
                                                      3.0f, dash4, 2.0f);


public PlotShapesSW(Graphics2D gi,int xabsmini  ,int yabsmini,
                              int absheighti,int abswidthi,
                            double xmini,double xmaxi,
                            double ymini,double ymaxi, int xlogi,int ylogi)
{
// xabsmin   : absolute(pixel) starting point x axis
// yabsmin   : absolute(pixel) starting point y axis
// absheight : absolute(pixel) height of plotting window
// abswidth  : absolute(pixel) width of plotting window
// xmin      : minimum x value (real number)
// xmax      : maximum x value (real number)
// ymin      : minimum y value (real number)
// ymax      : maximum y value (real number)
// g         : graphic object that actual drawing is done through
g=gi;
//Font fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
//f=fonts[2].deriveFont(Font.BOLD,14);//You can change Fony from here
//g.setFont(f);
xabsmin=xabsmini;
yabsmin=yabsmini;
absheight=absheighti;
abswidth=abswidthi;
xmin=xmini;
xmax=xmaxi;
ymin=ymini;
ymax=ymaxi;
xlog=xlogi;
ylog=ylogi;
if(xlog!=0) {xminmaxlog=Math.log10(xmax-xmin+10.0)-1.0;}
if(ylog!=0) {yminmaxlog=Math.log10(ymax-ymin+10.0)-1.0;}
}

public void drawLine(int plottype,double x1,double y1,double x2,double y2)
{
// draw a line from (x1,y1) to (x2,y2)
        int xx1,xx2,yy1,yy2;
        if(xlog!=0) 
        {
        xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth));
        xx2=(int)(xabsmin+((Math.log10(x2-xmin+10.0)-1.0)/xminmaxlog*abswidth));
	    }
        else
        {
	    xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);
        xx2=(int)(xabsmin+(x2-xmin)/(xmax-xmin)*abswidth);
	    }
        if(ylog!=0) 
        {
        yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));
        yy2=(int)(yabsmin+absheight-((Math.log10(y2-ymin+10.0)-1.0)/yminmaxlog*absheight));
	    }
        else
        {
	    yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);
        yy2=(int)(yabsmin+absheight-(y2-ymin)/(ymax-ymin)*absheight);
	    }        
        g.draw(new Line2D.Double( xx1,yy1,xx2,yy2));
}  //end of drawLine


public void drawPolyline(int plottype,double x1[],double y1[])
{
// draw a line from (x1,y1) to (x2,y2)
        int points=y1.length;
        int xPoints[]=new int[points];
        int yPoints[]=new int[points];
        int xx1,yy1;	            
        for(int i=0;i<points;i++)
        {
	       if(xlog!=0) 
           {xx1=(int)(xabsmin+(Math.log10(x1[i]-xmin+10.0)-1.0)/xminmaxlog*abswidth);}
           else
           {xx1=(int)(xabsmin+(x1[i]-xmin)/(xmax-xmin)*abswidth);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-(Math.log10(y1[i]-ymin+10.0)-1.0)/yminmaxlog*absheight);}
           else
           {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 w=h-2;
        int xx1,yy1;
           if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-abswidth/200.0));}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);}//-abswidth/200.0);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight))+h/2;}
           else
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);}//+h/2;}    
        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 h=g.getFontMetrics().getHeight();
        int w=h-2;
        int xx1,yy1;
        if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-abswidth/80.0));}
        else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);}//-abswidth/80.0);}
        if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));}
        else
           {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)
{
    //draws a String at (x1,y1)
        int h=g.getFontMetrics().getHeight();
        int w=h-2;
           int xx1,yy1;
           if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+1.0)-1.0)/xminmaxlog*abswidth));}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));}
           else
           {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

        int h=g.getFontMetrics().getHeight();
        int w=h-2;
        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;
	    }
}  //end of PlotShapes.drawStrings

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;
           if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-rectwidth/2));}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-rectwidth/2);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-rectheight/2));}
           else
           {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;
           if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-barwidth/2.0));}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-barwidth/2.0);
           }
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));
           barheight =(int)((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight);
           }
           else
           {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;
           if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-barwidth/2.0));}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-barwidth/2.0);
           }
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));
           barheight =(int)((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight);
           }
           else
           {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;
           if(xlog!=0) 
           {xx1=(int)(xabsmin+(Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-rectwidth/2);}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-rectwidth/2);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-rectheight/2));}
           else
           {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;
           if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-width/2));}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-width/2);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-height/2));}
           else
           {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;
           if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-width/2));}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-width/2);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-height/2));}
           else
           {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++)
        {
	       if(xlog!=0) 
           {xvalues[i]=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth+radius*Math.cos(angle)));}
           else
           {xvalues[i]=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth+radius*Math.cos(angle));}
           if(ylog!=0) 
           {yvalues[i]=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-radius*Math.sin(angle)));}
           else
           {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++)
        {
	       if(xlog!=0) 
           {xvalues[i]=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth+radius*Math.cos(angle)));}
           else
           {xvalues[i]=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth+radius*Math.cos(angle));}
           if(ylog!=0) 
           {yvalues[i]=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-radius*Math.sin(angle)));}
           else
           {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;
     if(xlog!=0)
     {
     xvalues[2*i]= (int)(Math.floor(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/
          xminmaxlog*abswidth+R*Math.cos(teta1))));
     xvalues[2*i+1]= (int)(Math.floor(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/
          xminmaxlog*abswidth+r*Math.cos(teta2))));
     }
     else
     {
     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)));
     }
     if(ylog!=0)
     {
     yvalues[2*i]= (int)(Math.floor(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/
          yminmaxlog*absheight-R*Math.sin(teta1))));
      yvalues[2*i+1]= (int)(Math.floor(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/
          yminmaxlog*absheight-r*Math.sin(teta2))));
     }  
     else
     {
     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;
     if(xlog!=0)
     {
     xvalues[2*i]= (int)(Math.floor(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/
          xminmaxlog*abswidth+R*Math.cos(teta1))));
     xvalues[2*i+1]= (int)(Math.floor(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/
          xminmaxlog*abswidth+r*Math.cos(teta2))));
     }
     else
     {
     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)));
     }
     if(ylog!=0)
     {
     yvalues[2*i]= (int)(Math.floor(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/
          yminmaxlog*absheight-R*Math.sin(teta1))));
      yvalues[2*i+1]= (int)(Math.floor(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/
          yminmaxlog*absheight-r*Math.sin(teta2))));
     }  
     else
     {
     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++)
        {	    
	    if(xlog!=0) 
        {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth));}
        else
        {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++)
        {if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));}
        else
        {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 drawXGrid(int ticNumber)
{
        //draw x gridlies |||||||
        double dtic=(xmax-xmin)/ticNumber;
        double x1=xmin;
        for(int i=0;i<=ticNumber;i++)
        {
          drawLine(0,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(0,xmin,y1,xmax,y1);
          y1=y1+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++)
        {  if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-abswidth/40.0));}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-abswidth/40.0);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight)+absheight/20.0);}
           else
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight+absheight/20.0);} 
           s=String.format(en,"%6.4g",x1);              
          g.drawString(s,xx1,yy1);
          x1=x1+dtic;
        }
}


public void drawYNumbers(int ticNumber)
{
        // draw y  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++)
        {
          if(xlog!=0) 
           {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-abswidth/200.0)-abswidth/10.0);}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth/200.0-abswidth/10.0);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));}
           else
           {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;
     
    if(xlog!=0) 
           {xx1=(int)(xabsmin+(Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth);}
           else
           {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-(Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight+abswidth/12.0);}
           else
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight+abswidth/12.0);} 
    g.drawString(xLabel,xx1,yy1);
}

public void drawYLabel(String yLabel)
{
    // draw y labels
    double x1;
    double y1=ymax-(ymax-ymin)/2.0;
     int xx1,yy1;
           if(xlog!=0) 
           {x1=xmin-2.7;xx1=(int)(xabsmin+(Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth);}
           else
           {x1=xmin-(xmax-xmin)/6.0;xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);}
           if(ylog!=0) 
           {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));}
           else
           {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} 
    int n=yLabel.length();
    char ch[]=new char[n];
    yLabel.getChars(0,n,ch,0);
    TextLayout t=new TextLayout(yLabel,g.getFont(),g.getFontRenderContext());
    AffineTransform at=AffineTransform.getRotateInstance(3.0*Math.PI/2.0,xx1,yy1);
    g.setTransform(at);
    t.draw(g,xx1,yy1);
    at=AffineTransform.getRotateInstance(0,xx1,yy1);
    g.setTransform(at);
}

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 drawMouseTic(double xi[],double yi[],int xn)
    {
	    for(int i=0;i<xn;i++)
	    {
		if((xi[i]>=xmin && xi[i]<=xmax) && (yi[i]>=ymin && yi[i]<=ymax)) { drawStar(xi[i],yi[i],(int)(abswidth/80.0),5); }
        }          
    }
public void drawPlotLine(int plottypei,double xi[],double yi[],char ch[])
{
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,n,ch);	
}

public void drawPlotLine(int plottypei,double xi[],double yi[])
{
char ch[]=new char[1];
ch[0]='+';
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,n,ch);	
}
    
public void drawPlotLines(int i,int plottype[],double x[][],double y[][],int n[],char ch[])
{
    int j;
//draw lines
    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[i]-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(0,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(0,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(0,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(0,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(0,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(0,(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[i];j++)
        {
          if((x[i][j]>=xmin && x[i][j]<=xmax )
          && (y[i][j]>=ymin && y[i][j]<=ymax))
             { drawChar(ch[i],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[i];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[i];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[i];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[i];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[i];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[i];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[i];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[i];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[i];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[i];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;
      }                  
}

}
