import java.awt.*;
import java.util.*;

public class newGraphics {
  Graphics g;
  double xDal=0, yDal=0, xAl, yAl;
  
  newGraphics(Graphics g) {
    this.g=g;
  }
  
  private void disCircolo(double xc, double yc, double ra, double rb, int nl, double rotz, double ainz, double afin) {
// se l'angolo iniziale risulta maggiore di quello finale allora negativizza quello iniziale
// es: arco da 270° a 45° diventa da -90° a 45° 
    if (ainz>afin) ainz=ainz-2*Math.PI;
        
    for (double an=rotz+ainz; an<=rotz+afin+.0001; an+=(afin-ainz)/nl) {
      xAl = ra*Math.cos(an)+ xc;
      yAl = rb*Math.sin(an)+ yc;
      if (an>rotz+ainz) g.drawLine((int) xDal, (int) yDal, (int) xAl, (int) yAl);
      xDal=xAl;
      yDal=yAl;
    }
  }

// poligono ellittico non ruotato
  public void disPoligonoE(double xc, double yc, double ra, double rb, int nl) {
    disCircolo(xc, yc, ra, rb, nl, 0, 0, 2*Math.PI);
  }

// poligono regolare non ruotato
  public void disPoligonoR(double xc, double yc, double r, int nl) {
    disCircolo(xc, yc, r, r, nl, 0, 0, 2*Math.PI);
  }

// poligono regolare ruotato
  public void disPoligonoR(double xc, double yc, double r, int nl, double rotz) {
    disCircolo(xc, yc, r, r, nl, rotz, 0, 2*Math.PI);
  }

// ellisse
  public void disEllisse(double xc, double yc, double ra, double rb) {
     disCircolo(xc, yc, ra, rb, 128, 0,0, 2*Math.PI);
  }

// circonferenza con noti centro e raggio
  public void disCirconf(double xc, double yc, double r) {
    disCircolo(xc, yc, r, r, 128, 0, 0, 2*Math.PI);
  }

// circonferenza passante per 3 punti noti (obsoleta dall'art. III)
	public void disCirconf(double xa, double ya, double xb, double yb, double xc, double yc) {
    double m1 = -(xb - xa) / (yb - ya);
    double m2 = -(xb - xc) / (yb - yc);
    double n1 = ((xb*xb - xa*xa) + (yb*yb - ya*ya)) / 2 / (yb - ya);
    double n2 = ((xb*xb - xc*xc) + (yb*yb - yc*yc)) / 2 / (yb - yc);
 
    if (m1 != m2) {
		  double x = (n2 - n1) / (m1 - m2);
      double y = m2 * x + n2;
      double r = Math.sqrt((x - xb)*(x - xb) + (y - yb)*(y - yb));
			disCircolo(x, y, r, r, 128, 0, 0, 2*Math.PI);
		}
		else System.out.println("i punti sono allinati");
	}

// disegnaun arco con noti centro, raggio e angoli iniziale e finale  
  public void disArco(double xc, double yc, double r, double ainz, double afin) {
    disCircolo(xc, yc, r, r, 128, 0, ainz, afin);
  }
}

// risoluzione di un'equazione di secondo grado utile al calcolo di intersezione
// tra entita' geometriche
class eq2grado {
	double a, b, c;
	double[] s= new double[2];


	eq2grado(double a, double b, double c) {
		this.a=a;
		this.b=b;
		this.c=c;
		double delta=b*b - 4*a*c;
		if (delta>=0) {
			s[0]=(-b + Math.sqrt(delta)) / (2*a);
			s[1]=(-b - Math.sqrt(delta)) / (2*a);
		}
		else System.out.println("non esiste un'intersezione reale");
	}

}

class Punto extends entita{
	double x, y;

// Origine (0, 0)
  Punto() {
    x=0;
    y=0;
	}

