/***************************************************************************
 *   Copyright (C) 2004 by Juergen Thies                                   *
 *   layout@juergenthies.de                                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#define _USE_MATH_DEFINES
#include "polygon.h"
#include "elementlist.h"
#include "box.h"
#include "layout.h"
#include "general/setup.h"
#include "polygonproperties.h"
#include "fileformats/dxf.h"
#include "fileformats/oasis.h"
#include "fileformats/cif.h"
#include "fileformats/csv.h"
#include "fileformats/gds.h"
#include "fileformats/gerber.h"
#include "fileformats/svg.h"
#include "general/drawingfield.h"
#include <qcolor.h>
#include <QList>
#include <math.h>
#include "bool/booleanhandler.h"
#include "pointarray.h"
#include "path.h"
#include <QTextStream>
#include "general/drc.h"

#include <math.h>

#include <QPaintEngine>
#include "bool/booleng.h"


polygon::polygon(const pointArray points,const int layer)
 : element(){
layerNum=layer;

pointarray=points;

//pointarray.resize(points.size());
//pointarray.putPoints(0,points.size(),points);
p_select.resize(pointarray.size());

int i;
for (i=0;i<p_select.size();i++){p_select.clearBit(i);}
clean();
}

polygon::polygon(const pointArray points,const qint16 layer,const qint16 datatype_):element()
{
// add polygon with later clean
layerNum=layer;
pointarray=points;
datatype=datatype_;
}


polygon::polygon()
 : element(){
pointarray.resize(0);
p_select.resize(0);
size=0;
}

polygon::~polygon(){}

void polygon::calcSize(){
int i=1;
int xmin,ymin,xmax,ymax;
xmax=xmin=pointarray.point(i).x();
ymax=ymin=pointarray.point(i).y();
for (i=1;i<pointarray.size();i++){
	if (pointarray.point(i).x()>xmax) xmax=pointarray.point(i).x();
	if (pointarray.point(i).y()>ymax) ymax=pointarray.point(i).y();
	if (pointarray.point(i).x()<xmin) xmin=pointarray.point(i).x();
	if (pointarray.point(i).y()<ymin) ymin=pointarray.point(i).y();
	}
size=xmax-xmin;
if (ymax-ymin>size) size=ymax-ymin;
}

void polygon::paint(layoutImagePainter *e){
if (layers::num[layerNum].visible){
	if (size<e->drawPixelSize){
		if (e->detailLevel>3) return;
 		e->drawPixel(pointarray.point(0),layers::layerColor[layerNum]);
		}
	else
	{
       e->drawPolygon(&pointarray,layers::layerColor[layerNum],layers::num[layerNum].brushStyle);
 	}}
}


	
void polygon::paintSelect(layoutImagePainter *e){
  if (layers::num[layerNum].visible){
	if (select){
		if (size<e->drawPixelSize){
 			e->drawPixel(pointarray.point(0),setup::selectColor.rgb());
			}
		else
			e->drawPolygon(&pointarray,setup::selectColor.rgb(),Qt::NoBrush);
		}
	else {
	int i;
	QPoint p;
	for (i=0;i<pointarray.size();i++) 
		if (p_select.testBit(i)){
				e->drawPoint(pointarray.point(i),setup::selectColor.rgb());
				}
	}
  }
}


void polygon::paintSelected(layoutImagePainter *e){
  if (size<e->drawPixelSize){
 	e->drawPixel(pointarray.point(0),setup::selectColor.rgb());
	}
  else
  	e->drawPolygon(&pointarray,setup::selectColor.rgb(),Qt::NoBrush);
}

void polygon::paintNode(int node, layoutImagePainter *e){
	if (layers::num[layerNum].visible)
	if (getNode()==node) paintSelected(e);
}

void polygon::paintHighlighted(QPainter *po,strans trans_ ){
  po->setPen(setup::highlightColor);
  QBrush br=layer::getBrush(setup::highlightBrush);
  br.setColor(setup::highlightColor);
  po->setBrush(br);
  po->drawPolygon(convert(pointarray,trans_));
  //paintHighlightedBackground(po,trans_ );
  
//paintSize(po,trans_,0.001);
}
void polygon::paintHighlighted(QPainter *po,strans trans_,QPoint p_ ) {
  QPoint p;
  int x,y;
  int i;
  for (i=0;i<pointarray.size();i++) {
		if (pointarray.point(i)==p_){
				p=convert(pointarray.point(i),trans_);
				x=p.x();y=p.y();
				po->setPen(setup::highlightColor);
  				QBrush br=layer::getBrush(setup::highlightBrush);
    				br.setColor(setup::highlightColor);
    				po->setBrush(br);
				po->drawLine(x-1,y-1,x+1,y+1);
				po->drawLine(x+1,y-1,x-1,y+1);
				po->drawLine(x,y-5,x,y+5);
				po->drawLine(x-5,y,x+5,y);
				}}

}


void polygon::paintSize(QPainter *po,strans  trans_,double uunits){
}

void polygon::paintDistance(QPainter *po,strans  trans_, double uunits,element *e) {
}


void polygon::paintInfo(QPoint *min,QPoint *max,uint *count)const{
   (*count)++;
    int i;
    QPoint p;
    int num=pointarray.size();
    for (i=0;i<num;i++) {
        p=pointarray.point(i);
        if (p.x()<min->x()) {
            min->setX(p.x());
        }
        if (p.y()<min->y()) {
            min->setY(p.y());
        }
        if (p.x()>max->x()) {
            max->setX(p.x());
        }
        if (p.y()>max->y()) {
            max->setY(p.y());
        }
    }
}

void polygon::fSelect(QRect select_){
if (layers::num[layerNum].visible){
	int i;
	for (i=0;i<pointarray.size();i++) {
		if (pointInRect(pointarray.point(i),select_)) {select=true;clearAllPSelect();};
	}}}
	
void polygon::fDeselect(QRect select_){
if (layers::num[layerNum].visible){
	int i;
	for (i=0;i<pointarray.size();i++) {
		if (pointInRect(pointarray.point(i),select_)) {select=false;clearAllPSelect();};
	}}}


void polygon::fAllDeselect(QRect select_) {
    if (layers::num[layerNum].visible) {
        int i;
	bool b=true;
        for (i=0;i<pointarray.size();i++) {
            if (!pointInRect(pointarray.point(i),select_)) {
                b=false;
                
            };
        }
	if (b) {
		clearAllPSelect();
		select=false;}
	
    }
}

void polygon::fAllSelect(QRect select_) {
    if (layers::num[layerNum].visible) {
        int i;
	bool b=true;
        for (i=0;i<pointarray.size();i++) {
            if (!pointInRect(pointarray.point(i),select_)) {
                b=false;
                
            };
        }
	if (b) {
		clearAllPSelect();
		select=true;}
	
    }
}
	
void polygon::pSelect(QRect select_){
if (layers::num[layerNum].visible){
	int i;
	if (select){setAllPSelect();select=false;}
	for (i=0;i<pointarray.size();i++) {
		if (pointInRect(pointarray.point(i),select_)) {p_select.setBit(i);};}
	bool b=true;
	for (i=0;i<p_select.size();i++){b=b&&p_select.testBit(i);}
	if (b){	clearAllPSelect();
		select=true;}}}
		
void polygon::pDeselect(QRect select_){
if (layers::num[layerNum].visible){
	int i;
	if (select){setAllPSelect();select=false;}
	for (i=0;i<pointarray.size();i++) {
		if (pointInRect(pointarray.point(i),select_)) {p_select.clearBit(i);};
	}
	bool b=true;
	for (i=0;i<p_select.size();i++){b=b&&p_select.testBit(i);}
	if (b){	clearAllPSelect();
		select=true;}}}

void polygon::minimum(QPoint *pos){
int i;
QPoint p;
for (i=0;i<pointarray.size();i++){
	p=pointarray.point(i);
	if (p.x()<pos->x()){pos->setX(p.x());}
	if (p.y()<pos->y()){pos->setY(p.y());}}}

void polygon::maximum(QPoint *pos){
int i;
QPoint p;
for (i=0;i<pointarray.size();i++){
	p=pointarray.point(i);
	if (p.x()>pos->x()){pos->setX(p.x());}
	if (p.y()>pos->y()){pos->setY(p.y());}}
}

void polygon::minimumSelect(QPoint *pos){
  if (select) minimum(pos);
  else {
  int i;
  QPoint p;
  for (i=0;i<pointarray.size();i++){
    if(p_select.testBit(i)) {
	p=pointarray.point(i);
	if (p.x()<pos->x()){pos->setX(p.x());}
	if (p.y()<pos->y()){pos->setY(p.y());}}
	}
  }
}

void polygon::maximumSelect(QPoint *pos){
if (select) maximum(pos);
else {
int i;
QPoint p;
for (i=0;i<pointarray.size();i++){
   if(p_select.testBit(i)) {
	p=pointarray.point(i);
	if (p.x()>pos->x()){pos->setX(p.x());}
	if (p.y()>pos->y()){pos->setY(p.y());}}
  }}
}

/*
int polygon::minSize(){
int size=1<<30;
//{for (uint i=0; i<pointarray.size();i++){printf("c#%d x %d y %d\n",i,pointarray.point(i).x(),pointarray.point(i).y());}}
for (int i=0;i<pointarray.size()-1;i++) {
  // spitze Winkel
  if (i>1) {
	if (angle(pointarray.point(i-1),pointarray.point(i),pointarray.point(i+1))>90.02) return 1;
	}
  else {
	if (angle(pointarray.point(pointarray.size()-1),pointarray.point(i),pointarray.point(i+1))>90.02) return 1;
	}
  //
  for (int k=0;k<pointarray.size()-1;k++)
   if ((k!=i)&&(k!=i+1))
     if (!((k==0)&&(i+2==pointarray.size()))){
	QPoint h=pointarray.point(i+1)-pointarray.point(i);
	double angle;
	if (h.x()==0)
		if (h.y()>0) angle=90;
		else angle=-90;
	else {
		angle=atan((double)(h.y())/(double)(h.x()))/2/M_PI*360;
		if (h.x()<0) angle-=180;
		}
	QMatrix m(1,0,0,1,0,0);
	m.rotate(-angle);
	QPoint map=m.map(pointarray.point(k)-pointarray.point(i));
	if ((map.y()>=0)
           &&  (map.y()<size)){
		if ((map.x()>1)&&(map.x()<(element::length(h)-1))) {
			size=map.y();
			//printf("in size %d length %f\n",size,length(h));
			}
		else if ((map.x()==0)||(map.x()==1)) {
			int h1=k+1;
			if ( h1 >= pointarray.size()-1) h1=0;
			if (h1!=i) size=map.y();
			else {
				h1=k-1;
				if (h1<0) h1=pointarray.size()-2;
				QPoint h2=m.map(pointarray.point(h1)-pointarray.point(i));
				if (h2.x()>0) size=map.y();
				//printf("0 size %d\n",size);
			}}
		else if ((map.x()<=element::length(h))&&(map.x()>0)) {
			int h1=k-2;
			if ( h1 < 0) h1=pointarray.size()-1-h1;
			if (h1!=i) size=map.y();
			else {
				h1=k+1;
				if ( h1 >= pointarray.size()) h1=1;
				QPoint h2=m.map(pointarray.point(h1)-pointarray.point(i));
				if (h2.x()<element::length(h)) size=map.y();
				//printf("length size %d h2x %d h2y %d\n",size,h2.x(),h2.y());
			}}
	  }
	//printf("i: %d k: %d mx %d my %d angle %f   size: %d\n",i,k,map.x(),map.y(),angle, size);
	}}
//printf("size %d\n",size);
return size;
}*/

bool polygon::drcMinSize(int val,drc *DRC,bool sharpAngles){
}

bool polygon::drcMinDistance(int dis,drc *DRC,element *e){
}



bool polygon::drcEnclosure(int dis,drc *DRC,element *e){
}

bool polygon::drcAngle90(drc *DRC){
bool b=true;
for (int i=1;i<pointarray.size();i++){
	QPoint dif=pointarray.point(i-1)-pointarray.point(i);
	if ((dif.x()!=0)&&(dif.y()!=0)){
		b=false;
		DRC->reportErrorDeg((pointarray.point(i-1)+pointarray.point(i))/2,angle(pointarray.point(i-1),pointarray.point(i)));
		}
	}
return b;
}
bool polygon::drcAngle45(drc *DRC){
bool b=true;
for (int i=1;i<pointarray.size();i++){
	QPoint dif=pointarray.point(i-1)-pointarray.point(i);
	if (dif.x()<0)dif.setX(-dif.x());
	if (dif.y()<0)dif.setY(-dif.y());
	if ((dif.x()!=0)&&(dif.y()!=0)&&(dif.x()!=dif.y())){
		b=false;
		DRC->reportErrorDeg((pointarray.point(i-1)+pointarray.point(i))/2,angle(pointarray.point(i-1),pointarray.point(i)));
		}
	}
return b;
}

bool polygon::drcAngle(double ang,drc *DRC){
bool b=true;
double a=0;
for (int i=(int)pointarray.size()-2;i>=0;i--) {
	if (i!=0) a=angle(pointarray.point(i+1),pointarray.point(i),pointarray.point(i-1));
	else a=angle(pointarray.point(i+1),pointarray.point(i),pointarray.point(pointarray.size()-2));
		if ((a<-ang-0.001)&&(a>-179.999)) {
			b=false;
			DRC->reportErrorDeg(pointarray.point(i),fabs(a));
		}
	}
return b;
}

bool polygon::drcNotch(int length,drc *DRC){
bool b=true;
double a1=angle(pointarray.point(1),pointarray.point(0),pointarray.point(pointarray.size()-2));
double a2=0.0;
for (int i=(int)pointarray.size()-2;i>=0;i--) {
	if (i!=0) a2=angle(pointarray.point(i+1),pointarray.point(i),pointarray.point(i-1));
	else a2=angle(pointarray.point(i+1),pointarray.point(i),pointarray.point(pointarray.size()-2));
	//DRC->reportErrorDeg(pointarray.point(i),a2);
	if ((a2>0.001)&&(a2<179.999)&&(a1>0.001)&&(a1<179.999)) {
		double len=distance(pointarray.point(i+1),pointarray.point(i));
		if (len<length)
			{
			b=false;
			DRC->reportError(pointarray.point(i),pointarray.point(i+1),len);
			
		}
	}
	a1=a2;
}
return b;

}

	
void polygon::clearAllPSelect(){
int i;
for (i=0;i<p_select.size();i++)
   {p_select.clearBit(i);}
}

void polygon::setAllPSelect(){
int i;
for (i=0;i<p_select.size();i++)
   {p_select.setBit(i);}
}

