/*******************************************************************************
+
+  LEDA 3.5
+
+  polygon.h
+
+  This file is part of the LEDA research version (LEDA-R) that can be 
+  used free of charge in academic research and teaching. Any commercial
+  use of this software requires a license which is distributed by the
+  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
+  (fax +49 681 31104).
+
+  Copyright (c) 1991-1997  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 66123 Saarbruecken, Germany     
+  All rights reserved.
+ 
*******************************************************************************/
#ifndef LEDA_POLYGON_H
#define LEDA_POLYGON_H

#if !defined(LEDA_ROOT_INCL_ID)
#define LEDA_ROOT_INCL_ID 350098
#include <LEDA/REDEFINE_NAMES.h>
#endif

#include <LEDA/point.h>
#include <LEDA/segment.h>
#include <LEDA/line.h>


class polygon_rep : public handle_rep {

friend class polygon;

  list<point>   pt_list;
  list<segment> seg_list;

public:

  polygon_rep() {}
  polygon_rep(const list<segment>&);
 ~polygon_rep() {}
   
};


/*{\Manpage {polygon} {} {Polygons} }*/

class list_polygon_;

class polygon   : public handle_base 
{
/*{\Mdefinition
An instance $P$ of the data type $polygon$ is a simple polygon
in the two-dimensional plane defined by the sequence of its vertices. 
The number of vertices is called the size
of $P$. A polygon with empty vertex sequence is called empty.}*/

polygon_rep* ptr() const { return (polygon_rep*)PTR; }

polygon(const list<segment>& sl);

double compute_area(const list<segment>&) const;

public:

/*{\Mcreation P }*/

polygon(const list<point>& pl);
/*{\Mcreate 
introduces a variable |\Mvar| of type |\Mname|. |\Mvar| is initialized to the
polygon with vertex sequence $pl$.\\
\precond The vertices in $pl$ define a simple polygon.}*/

polygon() { PTR = new polygon_rep; }
/*{\Mcreate 
introduces a variable |\Mvar| of type |\Mname|. |\Mvar| is initialized to the
empty polygon.}*/


 polygon(const polygon& P) : handle_base(P) {}
~polygon() {}
 polygon& operator=(const polygon& P) 
 { handle_base::operator=(P); return *this;}


/*{\Moperations 2.5 4.6}*/

polygon     to_polygon() const;
/*{\Xop  for compatibility with |rat_polgyon|. }*/

const list<point>&   vertices() const  { return ptr()->pt_list; } 
/*{\Mop     returns the sequence of vertices of |\Mvar| in 
            counterclockwise ordering.  }*/

/*{\Moptions nextwarning=no}*/
const list<segment>& segments() const { return ptr()->seg_list; }
const list<segment>& edges() const { return ptr()->seg_list; }
/*{\Mop     returns the sequence of bounding segments 
	    of |\Mvar| in counterclockwise ordering. }*/

list<point> intersection(const segment& s) const;
/*{\Mopl    returns $P \cap s$ as a list of points.}*/

list<point> intersection(const line& l) const;
/*{\Mopl    returns $P \cap l$ as a list of points.}*/

/*{\Moptions nextwarning=no}*/
list_polygon_ unite(const polygon& Q) const;
/*
list<polygon> unite(const polygon& Q) const;
*/
/*{\Mopl    returns $P \cup Q$ as a list of polygons. The first polygon
            in the list gives the outer boundary of the contour of the union.
            Possibly following polygons define the inner boundaries (holes) 
            of the contour (holes). }*/


/*{\Moptions nextwarning=no}*/
list_polygon_ intersection(const polygon& Q) const;
/*
list<polygon> intersection(const polygon& Q) const;
*/
/*{\Mopl    returns $P \cap Q$ as a list of polygons.}*/

bool        inside(const point& p) const;  
/*{\Mop     returns true if $p$ lies inside of |\Mvar| and
	    false otherwise.}*/

bool        outside(const point& p) const { return !inside(p); }
/*{\Mop     returns true if $p$ lies outside of |\Mvar| and
	    false otherwise.}*/

double      area() const { return compute_area(ptr()->seg_list); }
/*{\Mop     returns the area of $P$.}*/


polygon     translate_by_angle(double a, double d) const;
/*{\Mop     returns |\Mvar| translated in direction $a$ by distance $d$.}*/

polygon     translate(double dx, double dy) const;
/*{\Mop     returns |\Mvar| translated by vector $(dx,dy)$.}*/

polygon     translate(const vector& v) const;
/*{\Mop     returns |\Mvar| translated by vector $v$.}*/

polygon operator+(const vector& v) const { return translate(v); }
/*{\Mbinop  returns |\Mvar| translated by vector $v$.}*/

polygon operator-(const vector& v) const { return translate(-v); }
/*{\Mbinop  returns |\Mvar| translated by vector $-v$.}*/


polygon     rotate(const point& q, double a) const;
/*{\Mopl    returns |\Mvar| rotated by angle $a$ about point $q$.}*/

polygon     rotate(double a) const;
/*{\Mopl    returns |\Mvar| rotated by angle $a$ about the origin.}*/

polygon rotate90(const point& q) const;
/*{\Mopl    returns |\Mvar| rotated about $q$ by angle of $90$ degrees.}*/

polygon reflect(const point& p, const point& q) const;
/*{\Mop     returns |\Mvar| reflected  across the straight line passing
            through $p$ and $q$.}*/

polygon reflect(const point& p) const;
/*{\Mop     returns |\Mvar| reflected  across point $p$.}*/


int         size()   const  { return ptr()->seg_list.size(); }
/*{\Mop     returns the size of |\Mvar|.}*/

bool        empty()  const  { return ptr()->seg_list.empty(); }
/*{\Mop     returns true if |\Mvar| is empty, false otherwise.}*/



bool  operator==(const polygon& P1) const;


friend ostream& operator<<(ostream& out, const polygon& p);
friend istream& operator>>(istream& in,  polygon& p);


};



struct list_polygon_: public list<polygon>
{
  list_polygon_(const list<polygon>& L) : list<polygon>(L) {}
  list_polygon_() {}
 ~list_polygon_() {}
};

inline char* leda_tname(const polygon*) { return "polygon"; }


/*{\Mtext
\bigskip
{\bf Iterations Macros}

{\bf forall\_vertices}($v,P$)       
$\{$ ``the vertices of $P$ are successively assigned to point $v$'' $\}$

{\bf forall\_segments}($s,P$)       
$\{$ ``the edges of $P$ are successively assigned to segment $s$'' $\}$ }*/

#define forall_vertices(v,P)  forall(v,P.vertices())
#define forall_segments(s,P)  forall(s,P.segments())


#if LEDA_ROOT_INCL_ID == 350098
#undef LEDA_ROOT_INCL_ID
#include <LEDA/UNDEFINE_NAMES.h>
#endif

#endif 