	Punto(double x, double y) {
		this.x=x;
		this.y=y;
	}

// punto di intersezione tra due linee
	Punto(Linea L1, Linea L2) {
		if (L1.m != L2.m) {
		  if (!Double.isInfinite(L1.m) && !Double.isInfinite(L2.m))	{
		    x=(L2.n - L1.n) / (L1.m - L2.m);
		    y=L2.m * x + L2.n;
		  }
		  else {
			  if (Double.isInfinite(L1.m)) {
			    x=L1.P1.x;
			    y=L2.m*x + L2.n;
			  }
		  	  if (Double.isInfinite(L2.m)) {
  		       x=L2.P1.x;
			    y=L1.m*x + L1.n;
			  }
		  }
		}
		else System.out.println("le linee sono parallele");
	}

// punto di intersezione tra due linee definite dalle intersezioni
// com gli assi cartesioni
	Punto(double m1, double n1, double m2, double n2) {
		Punto p = new Punto(new Linea(m1, n1), new Linea (m2, n2));
		x = p.x;
		y = p.y;
	}

// punto polare rispetto ad un punto dato	
  Punto(Punto P, double ro, double teta) {
		x=P.x + ro*Math.cos(teta);
		y=P.y + ro*Math.sin(teta);
	}

// ritorna il punto di coordinate polari ro, teta relativo al punto in corso
  Punto polare(double ro, double teta) {
		return new Punto(new Punto(x, y), ro, teta);
	}

// ritorna il punto di coordinate x,y relative al punto in corso
  Punto relativo(double xr, double yr) {
		return new Punto(x+xr, y+yr);
	}


// ritorna il perimetro del triangolo costituito dal punto in corso ed altri due punti	
	double perimetro(Punto Pb, Punto Pc) {
	  return new Linea(this, Pb).lunghezza() + new Linea(Pb, Pc).lunghezza() + new Linea(Pc, this).lunghezza();
	}

// ritorna l'area del triangolo costituito dal punto in corso ed altri due punti applicando la formula di Erone
	double area(Punto Pb, Punto Pc) {
// calcola il semiperimetro (perimetro/2)	  
	  double p=perimetro(Pb, Pc)/2;
	  return Math.sqrt(p*(p- new Linea(this, Pb).lunghezza())*(p- new Linea(Pb, Pc).lunghezza())*(p- new Linea(Pc, this).lunghezza()));
	}

// Verifica se il punto in corso e' interno ad un triangolo
	boolean interno(Punto Pa, Punto Pb, Punto Pc) {
    return (Math.abs(area(Pa, Pb) + area(Pb, Pc) + area(Pc, Pa) - Pa.area(Pb, Pc)) < .0000001);
  }

// Verifica se il punto in corso e' interno ad una circonferenza data
	boolean interno(Circonferenza C) {
    return new Linea(C.centro, this).lunghezza() < C.raggio;
  }

// sposta il punto in corso parallelamente allo spostamento Porig-Pdest
	void sposta(Punto Porig, Punto Pdest) {
		Linea lPoPd = new Linea(Porig, Pdest);
		x = x + lPoPd.deltaX();
		y = y + lPoPd.deltaY();
	}

// ruota di un anglo specificato il punto in corso intorno ad un punto specificato
  void ruota(Punto Prot, double alfa) {
    double s=Math.sin(alfa), c=Math.cos(alfa);
    Linea Cp =new Linea(new Punto(0,0), Prot);
    double xo=x - Cp.deltaX();
    double yo=y - Cp.deltaY();
    double X = xo * c - yo * s;
    double Y = xo * s + yo * c;
    x=X+Cp.deltaX();
    y=Y+Cp.deltaY();
  }

// disegna il punto  
	void disegna(Color colore, Graphics g) {
		g.setColor(colore);
		g.drawLine((int) x, (int) y, (int) x, (int) y);
	}

}