void polygon::invertSelect(){
 if (select) {select=false; return;}
 bool b=false;
 int i;
    for (i=0;i<p_select.size();i++) {
	if (p_select.testBit(i)) {
		p_select.clearBit(i);
		b=true;	
		}
	else {
        	p_select.setBit(i);
	}
    }
 if (!b) {
	clearAllPSelect();
	select=true;
	}
}

void polygon::deleteSelect(){
int i,k;
pointArray pointarray2(pointarray.size());
k=0;
for (i=0;i<pointarray.size();i++) {
	if (!p_select.testBit(i)){pointarray2.setPoint(k,pointarray.point(i));k++;}
	}
if (p_select.testBit(pointarray.size()-1)&&(pointarray.point(0)==pointarray.point(pointarray.size()-1))){
		pointarray2.setPoint(k,pointarray2.point(0));k++;}
pointarray2.resize(k);
pointarray.resize(k);
pointarray=pointarray2;
p_select.resize(k);
clearAllPSelect();
}

void polygon::saveSOURCE( source *o){
}

void polygon::saveGDS(gds *g){
	if ((!setup::gdsMultiXYRecord)&&(pointarray.size()>setup::gdsMaxPoints)){ //8191){
		QString s1;
		s1.setNum(setup::gdsMaxPoints);
		g->error->addItem("Polygon with more than "+s1+" points. Polygon splitted.",3);
		int i;
		long long xcut;
		int ymin,ymax;
		xcut=0;
		ymin=0;
		ymax=0;
		for (i=0;i<pointarray.size();i++){
				xcut+=pointarray.point(i).x();
				if (pointarray.point(i).y()>ymax){ymax=pointarray.point(i).y();}
				if (pointarray.point(i).y()<ymin){ymin=pointarray.point(i).y();}
				}
		polygon p=polygon(this);
		p.selectAll();
		xcut=xcut/pointarray.size();
		//printf("precut %d %d %d\n",xcut,ymin,ymax);
		elementList *el=p.cutSelect(QPoint(xcut,ymin-1),QPoint(xcut,ymax+1));
		//printf("cut\n");
		p.saveGDS(g);
		//printf("fsave\n");
		elementList *f,*e;
		for (f=el;f!=NULL;) {
			if (f->thisElement!=NULL){
				//printf("presave %d\n",f->thisElement->getPoints().size());
			f->thisElement->saveGDS(g);
				//printf("nextsave\n");
			}
			delete f->thisElement;
			e=f;
			f=f->nextElement;
			delete e;
		}
		return;
	}

    QPoint point;
 // polygon (boundery)
    g->write->writeUInt16(4);
    g->write->writeUInt8(8);
    g->write->writeUInt8(0);
//(*g->streamPtr)<<(quint16) 4<<(quint8) 8<<(quint8)0;  //boundery
 //layer
    g->write->writeUInt16(6);
    g->write->writeUInt8(0x0D);
    g->write->writeUInt8(2);
    if (!setup::gdsMapLayer)
    	g->write->writeInt16((qint16)layerNum);
    else
	g->write->writeInt16((qint16)layers::num[layerNum].mapToLayer);
    //datatype
    g->write->writeUInt16(6);
    g->write->writeUInt8(0x0E);
    g->write->writeUInt8(2);
    if (!setup::gdsMapLayer)
    	g->write->writeInt16((qint16)datatype);
    else
	g->write->writeInt16((qint16)layers::num[layerNum].getMapToDatatype(datatype));
//(*g->streamPtr)<<(quint16) 6<<(quint8) 0x0D<<(quint8)2<<(qint16)(layer_nr);  //layer
//(*g->streamPtr)<<(quint16) 6<<(quint8) 0x0E<<(quint8)2<<(qint16)(datatype);  //Datatype
int i=pointarray.size();
if ((!setup::gdsMultiXYRecord)||(i<=setup::gdsMaxPoints)) {
    
    if (i>8191) {
	i=8191;
	g->error->addItem("Polygon with more than 8191 points. Data is lost.",1);
	}
    //xy 
    g->write->writeUInt16(((i*2*4)+4));
    g->write->writeUInt8(0x10);
    g->write->writeUInt8(3);
    
//(*g->streamPtr)<<(quint16) ((i*2*4)+4)<<(quint8) 0x10<<(quint8)3;  //XY
    for (int k=0;k<i;k++){
	point=pointarray.point(k);
	//(*g->streamPtr)<<(qint32)(point.x())<<(qint32)(point.y());	
	g->write->writeInt32((qint32)point.x());g->write->writeInt32((qint32)point.y());
    }
}
else {
  int offset=-1;
  while (offset<i){
	if (offset<0) offset=0;
	int write=i-offset;
	if (write>setup::gdsMaxPoints) write=setup::gdsMaxPoints;
	g->write->writeUInt16(((write*2*4)+4));
	g->write->writeUInt8(0x10);
	g->write->writeUInt8(3);
	
	//(*g->streamPtr)<<(quint16) ((i*2*4)+4)<<(quint8) 0x10<<(quint8)3;  //XY
	for (int k=0;k<write;k++){
		point=pointarray.point(k+offset);
		//(*g->streamPtr)<<(qint32)(point.x())<<(qint32)(point.y());	
		g->write->writeInt32((qint32)point.x());g->write->writeInt32((qint32)point.y());
	}
	offset+=write;
	}
}
	//properties
	saveGDSProperty(g);
// endel
    g->write->writeUInt16(4);
    g->write->writeUInt8(0x11);
    g->write->writeUInt8(0);
//(*g->streamPtr)<<(quint16) 4<<(quint8) 0x11<<(quint8)0;  //endel
    g->count();
}

void polygon::saveSelect(QDataStream *stream){
  if (select){
	save(stream);
  }

}

void polygon::save(QDataStream *stream){
	(*stream)<<(qint8)(2);
	(*stream)<<(qint16)(layerNum);
	(*stream)<<(qint16)(datatype);
	(*stream)<<(qint16)(pointarray.size());
	for (int i=0;i<pointarray.size();i++){
		(*stream)<<(qint32)(pointarray.point(i).x());
		(*stream)<<(qint32)(pointarray.point(i).y());
	}
}

void polygon::saveDXF(dxf *d) {
  if (setup::dxfSaveCircle) {
	QPoint pc;
	int r;
	if (isCircle(&pc, &r)){
	//save as circle
	QString s;
  	d->writeEntry(0,"CIRCLE");
	d->writeEntry(100,"AcDbCircle");
  	d->writeEntry(8,layers::num[layerNum].name);
	d->writeEntry(10,s.setNum(pc.x()*d->df->userunits));
	d->writeEntry(20,s.setNum(pc.y()*d->df->userunits));
	d->writeEntry(40,s.setNum(r*d->df->userunits));
  	return;
	}
  }
// save as polygon
  QString s;
  d->writeEntry(0,"POLYLINE");
  //dxf::writeEntry(st,8,layers::num[layer_nr].name);
  d->writeEntry(100,"AcDb2dPolyline");
  d->writeLayer(layerNum);
  d->writeEntry(66,"   1");
  d->writeEntry(70,"   1");
  d->writeEntry(40,"0.0");
  d->writeEntry(41,"0.0");
  for (int i=0; i<pointarray.size();i++){
	d->writeEntry(0,"VERTEX");
	d->writeEntry(100,"AcDbVertex");
	d->writeEntry(100,"AcDb2dVertex");
	d->writeEntry(8,layers::num[layerNum].name);
	d->writeEntry(10,s.setNum(pointarray.point(i).x()*d->df->userunits));
	d->writeEntry(20,s.setNum(pointarray.point(i).y()*d->df->userunits));
	}
  d->writeEntry(0,"SEQEND");
  //dxf::writeEntry(st,8,layers::num[layer_nr].name);
}

#ifdef USE_3d
void polygon::saveDXF3d(dxf3d*d){
if (select||d->renderAll())
	d->save(layerNum,pointarray);
}
#endif

void polygon::saveSVG(svg *s){
*(s->str)<<"<polygon points=\"";
for (int i=0; i<pointarray.size();i++){
	s->savePos("",pointarray.point(i).x());
	s->savePos("",-pointarray.point(i).y());
	}
*(s->str)<<"\" ";
if (layers::num[layerNum].getStyle()==0){
	s->saveValue("stroke",layers::num[layerNum].pen.color().name());
	s->saveValue("fill","none");
}
else 
	s->saveValue("fill",layers::num[layerNum].pen.color().name());
*(s->str)<<"/>"<<s->endOfLine;
}

