//======================================================
// 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.io.*;
import java.awt.*;
import java.applet.Applet;

public class PlotShapes 
{
Graphics g;
int xabsmin,yabsmin;
int absheight,abswidth;
double xmin,xmax,ymin,ymax;

public PlotShapes(Graphics gi,int xabsmini  ,int yabsmini,
                              int absheighti,int abswidthi,
                            double xmini,double xmaxi,
                            double ymini,double ymaxi)
{
// xabsmin   : absulute stating point x axis
// yabsmin   : absolute starting point y axis
// absheight : absoulute height of plotting window
// abswidth  : absolute 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;
xabsmin=xabsmini;
yabsmin=yabsmini;
absheight=absheighti;
abswidth=abswidthi;
xmin=xmini;
xmax=xmaxi;
ymin=ymini;
ymax=ymaxi;
}

public void drawLine(int plottype,double x1,double y1,double x2,double y2)
{
// draw a line from (x1,y1) to (x2,y2)
       if(plottype==0) //draw a continuous line
       {
        g.drawLine( (int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth),
                    (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight),
                    (int)(xabsmin+(x2-xmin)/(xmax-xmin)*abswidth),
                    (int)(yabsmin+absheight-(y2-ymin)/(ymax-ymin)*absheight));
       }
}  //end of drawLine


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;
        g.drawChars(ch1,0,1,
            (int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth)-2,
            (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)+h/2);
}  //end of PlotShapes.drawChar

public void drawChars(char ch[],int firstspace,int numberofchars,
                                double x1,double y1)
{
// draws a character array from space firstspace to (firstspace+numberofchars)
// starting at (x1,y1)
        int h=g.getFontMetrics().getHeight();
        int w=h-2;
        g.drawChars(ch,firstspace,numberofchars,
            (int)((xabsmin+(x1-xmin)/(xmax-xmin)*abswidth)+5),
            (int)((yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)+h/2));

}  //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;
        g.drawString(s,
            (int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth),
            (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight));

}  //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)
        g.drawRect(
        (int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-rectwidth/2),
        (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-rectheight/2),
              rectwidth,rectheight);

}//end of drawRect

public void drawOval(double x1,double y1,int width,int height)
{
// draw an oval with the centre of (x1,y1)
// with dimension of (width,height)
        g.drawOval(
            (int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-width/2),
            (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-height/2),
             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=4.0*Math.atan(1.0);
        int xvalues[]=new int[side+1];
        int yvalues[]=new int[side+1];
        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)(Math.floor(xabsmin+(x1-xmin)/
          (xmax-xmin)*abswidth+radius*Math.cos(angle)));
          yvalues[i]= (int)(Math.floor(yabsmin+absheight-(y1-ymin)/
          (ymax-ymin)*absheight-radius*Math.sin(angle)));
          if(i==0) {xvalues[side]=xvalues[i];yvalues[side]=yvalues[i];}
          angle+=angle_increase;
        }
        g.drawPolygon(xvalues,yvalues,side+1);
}//end of drawPolygon

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;
        if(ticSide==0)
        {
        for(int i=0;i<=ticNumber;i++)
        {
          drawLine(0,x1,y1,x1,(y1-ticHeight));
          x1=x1+dtic;
        }
        }
        else
        {
        for(int i=0;i<=ticNumber;i++)
        {
         drawLine(0,x1,y1,x1,(y1+ticHeight));
         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;
        if(ticSide==0)
        {
        for(int i=0;i<=ticNumber;i++)
        {
          drawLine(0,x1,y1,(x1-ticWidth),y1);
          y1=y1+dtic;
        }
        }
        else
        {

        for(int i=0;i<=ticNumber;i++)
           {
            drawLine(0,x1,y1,(x1+ticWidth),y1);
            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
        double dtic=(xmax-xmin)/ticNumber;
        double x1=xmin;
        double y1=ymin;
        String s;
        s="  ";
        for(int i=0;i<=ticNumber;i++)
        {
          s=Double.toString(Math.floor(x1*100.0)/100.00);
          g.drawString(s,(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth),
            (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)+20);
          x1=x1+dtic;
        }
}



public void drawYNumbers(int ticNumber)
{
        // draw y  numbers
        double dtic=(ymax-ymin)/ticNumber;
        double x1=xmin;
        double y1=ymin;
        String s;
        s="  ";
        for(int i=0;i<=ticNumber;i++)
        {
          s=Double.toString(Math.floor(y1*100)/100.0)+" ";
          g.drawString(s,(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-40),
            (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight));
          y1=y1+dtic;
        }
}

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

public void drawYLabel(String yLabel)
{
    // draw y labels
    double x1=xmin-(xmax-xmin)/6.0;
    double y1=ymax-(ymax-ymin)/3.0;
    int n=yLabel.length();
    char ch[]=new char[n];
    yLabel.getChars(0,n,ch,0);
   // g.DrawString(yLabel,(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-60),
   //         (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight));
      for(int i=0;i<n;i++)
         {
         drawChar(ch[i],x1,y1);
         y1=y1-(ymax-ymin)/30;
         }
}

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)-10);
}

public void
drawPlotLines(int i,int plottype[],double x[][],double y[][],int n[],char ch[])
{
    int j;
//draw lines
    if(plottype[i]==0)
      {
      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
      }//end of if(plottype
//draw characters
    else if(plottype[i]==10)
      {
        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)
//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],4,4); }
        }//end of for(j=0;
      }//end else if(plottype[i]==20)
//draw circle
    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))
            { drawOval(x[i][j],y[i][j],4,4); }
        }//end of for(j=0;
      }//end else if(plottype[i]==21)
    else if(plottype[i]>=22 && 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],20,(plottype[i]-19));}
        }//end of for(j=0;
      }//end else if(plottype[i]==21..27)
}

}