class Linea extends entita{
	Punto P1, P2;
	double m, n;

// linea tra due punti
  Linea(Punto P1, Punto P2) {
		this.P1=P1;
		this.P2=P2;
	  m=deltaY()/deltaX();
	  n=-m*P1.x + P1.y;
	}

// assi cartesiani  
  Linea(String asse) {
    if (asse.equals("ASSEX")) {
      P1=new Punto();
      P2=P1.relativo(1,0);
      m=0;n=0;
    }
    if (asse.equals("ASSEY")) {
      P1=new Punto();
      P2=P1.relativo(1, Math.PI/2);
      m=Math.PI/2; n=0;
    }
  }

//linea	definita secondo le intersezioni con gli assi cartesiano
	Linea(double m, double n) {
		this.m=m;
		this.n=n;
		P1=new Punto(0, n);
	  if (!Double.isInfinite(m)) P2=new Punto(-n/m, 0);
		if (m==0) P2=new Punto(1, n);
	}

// linea bisettrice dell'angolo tra due linee
  Linea(Linea l1, Linea l2, boolean unodeidue) {
    P1= new Punto(l1, l2);
    Circonferenza Ci= new Circonferenza(P1, 50);
    duePunti dp1= new duePunti(l1, Ci);
    duePunti dp2= new duePunti(l2, Ci);
    Linea La=new Linea(dp1.P1, dp2.P1);
    Linea Lb=new Linea(dp1.P1, dp2.P2);
    if (unodeidue) P2=Lb.medio(); else P2=La.medio();
    m=deltaY()/deltaX();
	  n=-m*P1.x + P1.y;
  }


// differenza delle ascisse degli estremi
	double deltaX() {
		return P2.x - P1.x;
	}

// differenza delle oordinate degli estremi	
	double deltaY() {
		return P2.y - P1.y;
	}

// angoolo in radianti nel pianoo XY rispetto oall'asse delle ascisse X
	double angoloXY() {
		double ang=0;
		if ((deltaX()<0) && (deltaY()<0)) ang= Math.atan(m)+Math.PI;
		if ((deltaX()<0) && (deltaY()>=0)) ang= Math.atan(m)+Math.PI;
		if ((deltaX()>=0) && (deltaY()<0)) ang= 2*Math.PI+Math.atan(m);
		if ((deltaX()>=0) && (deltaY()>=0)) ang= Math.atan(m);
		return ang;
	}

// distanza tra i punti estremi o lunghezza della linea
	double lunghezza() {
		return Math.sqrt(Math.pow(deltaX(), 2) + Math.pow(deltaY(), 2));
	}

// punto medio della linea
	Punto medio() {
		return new Punto((P1.x + P2.x)/2, (P1.y + P2.y)/2);
	}

// limea perpendicolare alla linea in corso passante per un punto P
	Linea perp(Punto p) {
		double x, y, m2, n2;		
		if (!Double.isInfinite(m) && (m!=0)) {
		  m2 = -1/m;
		  n2 =	-m2*p.x + p.y;
	      x = (n2 - n) / (m - m2);
          y = m2 * x + n2;
  	      Linea lperp = new Linea(p, new Punto(x, y));
  		  lperp.m = m2;
  		  lperp.n = n2;
		  return lperp;
		}
		else {
	    if (Double.isInfinite(m)) {
			  x = P1.x;
        y = p.y;
        Linea lperp = new Linea(p, new Punto(x, y));
				if (lperp.P1==lperp.P2) lperp = new Linea(lperp.P1, new Punto(lperp.P1.x+1, lperp.P1.y));
  		  lperp.m = 0;
  		  lperp.n = p.y;
				return lperp;
			}
			else { // (m==0)
			  x = p.x;
        y = P1.y;
        Linea lperp = new Linea(p, new Punto(x, y));
  		  lperp.m = Double.POSITIVE_INFINITY;
  		  lperp.n = Double.POSITIVE_INFINITY;
				return lperp;
			}
		}
	}

// linea parallela alla linea in corso passante per il punto P  
	Linea parallela(Punto p) {
		if (!Double.isInfinite(m)) return new Linea(m, -m*p.x + p.y);
		else return new Linea(new Punto(p.x, p.y), new Punto(p.x, P1.y));
	}

// proiezione di una linea esterna sulla linea in corso
	Linea proiezione(Linea l) {
		Punto Pl1= new Punto(new Linea(P1, P2), perp(l.P1));
		Punto Pl2= new Punto(new Linea(P1, P2), perp(l.P2));
		return new Linea(Pl1, Pl2);
	}

// angolo tra la linea in corso e un'altra linea  
  double angolo(Linea l, boolean unodeidue) {
    double ang= Math.abs(angoloXY()-l.angoloXY());
    ang = ang - ((int) (ang/Math.PI))*Math.PI;
    if (unodeidue) return ang; else return Math.abs(Math.PI-ang);
  }
    
// circonferenza tangente alla linea in corso con centro in un punto qualsiasi
	Circonferenza tangente(Punto centro) {
		return new Circonferenza(centro, perp(centro).lunghezza());
	}

// sposta la liena parallelamente allo spoostamento Porig - Pdest
	void sposta(Punto Porig, Punto Pdest) {
    P1.sposta(Porig, Pdest);
		P2.sposta(Porig, Pdest);
	}

// ruota di un anglo specificato la linea intorno ad un punto
	void ruota(Punto Prot, double alfa) {
    P1.ruota(Prot, alfa);
    P2.ruota(Prot, alfa);
	}

// disegna la linea  
	void disegna(Color colore, Graphics g) {
		g.setColor(colore);
		g.drawLine((int) P1.x, (int) P1.y, (int) P2.x, (int) P2.y);
	}
	
}