void polygon::saveOASIS( oasis *o){
  int oasisDatatype=datatype;
  int oasisLayer=layerNum;
  if (!setup::oasisMapLayer){
	oasisLayer=layers::num[layerNum].mapToLayer;
	oasisDatatype=layers::num[layerNum].getMapToDatatype(datatype);
  }
  o->count();
  if (setup::oasisSaveCircle) {
	QPoint pc;
	int r;
	if (isCircle(&pc, &r)){
		// save as circle
		if (!o->modal.absoluteMode){o->setModalAbsoluteMode();}
  		qint8 info_byte=0;
  		if (oasisLayer!=o->modal.layer) info_byte+=1;
  		if (oasisDatatype!=o->modal.datatype) info_byte+=2;
  		if (pc.x()!=o->modal.geometry_x) info_byte+=16;
  		if (pc.y()!=o->modal.geometry_y) info_byte+=8;
		if (r!=o->modal.circle_radius) info_byte+=32;
  		o->writeUnsignedInteger((uint)27);
  		o->writeRaw(info_byte);
  		if (info_byte&1) {
			o->modal.layer=oasisLayer;
			o->writeUnsignedInteger((uint)o->modal.layer);
			}
  		if (info_byte&2) {
			o->modal.datatype=oasisDatatype;
			o->writeUnsignedInteger((uint)oasisDatatype);
			}
		if (info_byte&32) {
			o->modal.circle_radius=r;
			o->writeUnsignedInteger((uint)o->modal.circle_radius);}
  		if (info_byte&16) {
			o->modal.geometry_x=pc.x();
			o->writeSignedInteger(o->modal.geometry_x);
			}
  		if (info_byte&8) {
			o->modal.geometry_y=pc.y();
			o->writeSignedInteger(o->modal.geometry_y);}
		  saveOASISProperty(o);
		return;

		}
  }
  // check if ctrapezoid
  if ((setup::oasisSaveCtrapezoid)&&((pointarray.size()==4)||(pointarray.size()==5))) {
	int form=0;
	int off=0;
	int w,h;
	for(int i=1;i<pointarray.size();i++){
	QPoint pd=pointarray.point(i)-pointarray.point(i-1);
	if ((pd.x()==pd.y())&&(pd.x()>0)) {form=form*10+9;}
	else if ((pd.x()==pd.y())&&(pd.x()<0)) {form=form*10+1;}
	else if ((pd.x()== -pd.y())&&(pd.x()<0)) {form=form*10+7;}
	else if ((pd.x()== -pd.y())&&(pd.x()>0)) {form=form*10+3;}
	else if ((pd.x()== 0)&&(pd.y()>0)) {form=form*10+8;}
	else if ((pd.x()== 0)&&(pd.y()<0)) {form=form*10+2;}
	else if ((pd.y()== 0)&&(pd.x()>0)) {form=form*10+6;}
	else if ((pd.y()== 0)&&(pd.x()<0)) {form=form*10+4;}
	else form=-1;
	if (form==-1) break;
	}
	if (form!=-1) {
	//printf("form %d\n",form);
	if (pointarray.size()==4){
	switch (form) {
	case 726: off=2; form=672; break;
	case 267: off=1; form=672; break;
	case 429: off=2; form=942; break;
	case 294: off=1; form=942; break;
	case 816: off=2; form=681; break;
	case 168: off=1; form=681; break;
	case 384: off=2; form=438; break;
	case 843: off=1; form=438; break;
	case 167: off=1; form=671; break;
	case 716: off=2; form=671; break;
	case 394: off=1; form=943; break;
	case 439: off=2; form=943; break;
	case 297: off=1; form=972; break;
	case 729: off=2; form=972; break;
	case 381: off=1; form=813; break;
	case 138: off=2; form=813; break;
	}
	switch (form) {
	case 672: o->writeCtrapezoid(oasisLayer,16,pointarray.point(0+off).x(),pointarray.point(0+off).y(), pointarray.point(1+off).x()-pointarray.point(0+off).x(),0,oasisDatatype); return;
	case 942: o->writeCtrapezoid(oasisLayer,17,pointarray.point(0+off).x(),pointarray.point(0+off).y(), pointarray.point(1+off).x()-pointarray.point(0+off).x(),0,oasisDatatype); return;
	case 681: o->writeCtrapezoid(oasisLayer,18,pointarray.point(0+off).x(),pointarray.point(0+off).y(), pointarray.point(1+off).x()-pointarray.point(0+off).x(),0,oasisDatatype); return;
	case 438: w=pointarray.point(0+off).x()-pointarray.point(1+off).x(); o->writeCtrapezoid(oasisLayer,19,pointarray.point(0+off).x()-w,pointarray.point(0+off).y()-w, w,0,oasisDatatype); return;
	case 671: h=(pointarray.point(1+off).x()-pointarray.point(0+off).x())/2; o->writeCtrapezoid(oasisLayer,20,pointarray.point(0+off).x(),pointarray.point(0+off).y(), 0,h,oasisDatatype); return;
	case 943: h=(pointarray.point(1+off).y()-pointarray.point(0+off).y()); o->writeCtrapezoid(oasisLayer,21,pointarray.point(0+off).x()-h,pointarray.point(0+off).y(), 0,h,oasisDatatype); return;
	case 972: w=pointarray.point(1+off).x()-pointarray.point(0+off).x(); o->writeCtrapezoid(oasisLayer,22,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,0,oasisDatatype); return;
	case 813: w=(pointarray.point(1+off).y()-pointarray.point(0+off).y())/2; o->writeCtrapezoid(oasisLayer,23,pointarray.point(0+off).x()-w,pointarray.point(0+off).y(), w,0,oasisDatatype); return;
	}
	}
	else if (pointarray.size()==5){
	switch (form) {
	//type 24
	case 2684: off=1; form=6842; break;
	case 4268: off=2; form=6842; break;
	case 8426: off=3; form=6842; break;
	//type 0
	case 2674: off=1; form=6742; break;
	case 4267: off=2; form=6742; break;
	case 7426: off=3; form=6742; break;
	//type 1
	case 2694: off=1; form=6942; break;
	case 4269: off=2; form=6942; break;
	case 9426: off=3; form=6942; break;
	//type 2
	case 1684: off=1; form=6841; break;
	case 4168: off=2; form=6841; break;
	case 8416: off=3; form=6841; break;
	//type 3
	case 3684: off=1; form=6843; break;
	case 4368: off=2; form=6843; break;
	case 8436: off=3; form=6843; break;
	//type 4
	case 1674: off=1; form=6741; break;
	case 4167: off=2; form=6741; break;
	case 7416: off=3; form=6741; break;
	//type 5
	case 3694: off=1; form=6943; break;
	case 4369: off=2; form=6943; break;
	case 9436: off=3; form=6943; break;
	//type 6
	case 1694: off=1; form=6941; break;
	case 4169: off=2; form=6941; break;
	case 9416: off=3; form=6941; break;
	//type 7
	case 3674: off=1; form=6743; break;
	case 4367: off=2; form=6743; break;
	case 7436: off=3; form=6743; break;
	//type 8
	case 2687: off=1; form=6872; break;
	case 7268: off=2; form=6872; break;
	case 8726: off=3; form=6872; break;
	//type 9
	case 2681: off=1; form=6812; break;
	case 1268: off=2; form=6812; break;
	case 8126: off=3; form=6812; break;
	//type 10
	case 2984: off=1; form=9842; break;
	case 4298: off=2; form=9842; break;
	case 8429: off=3; form=9842; break;
	//type 11
	case 3842: off=1; form=8423; break;
	case 2384: off=2; form=8423; break;
	case 4238: off=3; form=8423; break;
	//type 12
	case 2987: off=1; form=9872; break;
	case 7298: off=2; form=9872; break;
	case 8729: off=3; form=9872; break;
	//type 13
	case 3812: off=1; form=8123; break;
	case 2381: off=2; form=8123; break;
	case 1238: off=3; form=8123; break;
	//type 14
	case 2981: off=1; form=9812; break;
	case 1298: off=2; form=9812; break;
	case 8129: off=3; form=9812; break;
	//type 15
	case 3872: off=1; form=8723; break;
	case 2387: off=2; form=8723; break;
	case 7238: off=3; form=8723; break;

	}
	switch (form) {
	case 6842: 
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x();
		if (off==3) h=pointarray.point(1).y()-pointarray.point(2).y();
		else h=pointarray.point(2+off).y()-pointarray.point(1+off).y();
		if (h==w) o->writeCtrapezoid(oasisLayer,25,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,0,oasisDatatype);
		else o->writeCtrapezoid(oasisLayer,24,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype); 
		saveOASISProperty(o);
		return;
	case 6742: 
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x();
		if (off==0) h=pointarray.point(2).y()-pointarray.point(1).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		o->writeCtrapezoid(oasisLayer,0,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 6942: 
		if (off==0) h=pointarray.point(2).y()-pointarray.point(1).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x()+h;
		o->writeCtrapezoid(oasisLayer,1,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 6841: 
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x();
		if (off==0) h=pointarray.point(2).y()-pointarray.point(1).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		o->writeCtrapezoid(oasisLayer,2,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 6843: 
		if (off==0) h=pointarray.point(2).y()-pointarray.point(1).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x()+h;
		o->writeCtrapezoid(oasisLayer,3,pointarray.point(0+off).x()-h,pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 6741: 
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x();
		if (off==0) h=pointarray.point(2).y()-pointarray.point(1).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		o->writeCtrapezoid(oasisLayer,4,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 6943: 
		if (off==0) h=pointarray.point(2).y()-pointarray.point(1).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x()+h+h;
		o->writeCtrapezoid(oasisLayer,5,pointarray.point(0+off).x()-h,pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 6941: 
		if (off==0) h=pointarray.point(2).y()-pointarray.point(1).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x()+h;
		o->writeCtrapezoid(oasisLayer,6,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 6743: 
		if (off==0) h=pointarray.point(2).y()-pointarray.point(1).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x()+h;
		o->writeCtrapezoid(oasisLayer,7,pointarray.point(0+off).x()-h,pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 6872: 
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x();
		if (off==0) h=pointarray.point(3).y()-pointarray.point(0).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		o->writeCtrapezoid(oasisLayer,8,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 6812: 
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x();
		if (off==0) h=pointarray.point(2).y()-pointarray.point(0).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y()+w;
		o->writeCtrapezoid(oasisLayer,9,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 9842: 
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x();
		if (off==0) h=pointarray.point(3).y()-pointarray.point(0).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		o->writeCtrapezoid(oasisLayer,10,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 8423: 
		h=pointarray.point(1+off).y()-pointarray.point(0+off).y();
		if (off==0) w=pointarray.point(0).x()-pointarray.point(2).x();
		else w=pointarray.point(0+off).x()-pointarray.point(-1+off).x();
		o->writeCtrapezoid(oasisLayer,11,pointarray.point(0+off).x()-w,pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 9872: 
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x();
		if (off==0) h=pointarray.point(3).y()-pointarray.point(0).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y();
		o->writeCtrapezoid(oasisLayer,12,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 8123: 
		h=pointarray.point(1+off).y()-pointarray.point(0+off).y();
		if (off==0) w=pointarray.point(0).x()-pointarray.point(2).x();
		else w=pointarray.point(0+off).x()-pointarray.point(-1+off).x();
		o->writeCtrapezoid(oasisLayer,13,pointarray.point(0+off).x()-w,pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 9812: 
		w=pointarray.point(1+off).x()-pointarray.point(0+off).x();
		if (off==0) h=pointarray.point(2).y()-pointarray.point(0).y();
		else h=pointarray.point(-1+off).y()-pointarray.point(0+off).y()+w;
		o->writeCtrapezoid(oasisLayer,14,pointarray.point(0+off).x(),pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 8723: 
		if (off==0) w=pointarray.point(0).x()-pointarray.point(2).x();
		else w=pointarray.point(0+off).x()-pointarray.point(-1+off).x();
		h=pointarray.point(1+off).y()-pointarray.point(0+off).y()+w;
		o->writeCtrapezoid(oasisLayer,15,pointarray.point(0+off).x()-w,pointarray.point(0+off).y(), w,h,oasisDatatype);
		saveOASISProperty(o);
		return;
	}
	}}
  }
   //trapezoid
  if ((setup::oasisSaveTrapezoid)&&(pointarray.size()==5)) {
	int form=0;
	int minX,minY,maxX,maxY;
	int w,h,da,db;
	minX=pointarray.point(0).x();
	maxX=pointarray.point(0).x();
	minY=pointarray.point(0).y();
	maxY=pointarray.point(0).y();
	for(int i=1;i<pointarray.size();i++){
		if (pointarray.point(i).x()>maxX) maxX=pointarray.point(i).x();
		if (pointarray.point(i).y()>maxY) maxY=pointarray.point(i).y();
		if (pointarray.point(i).x()<minX) minX=pointarray.point(i).x();
		if (pointarray.point(i).y()<minY) minY=pointarray.point(i).y();
	  	QPoint pd=pointarray.point(i)-pointarray.point(i-1);
		if (pd.x()==0) form=form*10+1;
		else if (pd.y()==0) form=form*10+2;
		else form=form*10;
	}
	w=maxX-minX;
	h=maxY-minY;
	//printf("form%d\n",form);
	switch (form) {
	case 1010:
	case 1210:
	case 1012:
		if (pointarray.point(0).x()<pointarray.point(2).x()){
			da=pointarray.point(3).y()-pointarray.point(0).y();
			db=pointarray.point(2).y()-pointarray.point(1).y();
		} 
		else {
			db=pointarray.point(0).y()-pointarray.point(3).y();
			da=pointarray.point(1).y()-pointarray.point(2).y();
		}
		o->writeTrapezoid(oasisLayer, 1,minX,minY,w,h, -db,-da,oasisDatatype);
		//printf("minX %d, maxX %d, minY %d, maxY %d, w %d, h %d, da %d, db %d\n",minX,maxX,minY,maxY,w,h,da,db);
		saveOASISProperty(o);
		return;
	case 101:
	case 121:
	case 2101:
		if (pointarray.point(1).x()<pointarray.point(3).x()){
			da=pointarray.point(0).y()-pointarray.point(1).y();
			db=pointarray.point(3).y()-pointarray.point(2).y();
		} 
		else {
			db=pointarray.point(1).y()-pointarray.point(4).y();
			da=pointarray.point(2).y()-pointarray.point(3).y();
		}
		o->writeTrapezoid(oasisLayer, 1,minX,minY,w,h, -db,-da,oasisDatatype);
		//printf("minX %d, maxX %d, minY %d, maxY %d, w %d, h %d, da %d, db %d\n",minX,maxX,minY,maxY,w,h,da,db);
		saveOASISProperty(o);
		return;
	case 2020:
	case 2120:
	case 2021:
		if (pointarray.point(0).y()<pointarray.point(2).y()){
			da=pointarray.point(0).x()-pointarray.point(3).x();
			db=pointarray.point(1).x()-pointarray.point(2).x();
		} 
		else {
			db=-pointarray.point(0).x()+pointarray.point(3).x();
			da=-pointarray.point(1).x()+pointarray.point(2).x();
		}
		o->writeTrapezoid(oasisLayer, 0,minX,minY,w,h, -da,-db,oasisDatatype);
		saveOASISProperty(o);
		return;
	case 202:
	case 1202:
	case 212:
		if (pointarray.point(1).y()<pointarray.point(3).y()){
			da=pointarray.point(1).x()-pointarray.point(4).x();
			db=pointarray.point(2).x()-pointarray.point(3).x();
		} 
		else {
			db=-pointarray.point(1).x()+pointarray.point(4).x();
			da=-pointarray.point(2).x()+pointarray.point(3).x();
		}
		o->writeTrapezoid(oasisLayer, 0,minX,minY,w,h, -da,-db,oasisDatatype);
		saveOASISProperty(o);
		return;
	}
  }
  // save as polygon
  if (!o->modal.absoluteMode){o->setModalAbsoluteMode();}
  qint8 info_byte=32;  //write pointlist;
  if (oasisLayer!=o->modal.layer) info_byte+=1;
  if (oasisDatatype!=o->modal.datatype) info_byte+=2;
  if (pointarray.point(0).x()!=o->modal.geometry_x) info_byte+=16;
  if (pointarray.point(0).y()!=o->modal.geometry_y) info_byte+=8;
  o->writeUnsignedInteger((uint)21);
  o->writeRaw(info_byte);
  if (info_byte&1) {
	o->modal.layer=oasisLayer;
	o->writeUnsignedInteger((uint)o->modal.layer);
	}
  if (info_byte&2) {
	o->modal.datatype=oasisDatatype;
	o->writeUnsignedInteger((uint)oasisDatatype);
	}
  o->writePointArray(pointarray,true);
  if (info_byte&16) {
	o->modal.geometry_x=pointarray.point(0).x();
	o->writeSignedInteger(o->modal.geometry_x);
	}
  if (info_byte&8) {
	o->modal.geometry_y=pointarray.point(0).y();
	o->writeSignedInteger(o->modal.geometry_y);}
  saveOASISProperty(o);

}

void polygon::saveCIF( cif *c){
  QString s="L "+layers::num[layerNum].name;
  c->writeEntry(s);
  if (setup::cifSaveCircle) {
	QPoint pc;
	int r;
	if (isCircle(&pc, &r)){
		// save as circle
		s="R ";
		QString s1;
		s+=s1.setNum(r*2)+" ";
		s+=s1.setNum(pc.x())+",";
		s+=s1.setNum(pc.y())+" ";
  		s=s.trimmed();
  		c->writeEntry(s);
		return ;
	}
  }
  //save as polygon
  s="P ";
  QString s1;
  for (int i=0;i<pointarray.size()-1;i++){
	s+=s1.setNum(pointarray.point(i).x())+",";
	s+=s1.setNum(pointarray.point(i).y())+" ";
  }
  s=s.trimmed();
  c->writeEntry(s);
}

void polygon::saveCSV( csv *c){
 if (select) c->savePointArray(pointarray);
}

void polygon::saveGerber( gerber *g){
 	if (g->saveLayer!=layerNum) return;
	QPoint pc;
	int r;
	if (isCircle(&pc, &r)){
		g->write(g->aperturCircle(2*r),pc,3);
		return;
	}
	g->writeOutput("G36*\r\nG01");
	g->writeOutput(pointarray.point(0),2);
	for (int i=1;i<pointarray.size();i++){
		g->writeOutput(pointarray.point(i),1);
	}
	g->writeOutput("G37*\r\n");
  //g->write(g->aperturRect(rect.right()-rect.left(),rect.top()-rect.bottom()),QPoint((rect.right()+rect.left())/2,(rect.top()+rect.bottom())/2),3);
}



void polygon::saveODB( odb *g){
#ifdef netlistutility
#endif
}

void polygon::saveEPS( eps *e){
}

int polygon::saveEPSCount(){
  int count=29+pointarray.size()*(16+1)+9+20;
  return count;
}

void polygon::moveSelect(QPoint pos){
  int i;
  QPoint p;
  bool modified=false;
  if (select) pointarray.translate(pos.x(),pos.y());
  else {
    for (i=0;i<pointarray.size();i++){
      if (p_select.testBit(i)) {
	p=pointarray.point(i);
	p=p+pos;
	pointarray.setPoint(i,p);
	modified=true;
	}
    }
    if (modified) clean();
 }
}
	
void polygon::move(QPoint pos){
   pointarray.translate(pos.x(),pos.y());}

void polygon::resize(double size){
   int i;
   QPoint p;
   for (i=0;i<pointarray.size();i++){   
	p=pointarray.point(i)*size;
	pointarray.setPoint(i,p);
	}
   calcSize();
}

void polygon::resize(double size,int mod, bool *b){
    for (int i=0;i<pointarray.size();i++) {
        if (pointarray.point(i).x()%mod!=0) *b=true;
        if (pointarray.point(i).y()%mod!=0) *b=true;
    }

resize(size);
}
	
box * polygon::convertToBox(){
if (pointarray.size()!=5){return NULL;}
if (pointarray.point(0)!=pointarray.point(4)){return NULL;}
QPoint p;
int x1,x2,y1,y2;
p=pointarray.point(0);
x1=p.x();y1=p.y();
p=pointarray.point(1);
if (p.x()<x1){x2=x1;x1=p.x();}
else {x2=p.x();}
if (p.y()<y1){y2=y1;y1=p.y();}
else {y2=p.y();}
for (int i=2;i<4;i++){
	p=pointarray.point(i);
	if (p.x()<x1){x1=p.x();}
	if (p.x()>x2){x2=p.x();}
	if (p.y()<y1){y1=p.y();}
	if (p.y()>y2){y2=p.y();}}
bool b=true;
for (int i=0;i<4;i++){
	p=pointarray.point(i);
	if ((p.x()!=x1)&&(p.x()!=x2))b=false;
	if ((p.y()!=y1)&&(p.y()!=y2))b=false;
	}
if (b) { box *e=new box(x1,y1,(x2-x1),(y2-y1),layerNum);
    e->datatype=datatype;
    e->property=property;
	return e;}
else {return NULL;}}

polygon* polygon::convertToCircle(){
  pointArray points=element::fitToCircle(pointarray,false);
  polygon *p= new polygon(points,layerNum);
    p->datatype=datatype;
    p->property=property;
  return p;
}

elementList* polygon::convertToMesh(int width , int spaceing) { 
 if (!select) return NULL;
 elementList *b,*a=NULL;
 pointArray points=pointarray;
 int w2=width/2;
 points.sizeAdjust(-w2);
 QPoint p=(points.point(0)+points.point(1))/2;
 points.attachPoint(points.point(0));
 points.setPoint(0,p);
 points.attachPoint(p);
 element *c;
 c=new path(points,layerNum);
 c->setWidth(width);
 c->setCap(0);
 b=new elementList();
 b->thisElement=c;
 b->nextElement=a;
 c=NULL;
 a=b;
 points.clean();
 int sr=width+spaceing;
 int xmax,ymax,ymin,xmin;
 xmin=points.point(0).x();
 xmax=xmin;
 ymin=points.point(0).y();
 ymax=ymin;
 for (int i=1;i<points.size();i++){
	if (points.point(i).x()>xmax) xmax=points.point(i).x();
	if (points.point(i).y()>ymax) ymax=points.point(i).y();
	if (points.point(i).x()<xmin) xmin=points.point(i).x();
	if (points.point(i).y()<ymin) ymin=points.point(i).y();
	}

 int start=round(xmin/sr)*sr;
 while (start<=xmin) start+=sr;
 for (int i=start;i<xmax;i+=sr){
	pointArray pc=points.cutPoints(QPoint(i,ymin-w2),QPoint(i,ymax+w2));
	//printf("%d\n",pc.size());
	QList<int> cl;
	for (int k=0;k<pc.size();k++) cl<<pc.point(k).y();
	qSort(cl);
	if (cl.size()>0){
		if (cl.size()%2==0){
			while (!cl.isEmpty()){
				pc.resize(2);
				pc.setPoint(0,i,cl.takeFirst());
				pc.setPoint(1,i,cl.takeFirst());
				c=new path(pc,layerNum);
				c->setWidth(width);
				c->setCap(setup::defaultPathCap);
				b=new elementList();
				b->thisElement=c;
				b->nextElement=a;
				c=NULL;
				a=b;
			}
		}
		else {
			pc.resize(2);
			pc.setPoint(0,i,cl.first());
			pc.setPoint(1,i,cl.last());
			c=new path(pc,layerNum);
			c->setWidth(width);
			c->setCap(setup::defaultPathCap);
			b=new elementList();
			b->thisElement=c;
			b->nextElement=a;
			c=NULL;
			a=b;
		}
	}

   }
 start=round(ymin/sr)*sr;
 while (start<=ymin) start+=sr;
 for (int i=start;i<ymax;i+=sr){
	pointArray pc=points.cutPoints(QPoint(xmin-w2,i),QPoint(xmax+w2,i));
	//printf("%d\n",pc.size());
	QList<int> cl;
	for (int k=0;k<pc.size();k++) cl<<pc.point(k).x();
	qSort(cl);
	if (cl.size()>0){
		if (cl.size()%2==0){
			while (!cl.isEmpty()){
				pc.resize(2);
				pc.setPoint(0,cl.takeFirst(),i);
				pc.setPoint(1,cl.takeFirst(),i);
				c=new path(pc,layerNum);
				c->setWidth(width);
				c->setCap(setup::defaultPathCap);
				b=new elementList();
				b->thisElement=c;
				b->nextElement=a;
				c=NULL;
				a=b;
			}
		}
		else {
			pc.resize(2);
			pc.setPoint(0,cl.first(),i);
			pc.setPoint(1,cl.last(),i);
			c=new path(pc,layerNum);
			c->setWidth(width);
			c->setCap(setup::defaultPathCap);
			b=new elementList();
			b->thisElement=c;
			b->nextElement=a;
			c=NULL;
			a=b;
		}
	}

   }
  return a;

}

void polygon::mapSelect(strans m){
int i;
QPoint p;
bool maped=false;
if (select) {
 maped=true;
 for (i=0;i<pointarray.size();i++){
  	p=pointarray.point(i);
	p=m.matrix.map(p);
	pointarray.setPoint(i,p);}
	if (m.mirror_x) clean();}
else {
    for (i=0;i<pointarray.size();i++){
      if (p_select.testBit(i)) {
	p=pointarray.point(i);
	p=m.matrix.map(p);
	pointarray.setPoint(i,p);
	maped=true;
	}
	if (maped) clean();
	}}
if (maped) calcSize();
}
	
void polygon::map(strans m){
int i;
QPoint p;
 for (i=0;i<pointarray.size();i++){
  	p=pointarray.point(i);
	p=m.matrix.map(p);
	pointarray.setPoint(i,p);}
if (m.mirror_x) clean();
calcSize();
}

void polygon::deletePoint(uint pos){
for (int i=pos;i<pointarray.size()-1;i++){
	pointarray.setPoint(i,pointarray.point(i+1));}
pointarray.resize(pointarray.size()-1);
p_select.resize(pointarray.size());}

void polygon::addPoint(uint pos){
pointarray.resize(pointarray.size()+1);
p_select.resize(pointarray.size());
for (uint i=pointarray.size()-1;i>pos;i--){
	pointarray.setPoint(i,pointarray.point(i-1));}}

void polygon::clean(){
// clean also in pointarray
/*QPoint p;
double a;
bool b;
//printf("start clean\n");
//for (uint i=0; i<pointarray.size();i++){printf("c#%d x %d y %d\n",i,pointarray.point(i).x(),pointarray.point(i).y());}
if (pointarray.size()>2) 
	if (pointarray.point(0)!=pointarray.point(pointarray.size()-1)) 
		{
		addPoint(pointarray.size()-1);
		pointarray.setPoint(pointarray.size()-1,pointarray.point(0));
		}
int anz=0;
for (a=0;((a<350)||(a>370))&&(anz<2);){
	a=0;
	//überflüssige Punkte entfernen
	for (int i=0;i<(int)pointarray.size()-1;i++){
		if (pointarray.size()<4) return; //no area
		if (pointarray.point(i)==pointarray.point(i+1)){
		  	deletePoint(i+1);
		  	if (((int)pointarray.size())==(i+1)){pointarray.setPoint(0,pointarray.point(i));}
			i--;}
		if (i<(int)pointarray.size()-2){
		if (this->nearlyParallel(pointarray.point(i),pointarray.point(i+1),pointarray.point(i+1),pointarray.point(i+2))){
			 deletePoint(i+1);
			 i=0;}}
		if (pointarray.size()>3){
		while ( (pointarray.size()>3)&&(this->parallel(pointarray.point(0),pointarray.point(1),pointarray.point(pointarray.size()-1), pointarray.point(pointarray.size()-2)))){ deletePoint(pointarray.size()-1);
						pointarray.setPoint(0,pointarray.point(pointarray.size()-1));}}
		}
	//punkte sortieren
	for (int i=0; i<pointarray.size()-2;i++){
 		a+=angle(pointarray.point(i),pointarray.point(i+1),pointarray.point(i+2));}
	if (pointarray.size()>3){
		a+=angle(pointarray.point(pointarray.size()-2),pointarray.point(0),pointarray.point(1));}
	// Punkte linksdrehend
	if (a<-185) {
		for (int i=1; i<(pointarray.size())/2;i++){
				p=pointarray.point(pointarray.size()-i-1);
				pointarray.setPoint(pointarray.size()-i-1,pointarray.point(i));
				pointarray.setPoint(i,p);
			}
		a=-a;
		}
	// entartete Polygone bereinigen (simple selfintersecting) mit schnittpunkt von zwei greaden
	if ((a>370)||((a<350)&&(a>-350))){
		for (int i=0; i<pointarray.size()-1;i++){
			for (int j=i+2;j<pointarray.size()-1;j++){
				b=cutPoint2(pointarray.point(i),pointarray.point(i+1),pointarray.point(j),pointarray.point(j+1),&p);
				if (b)if(!((i==0)&&(j==pointarray.size()-2))){
					addPoint(j+1);
					j++;
					pointarray.setPoint(j,p);
					addPoint(i+1);
					i++;
					pointarray.setPoint(i,p);
					for (int k=i+1;k<=(i+j)/2;k++){
						p=pointarray.point(j-k+i+1);
						pointarray.setPoint(j-k+i+1,pointarray.point(k));
						pointarray.setPoint(k,p);	}	
					j=pointarray.size();
					i=pointarray.size();}
				}}}
	// remove selfintersection 
	if (pointarray.size()>=8){bool ende2=false;
	for (int i=0;i<(int)pointarray.size()-1;i++){ bool ende1=false;
		for (int j=i+2;j<(int)pointarray.size()-1;j++){
			//printf("0 i: %d j: %d\n",i,j);
			if (element::identical(pointarray.point(i),pointarray.point(i+1),pointarray.point(j+1),pointarray.point(j))){
				//two identical lines
				//printf("identical lines\n");
				//printf("0a i: %d j: %d\n",i,j);
				//printf("0a j+1: %d/%d i:%d/%d\n",pointarray.point(j+1).x(),pointarray.point(j+1).y(),pointarray.point(i).x(),pointarray.point(i).y());
				int h1,h2,h3,h4,h5,h6;
				bool side=true;
				bool change=false;
				bool doit=true;
				if (pointarray.point(j+1)==pointarray.point(i)){
					change=true;
					h1 =i-1;if (h1==(-1)) h1=pointarray.size()-2;
					h2=j+2; if (h2==(int)pointarray.size()) h2=1; 
					//printf("1\n");
					double d1,d2;
					d1=180-angle(pointarray.point(h1),pointarray.point(i),pointarray.point(i+1));
					d2=180-angle(pointarray.point(h2),pointarray.point(j+1),pointarray.point(j));
					if (d1<0) d1+=360;
					if (d2<0) d2+=360;
					//printf("d1 %f d2 %f\n",d1,d2);
					if (d1<d2){side=false;}}
				else if (onLine2(pointarray.point(i),pointarray.point(i+1),pointarray.point(j+1))){
					//printf("2\n");
					change=true;
					h2=j+2; if (h2==(int)pointarray.size()) h2=1;
					if (distance(pointarray.point(i),pointarray.point(i+1),pointarray.point(h2))<0){side=false;}}
				else if (onLine2(pointarray.point(j),pointarray.point(j+1),pointarray.point(i))){
					change=true;
					//printf("3\n");
					h1=i-1; if (h1==-1) h1=pointarray.size()-2;
					if (distance(pointarray.point(j),pointarray.point(j+1),pointarray.point(h1))<0){side=false;}}
				else {doit=false;}
				if (doit)
				{//printf("1 i: %d j: %d\n",i,j);
				//printf("change %d\n",change);	
				//printf("side %d\n",side);	
				while (pointarray.point(j)==pointarray.point(i+1)){j--;i++;
					if (j==(-1)) {j=pointarray.size()-2;ende1=true;}
					if (i==(int)pointarray.size()) {i=1;ende2=true;} }
				h2=i+1; if (h2==(int)pointarray.size()) h2=1; 
				h3=h2+1; if (h3==(int)pointarray.size()) h3=1; 
				h1=j-1; if (h1==-1) h1=pointarray.size()-2; 
				h4=j+1; if (h4==(int)pointarray.size()) h4=1; 
				h5=h4+1; if (h5==(int)pointarray.size()) h5=1; 
				h6=i-1; if (h6==-1) h6=pointarray.size()-2; 
				if (onLine2(pointarray.point(i),pointarray.point(h2),pointarray.point(j))){
					//printf("4\n");
					if ((distance(pointarray.point(i),pointarray.point(h2),pointarray.point(h1))<0)!=side){change=false;}}
				else if (onLine2(pointarray.point(j),pointarray.point(h4),pointarray.point(h2))){
					//printf("5\n");
					if ((distance(pointarray.point(j),pointarray.point(h4),pointarray.point(h3))<0)!=side){change=false;}}
				else {  //printf("6\n");
					double d1,d2;
					d1=180-angle(pointarray.point(h6),pointarray.point(i),pointarray.point(h2));
					d2=180-angle(pointarray.point(h5),pointarray.point(h4),pointarray.point(j));
					if (d1<0) d1+=360;
					if (d2<0) d2+=360;
					//printf("d1 %f d2 %f\n",d1,d2);
					if ((d1<d2)!=side){change=false;}}
				if (change){
					for (uint k=(uint)i+1; k<(uint)(i+j+2)/2;k++){
						//printf(" tausche %d %d\n",j+i-k+1,k);
						p=pointarray.point(j+i-k+1);
						pointarray.setPoint(j+i-k+1,pointarray.point(k));
						pointarray.setPoint(k,p);}}
				//printf("2 i: %d j: %d\n",i,j);
				//printf("change %d\n",change);	
				}
			}
			else if ((pointarray.point(i)==pointarray.point(j+1))&&(pointarray.point(i+1)!=pointarray.point(j))&&(j!=pointarray.size()-2)){
				//printf("check %d %d\n",i,j);
				// only one identical point and not parallel
				bool change=false;
				int h1,h2;
				h1 =i-1;if (h1==(-1)) h1=pointarray.size()-2;
				h2=j+2; if (h2==(int)pointarray.size()) h2=1; 
				double d1,d2,d3;
				d1=180-angle(pointarray.point(h1),pointarray.point(i),pointarray.point(i+1));
				d2=180-angle(pointarray.point(h1),pointarray.point(i),pointarray.point(j));
				d3=180-angle(pointarray.point(h1),pointarray.point(i),pointarray.point(h2));
				//printf("1 %f 2 %f 3 %f\n",d1,d2,d3);
				if ((d2<d1)&&(d3>d1)){change=true;}
				if ((d2>d1)&&(d3<d1)){change=true;}
				if (change){
					for (uint k=(uint)i+1; k<(uint)(i+j+2)/2;k++){
						//printf(" tausche %d %d\n",j+i-k+1,k);
						p=pointarray.point(j+i-k+1);
						pointarray.setPoint(j+i-k+1,pointarray.point(k));
						pointarray.setPoint(k,p);}}
				}
			if (ende1||ende2) break;
		}
		if (ende2) break;}
	}
	//printf("a: %f anz %d\n",a,pointarray.size());
	anz++;
 }
 //printf("end clean\n");
 //for (uint i=0; i<pointarray.size();i++){printf("c#%d x %d y %d\n",i,pointarray.point(i).x(),pointarray.point(i).y());}*/
pointarray.clean();
if (pointarray.size()!=p_select.size())p_select.resize(pointarray.size());
calcSize();
}

elementList* polygon::cutSelect(QPoint p1, QPoint p2){
if (select){
clean();
int anz_cp=0;
pointArray cutpoint;
pointArray cutpos;
cutpoint.resize(0);
cutpos.resize(0);
QPoint pos;
bool b;
double help,dist;
int nr=-2;
// calc intersections
for (int i=0; i<pointarray.size()-1;i++){
	b=cutPoint(p1,p2,pointarray.point(i),pointarray.point(i+1),&pos);
	if (b){ //printf("b %i\n",i);
		help=this->distance(p1,p2,pointarray.point(i));
		if (help<0) {
			anz_cp++;
			cutpoint.resize(anz_cp);
			cutpos.resize(anz_cp);
			cutpoint.setPoint(anz_cp-1,pos);
			cutpos.setPoint(anz_cp-1,i,-1-8);
			}
		else if (help>0) {
			anz_cp++;
			cutpoint.resize(anz_cp);
			cutpos.resize(anz_cp);
			cutpoint.setPoint(anz_cp-1,pos);
			cutpos.setPoint(anz_cp-1,i,-2-8);
			}
		help=this->distance(p1,p2,pointarray.point(i+1));
		if (help<0) {
			anz_cp++;
			cutpoint.resize(anz_cp);
			cutpos.resize(anz_cp);
			cutpoint.setPoint(anz_cp-1,pos);
			cutpos.setPoint(anz_cp-1,i,1-8);
			}
		else if (help>0) {
			anz_cp++;
			cutpoint.resize(anz_cp);
			cutpos.resize(anz_cp);
			cutpoint.setPoint(anz_cp-1,pos);
			cutpos.setPoint(anz_cp-1,i,2-8);
			}
		}
		if (parallel(p1,p2,pointarray.point(i),pointarray.point(i+1))){
			if (onLine2(p1,p2,pointarray.point(i))&&(!onLine2(p1,p2,pointarray.point(i+1)))){
				//printf("para1 %i\n",i);
				anz_cp++;
				cutpoint.resize(anz_cp);
				cutpos.resize(anz_cp);
				cutpoint.setPoint(anz_cp-1,pointarray.point(i));
				cutpos.setPoint(anz_cp-1,i,1-8);
				anz_cp++;
				cutpoint.resize(anz_cp);
				cutpos.resize(anz_cp);
				cutpoint.setPoint(anz_cp-1,pointarray.point(i));
				cutpos.setPoint(anz_cp-1,i,2-8);
				}
			if ((!onLine2(p1,p2,pointarray.point(i)))&&(onLine2(p1,p2,pointarray.point(i+1)))){
				//printf("para2 %d\n",i);
				anz_cp++;
				//printf("para2 anz %d\n",anz_cp);
				cutpoint.resize(anz_cp);
				cutpos.resize(anz_cp);
				cutpoint.setPoint(anz_cp-1,pointarray.point(i));
				cutpos.setPoint(anz_cp-1,i,-8);
				/*anz_cp++;
				printf("para2 anz %d\n",anz_cp);
				cutpoint.resize(anz_cp);
				cutpos.resize(anz_cp);
				cutpoint.setPoint(anz_cp-1,pointarray.point(i));
				cutpos.setPoint(anz_cp-1,i,-8);*/
				}	
			}
		}
//printf("anz %d\n",anz_cp);
if (anz_cp==0) return NULL;
//Abhängigkeiten auflösen
for (int i=0;i<anz_cp;i++){
   dist=1e+20;
   nr=-2;
   if (cutpos.point(i).y()<=-8){ 
      for (int j=i+1;j!=i;){
         if (j>=anz_cp) j=0;
	 //printf("i %d j %d\n",i,j);
         //if (cutpos.point(i).y()==cutpos.point(j).y()) {j=i-1;
	//			printf("ignore %d,%d\n",i,j);}  // not a valid intersection
	 if ((cutpos.point(i).y()+8)== -(cutpos.point(j).y()+8)) {
		help=distance(pointarray.point(cutpos.point(i).x()),pointarray.point(cutpos.point(i).x()+1),cutpoint.point(j));
		//printf("help %f \n",help);
		if ((help>0)&&(help<dist)){ 
			dist=help;
			nr=j;
		}}
	if (cutpos.point(i).y()==-8){
		help=0; //distance(pointarray.point(cutpos.point(i).x()),pointarray.point(cutpos.point(i).x()+1),cutpoint.point(j));
		if (help<0) help=-help;
		//printf("help8 %f \n",help);
		if ((help<=dist)){ 
			dist=help;
			nr=j;
		}
		}
         j++;
	 if (j>=anz_cp) j=0;
	}
	if (dist!=1e+20){
		int ih=cutpos.point(i).x();
		if (ih==pointarray.size()-2) ih=0;
		cutpos.setPoint(i,ih,nr);
		//cutpos.setPoint(nr,cutpos.point(nr).x(),-1);
		//printf("i%d j%d nri%d nrj%d\n",i,nr,cutpos.point(i).x(),cutpos.point(nr).x());
	}
   }
}
// Elemente erzeugen
elementList *a=NULL;
elementList *c;
polygon *p;
pointArray a_copy,a1;
a_copy=pointarray;
nr=0;
int pos_array,pos_copy;
//dieses element ändern
while ((nr<anz_cp)&&(cutpos.point(nr).y()<0)){nr++;}
if (nr==anz_cp){return NULL;}
pos_array=0;
pos_copy=0;
//printf("anz org %d/%d\n",pointarray.size(),a_copy.size());
//printf("start first\n");
while (pos_copy<(int)a_copy.size()-1){
	nr=-1;
	for (int i=0;i<anz_cp;i++){
	 //diese Punkt neuer Schnittpunkt?
	 //nr Nummer des Schnittpunktes
	 if ((cutpos.point(i).x()==pos_copy)&&cutpos.point(i).y()>=0){nr=i;}
	}
	if (nr>=0) {
		// nr = found intersection
		pos_array++;
		pointarray.resize(pos_array+1);
		pointarray.setPoint(pos_array,cutpoint.point(nr)); // add first intersection
		pos_array++;
		pointarray.resize(pos_array+1);
		//printf("add pc %d\n",nr);
		int i=nr;
		nr=cutpos.point(nr).y();
		cutpos.setPoint(i,cutpos.point(i).x(),-1);
		cutpos.setPoint(nr,cutpos.point(nr).x(),-1);
		pointarray.setPoint(pos_array,cutpoint.point(nr)); //add second intersection
		pos_copy=cutpos.point(nr).x();
		//printf("add pc %d\n",nr);
 	 } 
	pos_array++;
	pos_copy++;
	//printf("add %d/%d\n",pos_array,pos_copy);
	pointarray.resize(pos_array+1);
	pointarray.setPoint(pos_array,a_copy.point(pos_copy));
}
p_select.resize(pointarray.size());
clean();
//restlichen elemente
for (int i=0;i<anz_cp;i++){
 if (cutpos.point(i).y()>=0){
	//printf("start next\n");
 	a1.resize(2);	
 	a1.setPoint(0,cutpoint.point(i));
	nr=cutpos.point(i).y();
	a1.setPoint(1,cutpoint.point(nr));
	pos_copy=cutpos.point(nr).x();
	pos_array=1;
	b=true;
	while (i!=nr) {
		pos_array++;
		pos_copy++;
		if (pos_copy==(int)a_copy.size()){pos_copy=0;}
		a1.resize(pos_array+1);
		a1.setPoint(pos_array,a_copy.point(pos_copy));
		//printf("add %d\n",pos_array);
		nr=-1;
		for (int n=0;n<anz_cp;n++){
		 //diese Punkt neuer Schnittpunkt?
		 //nr Nummer des Schnittpunktes
		 if ((cutpos.point(n).x()==pos_copy)&&(cutpos.point(n).y()>=0)){
		 	nr=n;}
		}
		if ((nr>=0)&&(nr!=i)) {
			pos_array++;
			a1.resize(pos_array+1);
			a1.setPoint(pos_array,cutpoint.point(nr));
			//printf("add pc %d\n",nr);
			pos_array++;
			a1.resize(pos_array+1);
			int k=nr;
			nr=cutpos.point(nr).y();
			cutpos.setPoint(nr,cutpos.point(nr).x(),-1);
			cutpos.setPoint(k,cutpos.point(k).x(),-1);
			a1.setPoint(pos_array,cutpoint.point(nr));
			pos_copy=cutpos.point(nr).x();
			//printf("add pc %d\n",nr);
 	 	}  	
	}
	pos_array++;
	//printf("add %d\n",pos_array);
	a1.resize(pos_array+1);
	a1.setPoint(pos_array,a1.point(0));
	p=new polygon(a1,layerNum);
	p->select=true;
	p->clean();
	c=new elementList();
	c->thisElement=p;
	c->nextElement=a;
	a=c;
 
 }
}
return a;
}
return NULL;}

bool polygon::correct(){
if (pointarray.size()<4) return false;
return true;
}

bool polygon::mergeSelect(polygon *p){
if (select&&p->select&&(layerNum==p->layerNum)){
	clean();
	p->clean();
return mergeBoolean(p);
	if (layout::debug)for (int i=0; i<pointarray.size();i++){printf("original: 1: x %d y %d\n",pointarray.point(i).x(),pointarray.point(i).y());}
	if (layout::debug)for (int i=0; i<p->pointarray.size();i++){printf("add: 2: x %d y %d\n",p->pointarray.point(i).x(),p->pointarray.point(i).y());} 
	bool b;
	QPoint point;
	pointArray cutpoint,cutpos,cutpara,neu;
	int anz_cp=0;
	for (int i=0;i<pointarray.size()-1;i++){
		for (int k=0;k<p->pointarray.size()-1;k++){
			b=cutPoint2(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k),p->pointarray.point(k+1),&point);
			//if (layout::debug)printf("b: %d pcx %d pcy %d\n",b,point.x(),point.y());
			if (!b) { int i_=(int)i-1;if (i_<0){i_=pointarray.size()-2;}
				int k_=(int)k-1;if (k_<0){k_=p->pointarray.size()-2;}
				int k2=(int)k+2;if (k2>=(int)p->pointarray.size()) k2=1;
				int i2=(int)i+2;if (i2>=(int)pointarray.size()) i2=1;
				if (onLine2(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k))&& (distance(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k_))<0)
				&&(distance(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k+1))>0)
				){b=true;
													point=p->pointarray.point(k);
													if (layout::debug)printf("cp1\n");}
				if (onLine2(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k))&& (distance(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k+1))<0)
				&&(distance(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k_))>0)
				){b=true;
													point=p->pointarray.point(k);
													if (layout::debug)printf("cp2\n");}
				if ((onLine2(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i)))&& (distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i_))<0)&& (distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i+1))>0)
				){b=true;
													point=pointarray.point(i);
													if (layout::debug)printf("cp3\n");}
				if ((onLine2(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i))&& (distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i_))<0))
				&&(angle(p->pointarray.point(k),pointarray.point(i),pointarray.point(i+1))==-180)
				){b=true;
													point=pointarray.point(i);
													if (layout::debug)printf("cp3a\n");}
				if ((onLine2(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i)))&& (angle(pointarray.point(i_),pointarray.point(i),p->pointarray.point(k))==-180)&& (distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i+1))>0)
				){b=true;
													point=pointarray.point(i);
													if (layout::debug)printf("cp3b\n");}
				if ((onLine2(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i))&& ((distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i+1))<0)))
				&&((distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i_))>0))
				){b=true;
													point=pointarray.point(i);
													if (layout::debug)printf("cp4\n");}
				if ((onLine2(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i))&&    (distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i+1))<0))
				&&(angle(p->pointarray.point(k+1),pointarray.point(i),pointarray.point(i_))==-180)
				){b=true;
													point=pointarray.point(i);
													if (layout::debug)printf("cp4a\n");}
				if ((onLine2(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i))&& ((angle(p->pointarray.point(k+1),pointarray.point(i),pointarray.point(i+1))==-180)))
				&&((distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i_))>0))
				){b=true;
													point=pointarray.point(i);
													if (layout::debug)printf("cp4b\n");}
				if ((p->pointarray.point(k)==pointarray.point(i))){
					//double a1=angle(pointarray.point(i_),pointarray.point(i),p->pointarray.point(k_));
					//double a2=angle(pointarray.point(i_),pointarray.point(i),pointarray.point(i+1));
					double a3=angle(pointarray.point(i_),pointarray.point(i),p->pointarray.point(k+1));
					double a4=angle(pointarray.point(i+1),pointarray.point(i),p->pointarray.point(k_));
					double a5=angle(pointarray.point(i_),pointarray.point(i),p->pointarray.point(k_));
					double a6=angle(pointarray.point(i_),pointarray.point(i),pointarray.point(i+1));
					double a7=angle(pointarray.point(i+1),pointarray.point(i),pointarray.point(i_));
					double a8=angle(pointarray.point(i+1),pointarray.point(i),p->pointarray.point(k+1));
					/*if (layout::debug){
						printf("identicalpoint\n");
						printf("a1 %f\n",a1);
						printf("a2 %f\n",a2);
						printf("a3 %f\n",a3);
						printf("a4 %f\n",a4);
						printf("a5 %f\n",a5);
						printf("a6 %f\n",a6);
						printf("a7 %f\n",a6);
						printf("a8 %f\n",a6);
						}*/
					if (a3>179.9999) a3=-180;
					if (a4>179.9999) a4=-180;
					/*if ((a1<a2)&&(a2<a3)&&(a3!=-180)&&(a1!=-180)){b=true;
								if (layout::debug)printf("cp5\n");}
					if ((a1>a2)&&(a2>a3)&&(a3!=-180)&&(a1!=-180)){b=true;
								if (layout::debug)printf("cp6\n");}*/
					if ((a3>=a6)&&(a6>a5)&&(a5!=-180)){b=true;
								point=pointarray.point(i);
								if (layout::debug)printf("cp7\n");}
					if ((a3==-180)&&(a6>a5)&&(a5!=-180)){b=true;
								point=pointarray.point(i);
								if (layout::debug)printf("cp7a\n");}
					if ((a4<=a7)&&(a7<=a8)&&(a8!=-180)&&(a3!=-180)){b=true;
								point=pointarray.point(i);
								if (layout::debug)printf("cp8\n");}
					}
				
				if (element::identical(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k),p->pointarray.point(k+1))){
					if (layout::debug){
					//printf(" d9 %f\n",distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i_)));
					//printf("d10 %f\n",distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i2)));
					//printf("d11 %f\n",distance(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k_)));
					//printf("d12 %f\n",distance(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k2)));
					}
					/*if ((onLine2(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i)))&&
					(distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i_))<0)){
													b=true;
													point=pointarray.point(i);
													if (layout::debug)printf("cp9\n");
													}
					if ((onLine2(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i+1)))&&
					(distance(p->pointarray.point(k),p->pointarray.point(k+1),pointarray.point(i2))<0)){
													b=true;
													point=pointarray.point(i+1);
													if (layout::debug)printf("cp10\n");
													}*/
					if ((onLine2(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k)))&&
					(distance(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k_))<0)){
													b=true;
													point=p->pointarray.point(k);
													if (layout::debug)printf("cp11\n");
													}
					}
				if (element::identical(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k_),p->pointarray.point(k))){
					if ((onLine2(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k)))&&
					(distance(pointarray.point(i),pointarray.point(i+1),p->pointarray.point(k+1))<0)){
													b=true;
													point=p->pointarray.point(k);
													if (layout::debug)printf("cp12\n");
													}
					}
				}
			if (b) {
				anz_cp++;
				cutpoint.resize(anz_cp);
				cutpos.resize(anz_cp);
				cutpara.resize(anz_cp);
				cutpoint.setPoint(anz_cp-1,point);
				cutpos.setPoint(anz_cp-1,i,k);
				cutpara.setPoint(anz_cp-1,-1,-1);
				if (layout::debug) printf("cp: #%d %d %d\n",anz_cp-1,i,k);
				if (layout::debug) printf("cutpoint %d  %d \n",cutpoint.point(anz_cp-1).x(),cutpoint.point(anz_cp-1).y());
				}
			}
		}
	if (layout::debug) printf("anz_cp: %d\n",anz_cp);
	if (anz_cp==0){ 
			bool a=pointInPolygon(p->pointarray,pointarray.point(2))|| pointInPolygon(p->pointarray,pointarray.point(1))|| pointInPolygon(p->pointarray,pointarray.point(0));
			bool b=pointInPolygon(pointarray,p->pointarray.point(2))|| pointInPolygon(pointarray,p->pointarray.point(1)) || pointInPolygon(pointarray,p->pointarray.point(0));
			double a1=p->areaSelected();
			double b1=areaSelected();
			if (a||b) {
				if (a1>b1) {
					pointarray=p->pointarray;
					p_select=p->p_select;
					if (layout::debug) printf("groesser2\n");
					}
				else if (layout::debug) printf("kleiner2\n");
				return true;
				}
			else if ((a)&(a1>b1)) {//größer 
				pointarray=p->pointarray;
				p_select=p->p_select;
				if (layout::debug) printf("groesser\n");
				return true;}
			else if ((b)&(b1>a1)){ 
					if (layout::debug) printf("kleiner\n");
					return true;} //kleiner
			else return false;}  //kein Kontakt
	if (anz_cp%2==1) {return mergeBoolean(p);} //nicht mergebar
	int pos=0;
	int pos1,pos2;
	int nr;
	int start_cp=0;
	bool round=false;
	double dist,help;
	for (int i=0;i<anz_cp;i++){
	        dist=distance(pointarray.point(cutpos.point(i).x()),pointarray.point(cutpos.point(i).x()+1), p->pointarray.point(cutpos.point(i).y()));
		if (dist>0){start_cp=i;i=anz_cp;}
		if (dist==0){
			dist=distance(pointarray.point(cutpos.point(i).x()),pointarray.point(cutpos.point(i).x()+1), p->pointarray.point(cutpos.point(i).y()+1));
			if (dist<0){start_cp=i;i=anz_cp;}}
		}
	neu.resize(3);
	neu.setPoint(pos,cutpoint.point(start_cp));
	cutpara.setPoint(start_cp,1,1);
	pos2=cutpos.point(start_cp).y();
	pos1=cutpos.point(start_cp).x();
	//printf("pos 1->%d\n",pos);
	if (layout::debug) printf("mergein\n"); // Einfügen Zweig +
	mergeIn(&neu,&pos,&(p->pointarray),&pos2,&pos1,&cutpoint,&cutpos,&cutpara,true,start_cp);
	nr=-1;
	while (nr!=start_cp) {
	dist=1e+20;
	nr=-1;
	   for (int i=0;i<anz_cp;i++){
		if ((cutpos.point(i).x()==pos1)&&((cutpara.point(i).x()==-1)||(i==start_cp&&round))) {
			if (nearLine(neu.point(pos),pointarray.point(pos1+1),cutpoint.point(i))){
				point=neu.point(pos)-cutpoint.point(i);
      				help=(double)point.x()*(double)point.x()+(double)point.y()*(double)point.y();
     				 if (help<dist){nr=i;dist=help;}}}}
	   if ((nr>=0)&&(nr!=start_cp)) {
		pos++;
		neu.resize(pos+1);
		neu.setPoint(pos,cutpoint.point(nr));
		cutpara.setPoint(nr,1,1);
		pos2=cutpos.point(nr).y();
		//printf("pos 2->%d\n",pos);
		//einfügen zweig +
		if (layout::debug) printf("mergein2\n");
		mergeIn(&neu,&pos,&(p->pointarray),&pos2,&pos1,&cutpoint,&cutpos,&cutpara,true,nr);
		}
	  if (nr<0) {
	  	pos++;
		neu.resize(pos+1);
		pos1++;
		if (pos1>=(int)pointarray.size()-1){pos1=0;round=true;};
		neu.setPoint(pos,pointarray.point(pos1));
		//printf("pos1 3->%d\n",pos1);
		//printf("pos 3->%d\n",pos);
		}
	}
	pos++;
	neu.resize(pos+1);
	neu.setPoint(pos,cutpoint.point(start_cp));
	//printf("pos 4->%d\n",pos);
	double area1=areaSelected();
	double area2=p->areaSelected();
	pointArray backup=pointarray;
	pointarray=neu;
	p_select.resize(pointarray.size());
	double area3=areaSelected();
	if ((area3>area1)&&(area3>area2)) {
			if (!layout::debug) clean();
			return true;
			}

	//for (uint i=0; i<pointarray.size();i++){printf("1: x %d y %d\n",pointarray.point(i).x(),pointarray.point(i).y());}
	pointarray=backup;
	p_select.resize(pointarray.size());
	return mergeBoolean(p);
	}
