import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import java.applet.*;

public class MonteCarlo extends Applet implements MouseListener{
public int n=0,N=0,z,s,bladrys,m,d=-1,lw,i;
public float x,y,POLE,blad;
public boolean czynalezy=false,polacz=false,wyswietl=false,pp=false,pokaztriang;
public Button Polacz,MonteCarlo,Triangulacja,Reset;
public int xwierzch[]=new int[100];
public int ywierzch[]=new int[100];
public int xw[]=new int[100];
public int yw[]=new int[100];
public int xt[]=new int[3];
public int yt[]=new int[3];
public int R[]=new int[100];
public int G[]=new int[100];
public int B[]=new int[100];
public float polatrojkatow[]=new float[100]; 
Random generator = new Random();

public void init(){
setLayout(null);
for(i=0;i<100;i++)
{ 
   R[i]=generator.nextInt(256);
   G[i]=generator.nextInt(256);
   B[i]=generator.nextInt(256);
}
        

ActionListener al=new ActionListener(){
   public void actionPerformed(ActionEvent e){
      if(e.getSource()==Polacz&&polacz==false&&d>=2)
      {
         polacz=true;
         repaint();
      }
      if(e.getSource()==MonteCarlo&&polacz)
      {
         n=0;
         N=0;
         lw=d+1;

         for(i=0;i<=d+2;i++)
         {
            xw[i]=xwierzch[i];
            yw[i]=ywierzch[i]; 
         }
         wyswietl=true;
         pokaztriang=false;
         repaint();
      }
      if(e.getSource()==Reset)
      {
         d=-1;
         polacz=false;
         pokaztriang=false;
         polacz=false;
         pp=false;
         wyswietl=false;
         for(i=0;i<=99;i++)
         {
            xwierzch[i]=0;
            ywierzch[i]=0;
         }
         repaint();
      }
      if(e.getSource()==Triangulacja&&polacz)
      {
         n=0;
         N=0;
         lw=d+1;
         wyswietl=false;
         pokaztriang=true;

         for(i=0;i<=d+2;i++)
         {
            xw[i]=xwierzch[i];
            yw[i]=ywierzch[i]; 
         }
         repaint();
      }    
   }
};

MonteCarlo=new Button("Monte Carlo");
MonteCarlo.setBounds(160,500,160,50);
MonteCarlo.addActionListener(al);
add(MonteCarlo);

Triangulacja=new Button("Triangulacja");
Triangulacja.setBounds(320,500,160,50);
Triangulacja.addActionListener(al);
add(Triangulacja);

Reset=new Button("Reset");
Reset.setBounds(480,500,160,50);
Reset.addActionListener(al);
add(Reset);

Polacz=new Button("Połącz");
Polacz.setBounds(0,500,160,50);;
Polacz.addActionListener(al);
add(Polacz);
addMouseListener(this);
}
boolean czysieprzecinaja(float xA,float xB,float xC,float xD,float yA,float yB,float yC,float yD)
{
   if (wyznacznik(xA,yA,xB,yB,xC,yC)*wyznacznik(xA,yA,xB,yB,xD,yD)<0&&wyznacznik(xC,yC,xD,yD,xA,yA)*wyznacznik(xC,yC,xD,yD,xB,yB)<0)
   {
      return true;
   }
   else
   {
      return false;
   }
}

float wyznacznik(float xx,float xy,float yx,float yy,float zx,float zy)
{
   return (xx*yy+yx*zy+zx*xy-zx*yy-xx*zy-yx*xy);
}
boolean czysieprzecinazpoprzednimi(int e)
{
   int i,licznik=0;
   for(i=2;i<e;i++)
   {
      if(czysieprzecinaja(xwierzch[e],xwierzch[e-1],xwierzch[e-i],xwierzch[e-i-1],ywierzch[e],ywierzch[e-1],ywierzch[e-i],ywierzch[e-i-1]))
      {
        licznik++;
      }
        
   }
   if(licznik>0)
   {
      return true;
   }
   else
   {
      return false;
   }
}

boolean czynalezy(float x,float y)
{
   int ilerazyprzecina=0;
   xwierzch[d+1]=xwierzch[0];
   ywierzch[d+1]=ywierzch[0];
   for(i=0;i<=d;i++)
   {
      if(czysieprzecinaja(0,x,xwierzch[i],xwierzch[i+1],y,y,ywierzch[i],ywierzch[i+1]))
      {
         ilerazyprzecina++;
      }
   }
   if(ilerazyprzecina%2==1)
   {
      return true;
   }
   else
   {
      return false;
   }
}
boolean czyprzecinaktorysbok(int xA, int yA,int xB, int yB)
{
   boolean cp=false;
   int i;
   xwierzch[d+1]=xwierzch[0];
   ywierzch[d+1]=ywierzch[0];
   for(i=0;i<=d;i++)
   {
      if(czysieprzecinaja(xA,xB,xwierzch[i],xwierzch[i+1],yA,yB,ywierzch[i],ywierzch[i+1]))
      {
         cp=true;
      }
   }
return cp;
}
float Polezewzoru(int d)
{
   int i;
   float Suma=0,Poledokladne=0;
   for(i=0;i<=d;i++)
   {
      Suma=Suma+xwierzch[i]*ywierzch[i+1]-xwierzch[i+1]*ywierzch[i];
   }
Poledokladne=Math.abs(Suma/5000);
return Poledokladne;
}

Color kolor(int c)
{
    return(new Color(R[c],G[c],B[c]));
}


public void paint (Graphics g){

 

g.drawLine (100,400,450,400);
g.drawLine (450,400,420,410);
g.drawLine (450,400,420,390);
g.drawString("X", 400, 420);
g.drawLine (100,400,100,50);
g.drawLine (100,50,90,80);
g.drawLine (100,50,110,80);
g.drawString("Y",80, 100);

g.drawLine (500,400,1100,400);
g.drawLine (1100,400,1070,410);
g.drawLine (1100,400,1070,390);
g.drawString("ilość punktów", 1050, 420);
g.drawLine (500,400,500,50);
g.drawLine (500,50,490,80);
g.drawLine (500,50,510,80);
g.drawString("błąd",465, 80);

g.drawLine (150,390,150,410);
g.drawString("1", 147, 423);
g.drawLine (90,350,110,350);
g.drawString("1", 82, 355);
g.drawLine (490,100,510,100);
g.drawString("100%", 457, 103);
g.drawLine (600,390,600,410);
g.drawLine (700,390,700,410);
g.drawLine (800,390,800,410);
g.drawLine (900,390,900,410);
g.drawLine (1000,390,1000,410);
g.drawString("1000", 587, 423);
g.drawString("2000", 687, 423);
g.drawString("3000", 787, 423);
g.drawString("4000", 887, 423);
g.drawString("5000", 987, 423);

for(i=0;i<300;i=i+3)
{
   g.drawLine (100+i,100,100+i,100);
   g.drawLine (400,400-i,400,400-i);
}


int k,j,i=0;

if(pokaztriang&&polacz)
{
   i=0;
   int c=-1;
   xw[lw]=xw[0];
   yw[lw]=yw[0];
   xw[lw+1]=xw[1];
   yw[lw+1]=yw[1]; 
   while(lw>3)
   {   
      for(i=0;i<lw;i++)
      {
         if(czyprzecinaktorysbok(xw[i],yw[i],xw[i+2],yw[i+2])==false&&czynalezy((xw[i]+xw[i+2])/2,(yw[i]+yw[i+2])/2))
         {
            for(k=0;k<=2;k++)
            {
               xt[k]=xw[i+k];
               yt[k]=yw[i+k];
            }
            c++;
            polatrojkatow[c]=Math.abs(1F*(xw[i]*yw[i+1]+xw[i+1]*yw[i+2]+xw[i+2]*yw[i]-xw[i+2]*yw[i+1]-xw[i]*yw[i+2]-xw[i+1]*yw[i])/5000);
            g.setColor(kolor(c));
            g.fillPolygon(xt,yt,3);
            g.setColor(Color.BLACK);
            g.drawPolygon(xt,yt,3);         
            for(j=i;j<lw;j++)
            {
               xw[j+1]=xw[j+2];
               yw[j+1]=yw[j+2];

            }
            lw--;
            break;
         }
      }
   }
   if(lw==3)
   {
      for(k=0;k<=2;k++)
      {
         xt[k]=xw[i+k];
         yt[k]=yw[i+k];
      }
      polatrojkatow[c+1]=Math.abs((1F*xw[i]*yw[i+1]+xw[i+1]*yw[i+2]+xw[i+2]*yw[i]-xw[i+2]*yw[i+1]-xw[i]*yw[i+2]-xw[i+1]*yw[i])/5000);
      g.setColor(kolor(c+1));
      g.fillPolygon(xt,yt,3);
      
      g.setColor(Color.BLACK);
      g.drawPolygon(xt,yt,3);
   }
}  

		
if(wyswietl&&polacz)
{   
   for(k=0;k<5000;k++)
   {
      N++;
      x = generator.nextFloat()*300+100;
      y = generator.nextFloat()*300+100;
      z=Math.round(x);
      s=Math.round(y);
                   
      if(czynalezy(x,y)==true)
      {
         g.setColor(Color.RED);
         n++;
      }
      if(czynalezy(x,y)==false)
      {
         g.setColor(Color.BLUE);
      }
      g.drawLine (z,s,z,s);
      g.setColor(Color.BLACK);
      
      POLE=36F*n/N;
      blad=Math.abs((POLE-Polezewzoru(d))/Polezewzoru(d));
      bladrys=Math.round(blad*300);
      g.drawLine (Math.round(N/10)+500,400-bladrys,Math.round(N/10)+500,400-bladrys);
   }
g.drawString("Pole powierzchni wielokąta obliczone metodą Monte Carlo wynosi: "+POLE, 100, 460);
g.drawString("Błąd względny obliczonego pola wynosi: "+blad*100, 500, 440);
g.drawString("%", 800, 440);

} 
if(pp)
{
   g.fillOval(xwierzch[0]-5, ywierzch[0]-5, 10, 10);
}


for(m=1;m<=d;m++){
   g.drawLine(xwierzch[m],ywierzch[m],xwierzch[m-1],ywierzch[m-1]);
   g.fillOval(xwierzch[m]-5, ywierzch[m]-5, 10, 10);
}

 
if(pokaztriang)
{
   g.drawString("Pola powierzchni poszczególnych trójkatów:",50,580);
   int l=(d-2)%10;
   int b=0;
   for(i=0;i<=l;i++)
   {
      for(j=i*10;j<i*10+10&&b<=(d-2);j++)
      {
         b++;
         g.setColor(kolor(j));
         g.fillRect(50+100*j-i*1000,600+50*i,40,10);
         g.setColor(Color.BLACK);
         g.drawString(""+polatrojkatow[j],50+100*j-i*1000,630+50*i);

      }
   }
}
if(polacz)
{
   if(czyprzecinaktorysbok(xwierzch[0],ywierzch[0],xwierzch[d],ywierzch[d])==false)
   {
      g.drawLine(xwierzch[0],ywierzch[0],xwierzch[d],ywierzch[d]);
      g.drawString("Dokładna wartość pola powierzni wielokąta wynosi: "+Polezewzoru(d), 100, 440);
      polacz=true;
   }
   else
   {
      polacz=false;  
   }
}
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){
x=e.getX();
y=e.getY();
if(100<=x&&x<=400&&100<=y&&y<=400&&polacz==false)
{
   pp=true;
   
   d++;
   xwierzch[d]=e.getX();
   ywierzch[d]=e.getY();

   if(d<=2)
   {
      repaint();
   }

   else if(czysieprzecinazpoprzednimi(d)==false)
   {
   repaint();
   }

   else
   {
      d--;
   }
}
}
public void mouseReleased(MouseEvent e){}  
}