class Circonferenza extends entita {
	Punto centro;
	double raggio;

// circonferenza con centro e raggio noti	
  Circonferenza(Punto centro, double raggio) {
		this.centro=centro;
		this.raggio=raggio;
	}

// circonferenza passante per tre punti noti
	Circonferenza(Punto Pa, Punto Pb, Punto Pc) {
		Linea Lba =new Linea(Pb, Pa);
		Linea Lbc =new Linea(Pb, Pc);
		Linea asLba=Lba.perp(Lba.medio());
		Linea asLbc=Lbc.perp(Lbc.medio());
		if (asLba.m != asLbc.m) {
		  centro =new Punto(asLba, asLbc);
		  raggio =new Linea(centro, Pa).lunghezza();
		}
		else System.out.println("i punti sono allinati");
	}

// circonferenza tangente a due linee con raggio noto
// unodeidue1 regola quale dei due angoli e quindi anche bisettrice bisogna cosiderare
// unodeidue2 indica quale coppia dei sue punti possibili sara' il centro
  Circonferenza(Linea L1, Linea L2, double raggio, boolean unodeidue1, boolean unodeidue2) {
    double alfa = L1.angolo(L2, unodeidue1);
    System.out.println(alfa*180/Math.PI);
    Punto pint= new Punto(L1, L2);
    Circonferenza c= new Circonferenza(pint, raggio/Math.sin(alfa/2));
    duePunti dp= new duePunti(new Linea(L1, L2, unodeidue1), c);
    if (unodeidue2) {
      centro=dp.P1;
    }
     else {
      centro=dp.P2;
    }
    this.raggio=raggio;
   }

// area della circonferenza	
  double area() {
		return Math.PI*raggio*raggio;
	}

// perimetro della corconferenza
	double perimetro() {
		return 2*Math.PI*raggio;
	}

// punti di tangenza da un punto esterno alla circonferenza in corso
	duePunti tangente(Punto p) {
		double pc = new Linea(p, centro).lunghezza();
		double lunLtan = Math.sqrt(pc*pc - raggio*raggio);
		return new duePunti(new Circonferenza(p, lunLtan), this);
	}

// sposta la circonferenza parallelamente allo spostamento Porig - Pdest
	void sposta(Punto Porig, Punto Pdest) {
		centro.sposta(Porig, Pdest);
	}

// ruota di un anglo specificato la circonferenza intorno ad un punto
	void ruota(Punto Prot, double alfa) {
		centro.ruota(Prot, alfa);
	} 

// disegna la circonferenza
	void disegna(Color colore, Graphics g)	{
		newGraphics ng = new newGraphics(g);
		g.setColor(colore);
		ng.disCirconf(centro.x, centro.y, raggio);
	}

}