else return false;
}

void  polygon::mergeIn(pointArray *neu, int *pos, pointArray *parray, int *pos2, int *pos1, pointArray * cutpoint, pointArray * cutpos, pointArray *cutpara,bool dir,int nr){
int n=-1;
int pos1_r=*pos1;
double dist,help;
QPoint point;
//printf("merge 1 nr: %d pos1:%d\n",nr,*pos1);
//printf("cutpoint %d  %d \n",cutpoint->point(nr).x(),cutpoint->point(nr).y());
//printf("dir %d\n",dir);
if (dir){
    n=-1;
     while (n==(-1)){
     	dist=1e+20;
     	for (int i=0;i<(int)cutpos->size();i++){
		if ((cutpos->point(i).y()==*pos2)&&(i!=nr)) {
			if (nearLine(neu->point(*pos),parray->point(*pos2+1),cutpoint->point(i))){
				point=neu->point(*pos)-cutpoint->point(i);
      				help=(double)point.x()*(double)point.x()+(double)point.y()*(double)point.y();
     				 if (help<dist){n=i;dist=help;}}}}
	if (n==-1){
		*pos2=*pos2+1;
		if (*pos2==((int)parray->size()-1)){*pos2=0;};
		*pos=*pos+1;
		neu->resize(*pos+1);
		neu->setPoint(*pos,parray->point(*pos2));
		//printf("pos 5->%d\n",*pos);
		n=-1;
		}
	
    }
    //printf("merge 3 n:%d\n",n);
    *pos=*pos+1;
    neu->resize(*pos+1);
    neu->setPoint(*pos,cutpoint->point(n));
    pos1_r=cutpos->point(n).x();
    cutpara->setPoint(n,0,0);
    //printf("pos 6->%d pos1_r: %d\n",*pos,pos1_r);
    n=-1;
    while (n!=nr){
    // Schnittpunkt rückwärts
    	dist=1e+20;
    	n=-1;
    	for (int i=0;i<(int)cutpos->size();i++){
		if ((cutpos->point(i).x()==pos1_r)&&((i==nr)||(cutpara->point(i).x()==-1))) {
			if (nearLine(neu->point(*pos),pointarray.point(pos1_r),cutpoint->point(i))){
				point=neu->point(*pos)-cutpoint->point(i);
      				help=(double)point.x()*(double)point.x()+(double)point.y()*(double)point.y();
     				 if (help<dist){n=i;dist=help;}}}}
	//printf("merge 4 %d %d pos_r %d\n",nr,n,pos1_r);
	if (n>=0){
		*pos=*pos+1;
    		neu->resize(*pos+1);
    		neu->setPoint(*pos,cutpoint->point(n));
		//printf("pos 7->%d\n",*pos);
    		*pos2=cutpos->point(n).y();
		if (n!=nr) {
			cutpara->setPoint(n,1,1);
			//mergein -
			mergeIn(neu,pos,parray,pos2,&pos1_r,cutpoint,cutpos,cutpara,false,n);
			}
		}	
	if (n<0){
		pos1_r--;
		*pos=*pos+1;
		if (pos1_r<0){pos1_r=pointarray.size()-2;}
		neu->resize(*pos+1);
    		neu->setPoint(*pos,pointarray.point(pos1_r+1));
		//printf("pos 8->%d\n",*pos);
	}
    }
    return;
}
else
{   while (n==(-1)){
	dist=1e+20;
	for (int i=0;i<(int)cutpos->size();i++){
		if ((cutpos->point(i).y()==*pos2)&&(i!=nr)) {
			if (nearLine(neu->point(*pos),parray->point(*pos2+1),cutpoint->point(i))){
				point=neu->point(*pos)-cutpoint->point(i);
      				help=(double)point.x()*(double)point.x()+(double)point.y()*(double)point.y();
     				 if (help<dist){n=i;dist=help;}}}}
	if (n==-1) {
		*pos2=*pos2+1;
		if (*pos2==((int)parray->size()-1)){*pos2=0;};
		*pos=*pos+1;
		neu->resize(*pos+1);
		neu->setPoint(*pos,parray->point(*pos2));
		//printf("pos 5b->%d\n",*pos);
		n=-1;
		//printf("merge 2b\n");
	}
	
    }
    //printf("merge 3b\n");
    *pos=*pos+1;
    neu->resize(*pos+1);
    neu->setPoint(*pos,cutpoint->point(n));
    pos1_r=cutpos->point(n).x();
    cutpara->setPoint(n,0,0);
    //printf("pos 6b->%d\n",*pos);
    n=-1;
    //printf("merge 4b\n");
    while (n!=nr){
    	// Schnittpunkt  vorwärts
    	dist=1e+20;
    	n=-1;
    	for (int i=0;i<(int)cutpos->size();i++){
		if ((cutpos->point(i).x()==pos1_r)&&((i==nr)||(cutpara->point(i).x()==-1))) {
			if (nearLine(neu->point(*pos),pointarray.point(pos1_r+1),cutpoint->point(i))){
				point=neu->point(*pos)-cutpoint->point(i);
      				help=(double)point.x()*(double)point.x()+(double)point.y()*(double)point.y();
     				 if (help<dist){n=i;dist=help;}}}}
       	if (n>=0){
		*pos=*pos+1;
    		neu->resize(*pos+1);
    		neu->setPoint(*pos,cutpoint->point(n));
		//printf("pos 7b->%d\n",*pos);
    		*pos2=cutpos->point(n).y();
		if (n!=nr) {
			cutpara->setPoint(n,1,1);
			//mergein +
			mergeIn(neu,pos,parray,pos2,&pos1_r,cutpoint,cutpos,cutpara,true,n);
			}
		}	
	//printf("merge 5b\n");
	if (n<0){
		pos1_r++;
		*pos=*pos+1;
		if (pos1_r==(int)pointarray.size()-1){pos1_r=0;}
		neu->resize(*pos+1);
    		neu->setPoint(*pos,pointarray.point(pos1_r));
		//printf("pos 8b->%d\n",*pos);
	}
    }
    return;
}
}


bool polygon::mergeBoolean(polygon * p){
   Bool_Engine *engine;
   engine = new Bool_Engine();
  // set some global vals to arm the boolean engine
    double MARGE = 1;   // snap with in this range points to lines in the intersection routines
                          // should always be > DGRID  a  MARGE >= 10*DGRID is oke
                          // this is also used to remove small segments and to decide when
                          // two segments are in line.
    double CORRECTIONFACTOR = 1;  // correct the polygons by this number
    double CORRECTIONABER   = 1.0;    // the accuracy for the rounded shapes used in correction
    double ROUNDFACTOR      = 1.5;    // when will we round the correction shape to a circle
    double SMOOTHABER       = 1.0;   // accuracy when smoothing a polygon
    double MAXLINEMERGE     = 1.5; // leave as is, segments of this length in smoothen
    engine->SetMarge( MARGE );
    engine->SetCorrectionFactor( CORRECTIONFACTOR );
    engine->SetCorrectionAber( CORRECTIONABER );
    engine->SetSmoothAber( SMOOTHABER );
    engine->SetMaxlinemerge( MAXLINEMERGE );
    engine->SetRoundfactor( ROUNDFACTOR );
    engine->SetDGrid(1);
    engine->SetGrid(1);
    engine->StartPolygonAdd(GROUP_A);
        for (int i=0; i<pointarray.size();i++){
        engine->AddPoint(pointarray.point(i).x(),pointarray.point(i).y());
		//printf("p: %d ; %d\n",p->point(i).x()  , p->point(i).y());
		}
    engine->EndPolygonAdd(); 
    engine->StartPolygonAdd(GROUP_B);
        for (int i=0; i<p->pointarray.size();i++){
        engine->AddPoint(p->pointarray.point(i).x(),p->pointarray.point(i).y());
		//printf("p: %d ; %d\n",p->point(i).x()  , p->point(i).y());
		}
    engine->EndPolygonAdd(); 
    engine->Do_Operation(BOOL_OR);
    pointArray pa;
    if ( engine->StartPolygonGet() )
    {    pa.resize(0);
        // foreach point in the polygon
        while ( engine->PolygonHasMorePoints() )
        {   
	    pa.resize(pa.size()+1);
	    pa.setPoint(pa.size()-1,(int)engine->GetPolygonXPoint(),(int)engine->GetPolygonYPoint());
          
        }
        engine->EndPolygonGet();
	if (pa.size()>0) {
	  pa.resize(pa.size()+1);
	  pa.setPoint(pa.size()-1,pa.point(0));
	  }
    }
    	if (engine->StartPolygonGet()){
		engine->EndPolygonGet();
		delete engine;
		return false;
		}
	delete engine;
	pointarray=pa;
	p_select.resize(pointarray.size());
	clean();
return true;
}