class Arco extends entita {
	Punto centro;
	double raggio;
	Punto P1, P2;
	double ainz, afin;

// arco con punti inziale e finale, raggio noti
// gli archi possibili sono due e il parametro unodeidue permette la definizione dell'uno l'altro
  Arco(Punto P1, Punto P2, double raggio, boolean unodeidue) {
		this.P1=P1;
		this.P2=P2;
		this.raggio=raggio;
    duePunti C2p=new duePunti(new Circonferenza(P1, raggio), new Circonferenza(P2, raggio));
		if (unodeidue) centro=C2p.P1; else centro=C2p.P2;
    ainz =new Linea(centro, P1).angoloXY();
		afin =new Linea(centro, P2).angoloXY();
	}

// arco noto per i punti iniziale e finale e angolo compreso dall'arco
	Arco(double acomp, Punto P1, Punto P2, boolean unodeidue) {
		this.P1=P1;
		this.P2=P2;
		double corda = (new Linea(P1, P2)).lunghezza();
    raggio=corda/2/Math.sin(acomp/2);
    duePunti C2p= new duePunti(new Circonferenza(P1, raggio), new Circonferenza(P2, raggio));
    if (unodeidue) centro=C2p.P1; else centro=C2p.P2;
    ainz =new Linea(centro, P1).angoloXY();
		afin =new Linea(centro, P2).angoloXY();
	}

// arco noto per punti iniziale e finale e uno qualsiasi
	Arco(Punto P1, Punto Pi, Punto P2) {
		this.P1=P1;
		this.P2=P2;
		Circonferenza C=new Circonferenza(P1, Pi, P2);
		centro=C.centro;
		raggio=C.raggio;
		ainz =new Linea(C.centro, P1).angoloXY();
		afin =new Linea(C.centro, P2).angoloXY();
	}

// archi di raccordo tra due linee
// unodeidue1 indica quale angolo dei due possibili tra L1 e L2 bisogna considerare
// unodeidue2 indica ....DA COMPLETARE  
  Arco(Linea L1, Linea L2, double raggio, boolean unodeidue1, boolean unodeidue2) {
    double alfa = L1.angolo(L2, unodeidue1);
    Punto pint= new Punto(L1, L2);
    Circonferenza c= new Circonferenza(pint, raggio/Math.abs(Math.sin(alfa/2)));
    duePunti dp= new duePunti(new Linea(L1, L2, unodeidue1), c);
    duePunti dpa1 = (new Circonferenza(dp.P1, raggio)).tangente(pint);
    duePunti dpa2 = (new Circonferenza(dp.P2, raggio)).tangente(pint);
    if (unodeidue2) {
      P1=dpa1.P1;
      P2=dpa1.P2;
      centro=dp.P1;
    }
     else {
      P1=dpa2.P1;
      P2=dpa2.P2;
      centro=dp.P2;
    }
    this.raggio=raggio;
		ainz =new Linea(centro, P1).angoloXY();
		afin =new Linea(centro, P2).angoloXY();
 
  }

// punto medio dell'arco
  duePunti medi() {
    return new duePunti((new Linea(P1, P2)).perp(centro), new Circonferenza(centro, raggio));
  }

// area del settore circolare	
  double area() {
		return Math.PI*raggio*raggio*Math.abs(afin-ainz);
	}

// Lunghezza dell'arco o di quello complementare in dipendenza da unodeidue
	double lunghezza(boolean unodeidue) {
    double al= raggio*Math.abs(afin-ainz);
    double alc = 2*Math.PI*raggio - al;
// se l'angolo di al e' > 2PI allora scambia con alc cosi' al sara' sempre l'angolo minore
// dunque facilmente rilevabile con true passato come unodeidue    
    if (al/raggio > 2*Math.PI) {
      double temp=al;
      al=alc;
      alc=temp;
    }
    
    if (unodeidue) return al; else return alc; 
	}

// punti di tangenza da un punto esterno alla circonferenza in corso
	duePunti tangente(Punto p) {
		double pc = new Linea(p, centro).lunghezza();
		double lunLtan = Math.sqrt(pc*pc - raggio*raggio);
		return new duePunti(new Circonferenza(p, lunLtan), new Circonferenza(centro, raggio));
	}

// sposta l'arco parallelamente allo spostamento Porig - Pdest
	void sposta(Punto Porig, Punto Pdest) {
		centro.sposta(Porig, Pdest);
	}

// ruota di un angolo specificato l'arco intorno ad un punto
	void ruota(Punto Prot, double alfa) {
		centro.ruota(Prot, alfa);
	} 

// disegna l'arco
	void disegna(Color colore, Graphics g)	{
		newGraphics ng = new newGraphics(g);
		g.setColor(colore);
    ng.disArco(centro.x, centro.y, raggio, ainz, afin);
	}

}

class duePunti extends entita{
  Punto P1, P2;

// i due punti di intersezione tra una circonferenza ed una linea
	duePunti(Linea L, Circonferenza C) {
    double gam=C.centro.x*C.centro.x + C.centro.y*C.centro.y - C.raggio*C.raggio;
		double a, b, c;

    if (Double.isInfinite(Math.abs(L.m))) {
	  	a=1;
	  	b=-2*C.centro.y;
      c=L.P1.x*L.P1.x - 2*C.centro.x*L.P1.x + gam;
      eq2grado sol=new eq2grado(a, b, c);
   	  P1=new Punto(L.P1.x, sol.s[0]);
	 	  P2=new Punto(L.P1.x, sol.s[1]);
    }
     else {
   		a=1 + L.m*L.m;
  		b=2*(L.m*L.n - C.centro.x - C.centro.y*L.m);
  		c=L.n*L.n - 2*C.centro.y*L.n + gam;
      eq2grado sol=new eq2grado(a, b, c);
   	  P1=new Punto(sol.s[0], L.m*sol.s[0] + L.n);
	 	  P2=new Punto(sol.s[1], L.m*sol.s[1] + L.n);
    }
	}

// i due punti di intersezione tra due circonferenze
	duePunti(Circonferenza C1, Circonferenza C2) {
		double gam1=C1.centro.x*C1.centro.x + C1.centro.y*C1.centro.y - C1.raggio*C1.raggio;
		double gam2=C2.centro.x*C2.centro.x + C2.centro.y*C2.centro.y - C2.raggio*C2.raggio;
		double a=2*(C2.centro.x - C1.centro.x);
		double b=2*(C2.centro.y - C1.centro.y);
		double c=gam1 - gam2;
		Linea asrad= new Linea(-a/b, -c/b);
// assicura all'asse radicale asrad un punto reale (medio della congiungente i centri)
    asrad.P1 = (new Linea(C1.centro, C2.centro)).medio();
    duePunti sec =new duePunti(asrad, C1);
		P1=sec.P1;
		P2=sec.P2;
	}

// converte l'oggetto duePunti in una Linea	
  Linea linea() {
		return new Linea(P1, P2);
	}
}
            
class gruppo extends entita {
  Vector v=new Vector();
  Color colore;

// definisce un gruppo di entita' con specifica di colore
  gruppo(Color colore) {
    this.colore=colore;
  }

// definisce un gruppo di entita' con colore standard black
  gruppo() {
  }

// aggiunge un'entita' al gruppo
  void aggiungi(entita e) {
    v.addElement(e);
  }

// sposta il gruppo parallelamente allo spostamento Porig - Pdest 	
  void sposta(Punto Porig, Punto Pdest) {
    for (int i=0; i<v.size(); i++) {
       ((entita) v.elementAt(i)).sposta(Porig, Pdest);
    }  
	}

// ruota di un angolo specificato il gruppo intorno ad un punto
	void ruota(Punto Prot, double alfa) {
    for (int i=0; i<v.size(); i++) {
       ((entita) v.elementAt(i)).ruota(Prot, alfa);
    }  
	} 

// disegna l'intero gruppo di entita'
  void disegna(Color colore, Graphics g) {
    for (int i=0; i<v.size(); i++) {
      ((entita) v.elementAt(i)).disegna(colore, g);   
    }
    v.removeAllElements();
  }
  