void polygon::sizeadjustSelect(int value){
if (select){
	//pointarray.adjustCorners(1000,2);
	//return;
	/*pointArray array;
	array.resize(pointarray.size());
	QMatrix matrix;
	QPoint p1,p2,p3,p4;
	for (int i=0; i<(int)pointarray.size()-1;i++){
		matrix.setMatrix(1,0,0,1,0,0);
		double d=angle(pointarray.point(i),pointarray.point(i+1));
		matrix.rotate(d);
		matrix.translate(0,-value);
		matrix.rotate(-d);
		p1=matrix.map(pointarray.point(i));
		p2=matrix.map(pointarray.point(i+1));
		if (i>0) {
			bool b=cutPoint(p1,p2,p4,array.point(i-1),&p3);
			array.setPoint(i,p3);
			b=false;
		}
		else array.setPoint(0,p1);
		p4=p2;
		}
	bool b=cutPoint(p1,p2,array.point(0),array.point(1),&p3);
	array.setPoint(0,p3);
	array.setPoint(array.size()-1,p3);
	b=false;*/
	/*
	double x1,x2,y1,y2,l;
	QPoint d1=pointarray.point(0)-pointarray.point(pointarray.size()-2);
	l=length(d1);
	x1=(double)(d1.x())/l;
	y1=(double)(d1.y())/l;
	for (int i=0; i<(int)pointarray.size()-1;i++){
		d1=pointarray.point(i+1)-pointarray.point(i);
		l=length(d1);
		x2=(double)(d1.x())/l;
		y2=(double)(d1.y())/l;
		d1=pointarray.point(i)+QPoint((int)(y1*value+y2*value),(int)(-x1*value-x2*value));
		array.setPoint(i,d1);
		x1=x2;
		y1=y2;
		}
	array.setPoint(pointarray.size()-1,array.point(0));*/
	//pointarray=array;
    QList<pointArray> l=pointarray.seperate();
	int outer=-1;
    for(int li=0; li<l.size();li++){
		//printf ("process %d\n",li);
		//printf ("angle before%f\n",l[li].angle());
		if (l[li].angle()>350) outer=li;
		double before=l[li].angle();
		l[li].sizeAdjust(value);
		//printf ("angle after%f %d\n",l[li].angle(),l[li].size());
		if ((abs((int)(l[li].angle()-before))>10)&&(li!=outer)) {
			l.removeAt(li);
			li--;
			//printf ("remove %d\n",li+1);
		}
	}
	if (outer==-1) {
		pointarray.sizeAdjust(value);
	}
	else if (l[outer].angle()<350){
	    pointarray.resize(2);
		pointarray.setPoint(1,pointarray.point(0));
		p_select.resize(2);
	}
	else {
		pointArray a=l[outer];
		QList<pointArray> l2;
		l2.clear();
		l.removeAt(outer);
		while (l.size()>0){
			int max=0;
			int maxX=l[max].maxX();
			for (int li=1; li<l.size();li++){
				if (maxX<l[li].maxX()) {max=li; maxX=l[max].maxX();}
			}
			l2.append(l[max]);
			l.removeAt(max);
		}
		l=l2;
		//for (int i=0; i<a.size();i++)
		//printf("a: %d ; %d\n",a.point(i).x()  , a.point(i).y());
		//printf ("use %d\n",outer);
		if (a.size()>2) 
		  for(int li=0; li<l.size();li++)
			//if (li!=outer)
				{
				// prüfen ob alle innerhalb sonst booleantool
				bool out=false;
				for (int k=0;k<l[li].size();k++)
				{
					if (!element::pointInPolygon(a,l[li].point(k))) out=true;
				}
				if (out) {
					//printf ("boolean %d %d\n",li,a.size());
					booleanHandler boolean;
					boolean.setA(&a);
					//printf ("set B %d %d\n",li,l[li].size());
					boolean.setB(&l[li]);
					QList<pointArray> pl=boolean.getAMinusB();
					if (pl.size()>=1) a=pl.at(0);
				}
				else
				{
				  a.add(&l[li]);
				}
			}
		pointarray=a;
		p_select.resize(pointarray.size());
	}
	clean();
	calcSize();
	}
}