  void disegna(Graphics g) {
    disegna(colore, g);
  }

}

class Poligono extends entita {
	Punto centro=new Punto();
	double raggio, lato, rot;
  int numLati;


// poligono con centro, raggio e numero lati noti	inscritto
  Poligono(Punto centro, double raggio, int numLati) {
    this.centro=centro;
	this.raggio=raggio;
    lato=2*raggio*Math.sin(4*Math.PI/numLati);
    this.numLati=numLati;
    rot=0;
	}

// poligono inscritto nella circonferenza passante per tre punti noti e noti il
// numero di lati
	Poligono(Punto Pa, Punto Pb, Punto Pc, int numLati) {
		Linea Lba =new Linea(Pb, Pa);
		Linea Lbc =new Linea(Pb, Pc);
		Linea asLba=Lba.perp(Lba.medio());
		Linea asLbc=Lbc.perp(Lbc.medio());
		if (asLba.m != asLbc.m) {
		  centro =new Punto(asLba, asLbc);
		  raggio =new Linea(centro, Pa).lunghezza();
      this.numLati=numLati;
      lato=2*raggio*Math.sin(4*Math.PI/numLati);
      rot=0;
		}
		else System.out.println("i punti sono allinati");
	}

// poligono con noti solo i punti estremi di un lato e il numero dei lati
  Poligono(Punto P1, Punto P2, int numLati, boolean unodeidue) {
    this.numLati =numLati;
    lato =new Linea(P1, P2).lunghezza();
    raggio =lato/(2*Math.sin(Math.PI/numLati));
    Circonferenza C1 =new Circonferenza(P1, raggio);
    Circonferenza C2 =new Circonferenza(P2, raggio);
    duePunti centri =new duePunti(C1, C2);
    if (!unodeidue) {
      centro = centri.P1;
      rot =new Linea(centro, P1).angoloXY();
    }
     else {
      centro = centri.P2;
      rot =new Linea(centro, P2).angoloXY();
    }
  }

// area delpoligono	
  double area() {
		return perimetro()*apotema()/2;
	}

// perimetro del poligono
	double perimetro() {
		return lato*numLati;
	}

// apotema del poligono
  double apotema() {
    return Math.sqrt(raggio*raggio - lato*lato/4);
  }

// poligono parallelo ad una distanza nota dai lati del poligono in corso
  Poligono parallelo(double d) {
    Poligono plgpar = new Poligono(centro, (apotema()+d)*raggio/apotema(), numLati);
    plgpar.rot=rot;
    return plgpar;
  }

// poligono cirscoscritto al cerchio in cui il poligono corrente e' inscritto
  Poligono circoscritto() {
    return parallelo(raggio - apotema());
  }

// sposta il poligono parallelamente allo spostamento Porig - Pdest
	void sposta(Punto Porig, Punto Pdest) {
		centro.sposta(Porig, Pdest);
	}

// ruota di un anglo specificato il poligono intorno ad un punto
	void ruota(Punto Prot, double alfa) {
		centro.ruota(Prot, alfa);
	} 

// disegna il poligono
	void disegna(Color colore, Graphics g)	{
		newGraphics ng = new newGraphics(g);
		g.setColor(colore);
	  ng.disPoligonoR(centro.x, centro.y, raggio, numLati, rot);
	}

}

// classe generica utile al ragruppamento delle entita' primitive
abstract class entita {
  
  entita() {}

	void sposta(Punto Porig, Punto Pdest) {}
  void ruota(Punto Prot, double alfa) {}
  void disegna(Color colore, Graphics g) {}
}