void polygon::sizeadjustSelect(int valueX,int valueY){
if (select){
    QList<pointArray> l=pointarray.seperate();
	int outer=-1;
    for(int li=0; li<l.size();li++){
		//printf ("process %d\n",li);
		//printf ("angle before%f\n",l[li].angle());
		if (l[li].angle()>350) outer=li;
		double before=l[li].angle();
		l[li].sizeAdjust(valueX,valueY);
		//printf ("angle after%f %d\n",l[li].angle(),l[li].size());
		if ((abs((int)(l[li].angle()-before))>10)&&(li!=outer)) {
			l.removeAt(li);
			li--;
			//printf ("remove %d\n",li+1);
		}
	}
	if (outer==-1) {
		pointarray.sizeAdjust(valueX,valueY);
	}
	else if (l[outer].angle()<350){
	    pointarray.resize(2);
		pointarray.setPoint(1,pointarray.point(0));
		p_select.resize(2);
	}
	else {
		pointArray a=l[outer];
		QList<pointArray> l2;
		l2.clear();
		l.removeAt(outer);
		while (l.size()>0){
			int max=0;
			int maxX=l[max].maxX();
			for (int li=1; li<l.size();li++){
				if (maxX<l[li].maxX()) {max=li; maxX=l[max].maxX();}
			}
			l2.append(l[max]);
			l.removeAt(max);
		}
		l=l2;
		//for (int i=0; i<a.size();i++)
		//printf("a: %d ; %d\n",a.point(i).x()  , a.point(i).y());
		//printf ("use %d\n",outer);
		if (a.size()>2) 
		  for(int li=0; li<l.size();li++)
			//if (li!=outer)
				{
				// prüfen ob alle innerhalb sonst booleantool
				bool out=false;
				for (int k=0;k<l[li].size();k++)
				{
					if (!element::pointInPolygon(a,l[li].point(k))) out=true;
				}
				if (out) {
					//printf ("boolean %d %d\n",li,a.size());
					booleanHandler boolean;
					boolean.setA(&a);
					//printf ("set B %d %d\n",li,l[li].size());
					boolean.setB(&l[li]);
					QList<pointArray> pl=boolean.getAMinusB();
					if (pl.size()>=1) a=pl.at(0);
				}
				else
				{
				  a.add(&l[li]);
				}
			}
		pointarray=a;
		p_select.resize(pointarray.size());
	}
	clean();
	calcSize();
	}
}

void polygon::modifyCornersSelect(double value1,double value2){
if (select){
    QList<pointArray> l=pointarray.seperate();
	int outer=-1;
    for(int li=0; li<l.size();li++){
		//printf ("process %d\n",li);
		//printf ("angle before%f\n",l[li].angle());
		if (l[li].angle()>350) outer=li;
		double before=l[li].angle();
		l[li].modifyCorners(value1,value2);
		//printf ("angle after%f %d\n",l[li].angle(),l[li].size());
		if ((abs((int)(l[li].angle()-before))>10)&&(li!=outer)) {
			l.removeAt(li);
			li--;
			//printf ("remove %d\n",li+1);
		}
	}
	if (outer==-1) {
		pointarray.modifyCorners(value1,value2);
	}
	else if (l[outer].angle()<350){
	    pointarray.resize(2);
		pointarray.setPoint(1,pointarray.point(0));
		p_select.resize(2);
	}
	else {
		pointArray a=l[outer];
		QList<pointArray> l2;
		l2.clear();
		l.removeAt(outer);
		while (l.size()>0){
			int max=0;
			int maxX=l[max].maxX();
			for (int li=1; li<l.size();li++){
				if (maxX<l[li].maxX()) {max=li; maxX=l[max].maxX();}
			}
			l2.append(l[max]);
			l.removeAt(max);
		}
		l=l2;
		//for (int i=0; i<a.size();i++)
		//printf("a: %d ; %d\n",a.point(i).x()  , a.point(i).y());
		//printf ("use %d\n",outer);
		if (a.size()>2) 
		  for(int li=0; li<l.size();li++)
			//if (li!=outer)
				{
				// prüfen ob alle innerhalb sonst booleantool
				bool out=false;
				for (int k=0;k<l[li].size();k++)
				{
					if (!element::pointInPolygon(a,l[li].point(k))) out=true;
				}
				if (out) {
					//printf ("boolean %d %d\n",li,a.size());
					booleanHandler boolean;
					boolean.setA(&a);
					//printf ("set B %d %d\n",li,l[li].size());
					boolean.setB(&l[li]);
					QList<pointArray> pl=boolean.getAMinusB();
					if (pl.size()>=1) a=pl.at(0);
				}
				else
				{
				  a.add(&l[li]);
				  //printf ("add %d\n",li);
				}
			}
		pointarray=a;
		p_select.resize(pointarray.size());
	}
	clean();
	calcSize();
	}
}


void polygon::nextPoint(){
bool help=false;
for (int i=(int)pointarray.size()-1;i>0;i--) {
	if (p_select.testBit(i)){
	 p_select.clearBit(i);
	 if (i!=(int)pointarray.size()-1) {p_select.setBit(i+1);}
	  else {help=true;p_select.clearBit(0);}
	 if (i==(int)pointarray.size()-2){p_select.setBit(0);}
	}}
if (help) p_select.setBit(1);
}

void polygon::edgeRemoveSelect(int n){
double a;
for (int i=(int)pointarray.size()-1;i>0;i--) {
	if (p_select.testBit(i)||select){
		//a=(double)(pointarray.point(i).x()-pointarray.point(i-1).x());
		//b=(double)(pointarray.point(i).y()-pointarray.point(i-1).y());
		a=element::distance(pointarray.point(i),pointarray.point(i-1));
		//printf("%d %d\n",(int)a,n);
		if ((int)a<=n) {
			//printf("delete\n");
			if ((i==1)){pointarray.setPoint(pointarray.size()-1,pointarray.point(i));}
			deletePoint(i-1);}
	}}
calcSize();
}

void polygon::cropSharpAnglesSelect(int n){
double a,b;
for (int i=(int)pointarray.size()-2;i>0;i--) {
	//printf("%d : %f\n",i,angle(pointarray.point(i+1),pointarray.point(i),pointarray.point(i-1)));
	if (p_select.testBit(i)||select){
		a=angle(pointarray.point(i+1),pointarray.point(i),pointarray.point(i-1));
		if ((a<-90.001)&&(a>-179.999)){
			b=1.0/sin((180-fabs(a))*M_PI/360)*(n/2);
			//printf("%d : %f/%f\n",i,a,b);
			QPoint ph=pointarray.point(i);
			QPoint p2=pointarray.point(i)-pointarray.point(i+1);
			addPoint(i+1);
			pointarray.setPoint(i+1,ph-(p2*(b/element::length(p2))));
			p2=pointarray.point(i)-pointarray.point(i-1);
			pointarray.setPoint(i,ph-(p2*(b/element::length(p2))));
		}
	}}
if ((p_select.testBit(0)||select)&&(pointarray.size()>3)){
		a=angle(pointarray.point(1),pointarray.point(0),pointarray.point(pointarray.size()-2));
		if ((a<-90.001)&&(a>-179.999)){
			b=1.0/sin((180-fabs(a))*M_PI/360)*(n/2);
			QPoint ph=pointarray.point(0);
			QPoint p2=pointarray.point(0)-pointarray.point(1);
			QPoint p3=pointarray.point(0)-pointarray.point(pointarray.size()-2);
			addPoint(pointarray.size()-1);
			pointarray.setPoint(0,ph-(p2*(b/element::length(p2))));
			pointarray.setPoint(pointarray.size()-2,ph-(p3*(b/element::length(p3))));
			pointarray.setPoint(pointarray.size()-1,ph-(p2*(b/element::length(p2))));
		}
	}
calcSize();
}

void polygon::roundSelect(int n){
bool modified=false;
for (int i=(int)pointarray.size()-1;i>=0;i--) {
	if (p_select.testBit(i)||select){
		pointarray.setPoint(i,round(pointarray.point(i),n));
		modified=true;
	}}
if (modified) clean();
}

double polygon::areaSelected(){
  return pointarray.area();
/*
  double a=0;
  for (int i=0; i<pointarray.size()-1;i++){
  	a+=(double(pointarray.point(i).y()+pointarray.point(i+1).y())/2*(double(pointarray.point(i).x()-pointarray.point(i+1).x())));
  }
  if (a<0){a*=-1;}
  return a;*/
}

double polygon::circumferenceSelected(){
 return length();
}

bool polygon::pointInsideElement(QPoint p){
return pointInPolygon(pointarray,p);
}

double polygon::nearestDistance(QPoint p) {
   if (layers::num[layerNum].visible) {
    double dis=1.1E99;
    double d;
    for (int i=0; i<pointarray.size()-1;i++){
	d=distance(pointarray.point(i),p);
        if (d<dis) {
                 dis=d;
		 };
    }
    return dis;}
  else return 1.1E99;
}

bool polygon::isCircle(QPoint *p, int *radius){
//printf("test circle\n");
  if (pointarray.size()<10) return false;
  long long x,y;
  x=0;y=0;
  for (int i=1; i<pointarray.size();i++){
	x+=pointarray.point(i).x();
	y+=pointarray.point(i).y();
	}
  x=runden((double)x/(pointarray.size()-1));
  y=runden((double)y/(pointarray.size()-1));
  QPoint pc=QPoint(x,y);
  double d=distance(pc,pointarray.point(1));
  double sum=d;
  double min=d;
  double max=d;
  int offset=(int) (0.02*distance(pc,pointarray.point(0)))+10;
  for (int i=2; i<pointarray.size();i++){
	double d1=distance(pc,pointarray.point(i));
	sum+=d1;
	if (d1>max) { max=d1; if (max>d+offset) return false;};
	if (d1<min) { min=d1; if (min<d-offset) return false;};
	}
  (*p)=(pc);
  (*radius)=runden(sum/(pointarray.size()-1));
  offset=(int)(0.001*(*radius)+3);
  if ((*radius)<runden(max-offset)) return false;
  if ((*radius)>runden(min+offset)) return false;
  //double f=sum/(pointarray.size()-1);
  //printf("kreis min:%f max:%f d:%f r:%f \n",min,max,d,f);
  return true;
}

bool polygon::isSector(QPoint *p, int *radius, double *start,double *end){
  if (pointarray.size()<4) return false;
  QPoint pc=pointarray.point(pointarray.size()-2);
  double d=distance(pc,pointarray.point(0));
  double sum=d;
  double min=d;
  double max=d;
  int offset=(int) (0.02*distance(pc,pointarray.point(0)))+10;
  for (int i=1; i<pointarray.size()-2;i++){
	double d1=distance(pc,pointarray.point(i));
	sum+=d1;
	//printf("arc %f center: %d %d\n",d1,pc.x(),pc.y());
	if (d1>max) { max=d1; if (max>d+offset) return false;};
	if (d1<min) { min=d1; if (min<d-offset) return false;};
	}
  (*p)=(pc);
  (*radius)=runden(sum/(pointarray.size()-2));
  offset=(int)(0.001*(*radius)+3);
  if ((*radius)<runden(max-offset)) return false;
  if ((*radius)>runden(min+offset)) return false;
  (*start)=angle(pc,pointarray.point(0));
  if ((*start)<0) (*start)+=360;
  if ((*start)>359.95) (*start=0);
  (*end)=angle(pc,pointarray.point(pointarray.size()-3));
  if ((*end)<0) (*end)+=360;
  if ((*end)>359.95) (*end=0);
  double ah=angle(pc,pointarray.point(1));;
  if (ah<0) ah+=360;
  if ((*start)<(*end)){
	if ((ah>(*start))&&(ah< (*end))) {
	//ok
	}
	else {
	//swap
 	     ah=(*start);
	     (*start)=(*end);
	     (*end)=ah;
	}
	}
   else {
	if ((ah<(*start))&&(ah> (*end))){
	     ah=(*start);
	     (*start)=(*end);
	     (*end)=ah;
	}
	}

  //double f=sum/(pointarray.size()-1);
  //printf("arc min:%f max:%f d:%f r:%f \n",min,max,d,f);
  //printf("arc start:%f end:%f \n",(*start),(*end));
  //printf("center: %d %d radius: %d \n",pc.x(),pc.y(),(*radius));
  return true;
}

double polygon::nearestDistance(const QPoint p,QPoint *point)const {
   if (layers::num[layerNum].visible) {
    double dis=1.1E99;
    double d;
    for (int i=0; i<pointarray.size()-1;i++){
	d=distance(pointarray.point(i),p);
        if (d<dis) {
                 dis=d;
		 *point=pointarray.point(i);
		 };
    }
    return dis;}
  else return 1.1E99;
}

double polygon::nearestLine(QPoint p,QPoint *point,int) {
 if (layers::num[layerNum].visible) {
    double dis=1.1E99;
    double d;
    for (int i=0; i<pointarray.size()-1;i++){
    	QPoint h=pointarray.point(i)-pointarray.point(i+1);
	QPoint help=p+QPoint(-h.y(),h.x());
	cutPoint3(p,help,pointarray.point(i),pointarray.point(i+1),&h);
	d=distance(h,p);
	bool between=true;
	if ((h.x()<pointarray.point(i).x())&&(h.x()<pointarray.point(i+1).x())) between=false;
	if ((h.x()>pointarray.point(i).x())&&(h.x()>pointarray.point(i+1).x())) between=false;
	if ((h.y()<pointarray.point(i).y())&&(h.y()<pointarray.point(i+1).y())) between=false;
	if ((h.y()>pointarray.point(i).y())&&(h.y()>pointarray.point(i+1).y())) between=false;
            if ((d<dis)&&between) {
                 dis=d;
		 *point=h;
		 };
    }
    return dis;}
  else return 1.1E99;
}

double polygon::nearestMiddle(QPoint p,QPoint *point,int) {
 if (layers::num[layerNum].visible) {
    double dis=1.1E99;
    double d;
    for (int i=0; i<pointarray.size()-1;i++){
    	QPoint help=(pointarray.point(i)+pointarray.point(i+1))/2;
	d=distance(help,p);
        if (d<dis) {
                 dis=d;
		 *point=help;
		 };
    }
    return dis;}
  else return 1.1E99;
}

double polygon::nearestCenter(QPoint p,QPoint *point,int) {
  if (layers::num[layerNum].visible) {
   QPoint center=QPoint(0,0);
   for (int i=0; i<pointarray.size()-1;i++){
	center+=pointarray.point(i);
	}
   center/=(int)(pointarray.size()-1);
   *point=center;
   return distance(p,center);
  }
  else return 1.1E99;
}


bool polygon::showProperties(elementList *el, drawingField *d,bool basicEditing){
  polygonproperties b(d->userunits);
  b.setElement(el->thisElement->getPolygon(),basicEditing);
  b.show();
  int i=b.exec();
  b.hide();
  switch (i) {
  case QDialog::Rejected :
  	return false;
  case QDialog::Accepted :
  	clean();
  	return false;
  case 2 :
  	return true;
  case 3 :
        elementList *e;
	e=new elementList();
	e->nextElement=el->nextElement;
	e->thisElement=convertToBox();
	el->nextElement=e;
	if (e->thisElement!=NULL) return true;
	return false;
  }
  return false;
}

bool polygon::identicalStructure(element *e){
	if (e->isPolygon()) {
	polygon *b=reinterpret_cast<polygon(*)>(e);
	if ((*b)%(*this)) return true;
	}
return false;
}

bool operator% (const polygon &b1,const polygon &b2){
if (b1.layerNum!=b2.layerNum) return false;
if (b1.datatype!=b2.datatype) return false;
if (b1.pointarray.size()!=b2.pointarray.size()) return false;
bool b=true;
for (int i=0;i<b1.pointarray.size();i++){
	int p1=0;
	int p2=i;
	QPoint off=b1.pointarray.point(p1)-b2.pointarray.point(p2);
	b=true;
	while ((b1.pointarray.point(p1)==b2.pointarray.point(p2)+off)&&(p1<(b2.pointarray.size()-1))){
		p1++;
		p2++;
		if (p2>=b2.pointarray.size()) p2=1;
		if (p1>=b1.pointarray.size()) p1=1;
		}
	if ((p1==(b1.pointarray.size()-1))) return true;
	}
return false;
}

bool polygon::identical(element *e){
if (e->isPolygon()) {
	polygon *b=reinterpret_cast<polygon(*)>(e);
	if ((*b)==(*this)) return true;
	}
return false;
}

bool operator== (const polygon &b1,const polygon &b2){
if (b1.layerNum!=b2.layerNum) return false;
if (b1.datatype!=b2.datatype) return false;
if (b1.pointarray.size()!=b2.pointarray.size()) return false;
//bool b=true;
for (int i=0;i<b1.pointarray.size();i++){
	int p1=0;
	int p2=i;
	//b=true;
	while ((b1.pointarray.point(p1)==b2.pointarray.point(p2))&&(p1<(b2.pointarray.size()-1))){
		p1++;
		p2++;
		if (p2>=b2.pointarray.size()) p2=1;
		if (p1>=b1.pointarray.size()) p1=1;
		}
	if ((p1==(b1.pointarray.size()-1))) return true;
	}
return false;
}

double polygon::length(){
double l=0;
QPoint p=pointarray.point(0);
for (int i=1;i<pointarray.size();i++){
	l+=element::length(pointarray.point(i)-p);
	p=pointarray.point(i);
	}
return l;
}

void  polygon::findEdge(QPoint p1, QPoint p2,int layer,char dir,int *result){
if (layer!=layerNum) return;
QPoint pa;
pa=pointarray.point(0);
switch(dir){
	case 0:
		if (pointInPolygon(pointarray,QPoint(p1.x(),p2.y()))) return;
		if (pointInPolygon(pointarray,p1)) return;
		for (int i=1;i<pointarray.size();i++){
			QPoint p=pointarray.point(i);
			if ((p.y()>p2.y())&&(pa.y()<p1.y())){
			if ((p.x()==pa.x())&&(p.y()>pa.y())&&(p.x()>(*result))&&(p.x()<p1.x()))
				*result=p.x();
			else if ((p.x()>(*result))&&(p.x()>p2.x())&&(p.x()<p1.x())&&(p.y()<p1.y()))
				*result=p.x();
			}
			pa=p;
		}
		break;
	case 1:
		if (pointInPolygon(pointarray,QPoint(p2.x(),p1.y()))) return;
		if (pointInPolygon(pointarray,p1)) return;
		for (int i=1;i<pointarray.size();i++){
			QPoint p=pointarray.point(i);
			if ((pa.x()>p2.x())&&(p.x()<p1.x())){
			if ((p.y()==pa.y())&&(p.x()<pa.x())&&(p.y()>(*result))&&(p.y()<p1.y()))
				*result=p.y();
			else if ((p.y()>(*result))&&(p.y()>p2.y())&&(p.y()<p1.y())&&(p.x()>p2.x()))
				*result=p.y();
			}
			pa=p;
		}
		break;
	case 2:
		if (pointInPolygon(pointarray,QPoint(p2.x(),p1.y()))) return;
		if (pointInPolygon(pointarray,p2)) return;
		for (int i=1;i<pointarray.size();i++){
			QPoint p=pointarray.point(i);
			if ((pa.y()>p2.y())&&(p.y()<p1.y())){
			if ((p.x()==pa.x())&&(p.y()<pa.y())&&(p.x()<(*result))&&(p.x()>p2.x()))
				*result=p.x();
			else if ((p.x()<(*result))&&(p.x()>p2.x())&&(p.x()<p1.x())&&(p.y()>p2.y()))
				*result=p.x();
			}
			pa=p;
		}
		break;
	case 3:
		if (pointInPolygon(pointarray,QPoint(p1.x(),p2.y()))) return;
		if (pointInPolygon(pointarray,p2)) return;
		for (int i=1;i<pointarray.size();i++){
			QPoint p=pointarray.point(i);
			if ((p.x()>p2.x())&&(pa.x()<p1.x())){
			if ((p.y()==pa.y())&&(p.x()>pa.x())&&(p.y()<(*result))&&(p.y()>p2.y()))
				*result=p.y();
			else if ((p.y()<(*result))&&(p.y()>p2.y())&&(p.y()<p1.y())&&(p.x()<p1.x()))
				*result=p.y();
			}
			pa=p;
		}
		break;
}
}

void polygon::lineDistanceLayer(QPoint p1,QPoint p2, int *left,int *right,int layer, QPoint min, QPoint max){
    if (layer!=layerNum) return;
    if (pointarray.size()==0) return;
    QPoint minP,maxP;
    minP=pointarray.point(0);
    maxP=minP;
    QPoint p;
    for (int i=0;i<pointarray.size();i++) {
        p=pointarray.point(i);
        if (p.x()<minP.x()) minP.setX(p.x());
        if (p.y()<minP.y()) minP.setY(p.y());
        if (p.x()>maxP.x()) maxP.setX(p.x());
        if (p.y()>maxP.y()) maxP.setY(p.y());
    }
    if (max.x()<minP.x())return ;
    if (min.x()>maxP.x())return ;
    if (max.y()<minP.y())return ;
    if (min.y()>maxP.y())return ;
    pointarray.lineDistance(p1,p2,left,right);
}

bool polygon::pointOnLayer(QPoint p,int layer){
    if (layer!=layerNum) return false;
    if (pointarray.size()==0) return false;
    QPoint p2=pointarray.point(0);
    if (p2.x()-size > p.x()) return false;
    if (p2.y()-size > p.y()) return false;
    if (p2.x()+size < p.x()) return false;
    if (p2.y()+size < p.y()) return false;
    if (element::pointInPolygon(pointarray,p)) return true;
return false;
}

/*bool polygon::add(pointArray *array){
  if (array->size()==0) return false;
  if (pointInPolygon(*array,pointarray.point(0))){
  	pointArray help=(*array);
	*array=pointarray;
	pointarray=help;
	p_select.resize(pointarray.size());
	clearAllPSelect(); 
	//clean();
	}
  else if (!pointInPolygon(pointarray,array->point(0))) {  //printf("no insert\n");
  	return false;}
  //printf("insert\n");
  QPoint p=array->point(0);
  int index=0;
  for (int i=1; i<array->size()-1;i++){
  	if (array->point(i).x()>p.x()) {
		p=array->point(i);
		index=i;
		}
	}
  float dist=99999999.0;
  int pos=-1;
  QPoint pc,padd;
  for (int k=0;k<pointarray.size()-1;k++) {
  	if (cutPoint(pointarray.point(k),pointarray.point(k+1),p,QPoint((1<<30),p.y()),&pc)){
		if (distance(p,pc)<dist) {
                            dist=distance(p,pc);
                            pos=(int)k;
                            padd=pc;
                        }
		}
	}
  if (pos==-1) { //printf("error\n");
  	return false;}
  //printf("insert at %d\n",pos);
  uint neugross,altgross;
  //printf("pointarray: %d array: %d insert pos: %d\n",pointarray.size(),array->size(),pos);
  altgross=pointarray.size();
  neugross=pointarray.size()+array->size()+4;
  pointarray.resize(neugross);
  p_select.resize(neugross);
               //printf("a: %d n: %d\n",altgross,neugross);
		
  for (int i=neugross;i>pos+array->size()+4;i--) {
  	pointarray.setPoint(i-1,pointarray.point(altgross-neugross+i-1));
                     //printf("3 %d %d\n",i-1,altgross-neugross+i-1);
                     //printf("p %d %d\n",pointarray.point(altgross-neugross+i-1).x(),pointarray.point(altgross-neugross+i-1).y());
        }
  //printf("3a pc %d \n",pos+array->size()+3);
  pointarray.setPoint(pos+array->size()+3,padd);
  pointarray.setPoint(pos+array->size()+4,padd);
  for (int i=index;i<array->size();i++) {
    	pointarray.setPoint(pos+i-index+2,array->point(i));
                     //printf("4 %d %d\n",pos+i-index+2,i);
                     //printf("p %d %d\n",array->point(i).x(),array->point(i).y());
        }
  for (int i=0;i<=(int)index;i++) {
        pointarray.setPoint(pos+array->size()-index+i+2,array->point(i));
                     //printf("5 %d %d\n",pos+array->size()-index+i+2,i);
                     //printf("p %d %d\n",array->point(i).x(),array->point(i).y());
        }
  //printf("3a pc %d \n",pos+1);
  pointarray.setPoint(pos+1,padd);
  //printf("p %d %d\n",padd.x(),padd.y());
  //printf("end add\n");
  clean();
  clearAllPSelect();
  return true;	
}
*/

void polygon::snapSelectGet(QHash<int,QPoint> *h){
     if (select) {
       
     } else {
	for (int i=(int)pointarray.size()-2;i>=0;i--) {
	    if (!p_select.testBit(i)) {
	        QList<QPoint> l=h->values(pointarray.point(i).x());
		if (!l.contains(pointarray.point(i))) h->insertMulti(pointarray.point(i).x(),pointarray.point(i));
	    }
	}
     }
}

void polygon::snapSelectSnap(QHash<int,QPoint> *h,int radius){
  bool moved=false;
     for (int i=(int)pointarray.size()-1;i>=0;i--) {
	    if (p_select.testBit(i)||select) {
	        double snapdist=radius+1;
		bool snaped=false;
		int x1=pointarray.point(i).x();
		QPoint snapTo;
		for (int x=0;x<=radius;++x){
		  QList<QPoint> l=h->values(x1+x);
		  if (x!=0) l<<h->values(x1-x);
		  for (int k=l.size();k>0;--k){
		    if (distance(pointarray.point(i),l.at(k-1))<snapdist){
		      snaped=true; moved=true; snapdist=distance(pointarray.point(i),l.at(k-1));
		      snapTo=l.at(k-1);
		    }
		  }
		}
		if (snaped)
		  pointarray.setPoint(i,snapTo);
		else{
		  QList<QPoint> l=h->values(pointarray.point(i).x());
                  if (!l.contains(pointarray.point(i))) h->insertMulti(pointarray.point(i).x(),pointarray.point(i));
		}
	    }

     }
  if (moved) clean();
}
