package com.pixelmaid.dresscode.drawing.math;
import java.util.ArrayList;
import com.pixelmaid.dresscode.drawing.datatype.Point;
import com.pixelmaid.dresscode.drawing.primitive2d.ComplexPolygon;
import com.pixelmaid.dresscode.drawing.primitive2d.Drawable;
import com.pixelmaid.dresscode.drawing.primitive2d.Polygon;
import com.seisw.util.geom.Point2D;
import com.seisw.util.geom.PolyDefault;
import com.seisw.util.geom.Poly;
import com.seisw.util.geom.Clip;
public class PolyBoolean{
//merges a group of objects into one
/*public static Drawable merge(Drawable d) {
//Point origin = d.getOrigin();
Drawable master;
Poly group = drawableToBoolean(d);
if(group.getNumInnerPoly()==1){
//Poly i_Poly = clip.intersection(group.getInnerPoly(0));
//master = booleanToPolygon(i_Poly);
//System.out.println("PolyBoolean has only one polygon result");
//master.setRelativeTo(Geom.findCentroid((Polygon)master));
return d;
}
else{
Poly mP = new PolyDefault();
for( int i = 0 ; i < group.getNumInnerPoly() ; i++ )
{
Poly ip = group.getInnerPoly(i);
mP = mP.union(ip);
}
master = booleanToDrawable(mP);
//master.moveTo(origin.getX(), origin.getY());
return master;
}
}
*/
public static Drawable merge(Drawable d) {
Drawable group = d;
if(group.numChildren()==1){
return group.removeFromGroup(0);
}
else{
Drawable master = group.removeFromGroup(0);
int count =0;
while(group.numChildren()!=0){
System.out.println("current merge count="+count);
count++;
Drawable m1 = group.removeFromGroup(0);
master = union(master,m1);
}
return master;
}
}
//performs union of two polygons and returns the result
public static Drawable union(Drawable a, Drawable b){
Drawable result = unionRecur(a,b);
result.copyStyleParams(a,result);
return result;
}
private static Drawable unionRecur(Drawable d1, Drawable d2){
if(d1.numChildren()!=0 && !(d1 instanceof ComplexPolygon)){
Drawable child1 = d1.removeFromGroup(0);
d1 = unionRecur(d1,child1);
}
if(d2.numChildren()!=0&& !(d2 instanceof ComplexPolygon)){
Drawable child1 = d2.removeFromGroup(0);
d2 = unionRecur(d2,child1);
}
return unionSimple(d1,d2);
}
public static Drawable unionSimple(Drawable a, Drawable b){
BooleanPoly a_Poly = drawableToBoolean(a.copy());
BooleanPoly b_Poly = drawableToBoolean(b.copy());
BooleanPoly o_Poly = (BooleanPoly)a_Poly.union(b_Poly);
Drawable unionPoly = booleanToDrawable(o_Poly);
if(unionPoly.numChildren()>1&&!(unionPoly instanceof ComplexPolygon)){
Drawable d = new Drawable();
d.addToGroup(a);
d.addToGroup(b);
return(d);
}
else{
return unionPoly;
}
//Drawable a_d = booleanToDrawable(a_Poly);
//Drawable b_d = booleanToDrawable(b_Poly);
//return a_d;
//return booleanToDrawable(o_Poly);
}
//performs difference of two polygons and returns the result
public static Drawable difference(Drawable a, Drawable b) {
BooleanPoly a_Poly = drawableToBoolean(a);
BooleanPoly b_Poly = drawableToBoolean(b);
Poly o_Poly = a_Poly.difference(b_Poly);
Drawable result = booleanToDrawable(o_Poly);
result.copyStyleParams(a,result);
return result;
}
//performs difference of two polygons and returns the result
public static Drawable xor(Drawable a, Drawable b) {
BooleanPoly a_Poly = drawableToBoolean(a);
BooleanPoly b_Poly = drawableToBoolean(b);
Poly o_Poly = a_Poly.xor(b_Poly);
//System.out.println("oPoly.size="+o_Poly.getNumPoints());
Drawable result = booleanToDrawable(o_Poly);
result.copyStyleParams(a,result);
return result;
}
//performs difference of two polygons and returns the result
public static Drawable intersection(Drawable a, Drawable b) {
System.out.println("intersection");
a = a.toPolygon();
b = b.toPolygon();
if(a.numChildren()>0){
System.out.println("num children a > 0");
a = a.getChildren().get(0);
}
BooleanPoly a_Poly = polygonToBoolean((Polygon)a);
BooleanPoly b_Poly;
if(b.numChildren()<=0){
System.out.println("num children b = 0");
b_Poly = polygonToBoolean((Polygon)b);
Poly c_Poly = a_Poly.intersection(b_Poly);
if(!c_Poly.isEmpty()){
Drawable m = booleanToPolygon(c_Poly);
if(m!=null){
m.copyStyleParams(b,m);
return m;
}
}
return null;
}
else{
Drawable m = new Drawable();
System.out.println("num children b ="+b.numChildren());
ArrayList<Drawable> c = b.getChildren();
for(int i=0;i<c.size();i++){
b_Poly = polygonToBoolean((Polygon)c.get(i));
Poly c_Poly = a_Poly.intersection(b_Poly);
if(!c_Poly.isEmpty()){
Polygon nc = booleanToPolygon(c_Poly);
if(nc!=null){
m.addToGroup(nc);
}
}
}
m.copyStyleParams(b,m);
return m;
}
}
/*
//performs difference of two polygons and returns the result
public static Drawable intersection(Drawable a, Drawable b) {
a = a.toPolygon();
b = b.toPolygon();
if(a.numChildren()!=0){
//Window.output.setText("first object must be a single object, not a group for intersection");
System.err.println("first object must be a single object, not a group for intersection");
return null;
}
else{
System.out.println("first object is a single polygon");
BooleanPoly a_Poly = polygonToBoolean((Polygon)a);
System.out.println("only clipping with single poly");
BooleanPoly b_Poly;
if(b instanceof ComplexPolygon){
b_Poly = complexPolygonToBoolean((ComplexPolygon)b);
Poly o_Poly = Clip.intersection(a_Poly,b_Poly);
System.out.println("holes for o poly="+ o_Poly.getNumInnerPoly());
Polygon returnPoly = booleanToPolygon(o_Poly);
return returnPoly;
}
else if(b.numChildren()==0){
b_Poly = polygonToBoolean((Polygon)b);
Poly o_Poly = Clip.intersection(a_Poly,b_Poly);
System.out.println("holes for o poly="+ o_Poly.getNumInnerPoly());
if(!o_Poly.isEmpty()){
Polygon returnPoly = booleanToPolygon(o_Poly);
returnPoly.copyStyleParams(a,returnPoly);
return returnPoly;
}
return null;
}
else{
b_Poly = drawableToBoolean(b);
Drawable result = groupIntersection(a_Poly,b_Poly);
//result.copyStyleParams(a,result);
return result;
}
}
}
*/
// performs intersection on a group of objects
private static Drawable groupIntersection(BooleanPoly clip, BooleanPoly group){
Drawable master = new Drawable();
if(group.getNumInnerPoly()==1){
Poly i_Poly = clip.intersection(group.getInnerPoly(0));
master = booleanToPolygon(i_Poly);
//System.out.println("PolyBoolean has only one polygon result");
//master.setRelativeTo(Geom.findCentroid((Polygon)master));
}
else{
System.out.println("number of inner poly>1");
for( int i = 0 ; i < group.getNumInnerPoly() ; i++ )
{
Poly ip = group.getInnerPoly(i);
Poly i_Poly = clip.intersection(ip);
if(!i_Poly.isEmpty()){
Polygon p = booleanToPolygon(i_Poly);
master.addToGroup(p);
}
}
}
return master;
}
//converts drawable to collection of boolean operation polygons
private static BooleanPoly drawableToBoolean(Drawable d){
//d = d.condense();
BooleanPoly m_Poly = new BooleanPoly(); // master level polygon
d = d.toPolygon();
if(d.numChildren()==0 && (d instanceof Polygon)){
Poly p = polygonToBoolean((Polygon)d);
m_Poly.add(p);
}
else{
for(int j=0;j<d.children.size();j++){
Poly bP;
if(d.children.get(j) instanceof ComplexPolygon){
ComplexPolygon p = (ComplexPolygon)d.children.get(j);
bP = complexPolygonToBoolean(p);
}
else{
System.out.println("d check:");
System.out.println(d);
Polygon p = (Polygon)d.children.get(j);
bP = polygonToBoolean(p);
if(p.isHole()){
bP.setIsHole(true);
}
//}
}
m_Poly.add(bP);
}
}
//System.out.println("master poly Bounds="+m_Poly.getX(0)+","+m_Poly.getBounds().getWidth());
return m_Poly;
}
/*
//converts single polygon to single boolean operation polygon
private static BooleanPoly complexPolygonToBoolean(ComplexPolygon cp){
BooleanPoly
for(int j=0;j<cp.numChildren();j++){
Polygon p = (Polygon)cp.removeFromGroup(j);
p.setPointsAbsolute();
ArrayList<Point> pPoints = p.getPoints();
//temp polygon to be stored in master polygon
BooleanPoly p_Poly = new BooleanPoly();
//add all polygon points to temp polygon
for(int i=0;i<pPoints.size();i++)
{
p_Poly.add( new Point2D(pPoints.get(i).getX(),pPoints.get(i).getY()) );
}
//add all polygon holes to temp polygon
}
return p_Poly;
}*/
//converts single polygon to single boolean operation polygon
private static BooleanPoly polygonToBoolean(Polygon p){
p.setPointsAbsolute();
ArrayList<Point> pPoints = p.getPoints();
//temp polygon to be stored in master polygon
BooleanPoly p_Poly = new BooleanPoly();
//add all polygon points to temp polygon
for(int i=0;i<pPoints.size();i++)
{
p_Poly.add( new Point2D(pPoints.get(i).getX(),pPoints.get(i).getY()) );
}
//add all polygon holes to temp polygon
return p_Poly;
}
private static BooleanPoly complexPolygonToBoolean(ComplexPolygon cp){
BooleanPoly masterPoly = new BooleanPoly();
for(int j=0;j<cp.numChildren();j++){
Polygon p = (Polygon)cp.removeFromGroup(j);
p.setPointsAbsolute();
ArrayList<Point> pPoints = p.getPoints();
//temp polygon to be stored in master polygon
BooleanPoly p_Poly = new BooleanPoly();
//add all polygon points to temp polygon
for(int i=0;i<pPoints.size();i++)
{
p_Poly.add( new Point2D(pPoints.get(i).getX(),pPoints.get(i).getY()) );
}
if (p.isHole()){
p_Poly.isHole();
}
//add all polygon holes to temp polygon
masterPoly.add(p_Poly);
}
return masterPoly;
}
//converts boolean operation collection of polygons to drawable
private static Drawable booleanToDrawable(Poly poly){
Drawable master = new Drawable();
if(poly.getNumInnerPoly()==1){
master = booleanToPolygon(poly.getInnerPoly(0));
}
else{
int polyCount =0;
int polyIndex;
ComplexPolygon cp = new ComplexPolygon();
System.out.println("Number of inner poly="+poly.getNumInnerPoly());
for( int i = 0 ; i < poly.getNumInnerPoly() ; i++ )
{
Poly ip = poly.getInnerPoly(i);
Polygon p = booleanToPolygon(ip);
if(ip.isHole()){
p.toHole();
}
else{
polyCount++;
polyIndex=i;
}
master.addToGroup(p.copy());
cp.addToGroup(p);
}
if(polyCount ==1){
return cp;
}
}
return master;
}
//converts single boolean operation polygon to single polygon
private static Polygon booleanToPolygon(Poly ip)
{
Polygon jp = new Polygon();
//System.out.println("NUM OF INNER POLY="+ip.getNumInnerPoly());
//System.out.println("PolyBoolean has " + ip.getNumInnerPoly()+" holes");
for( int i = 0 ; i < ip.getNumInnerPoly() ; i++ )
{
Poly ipp = ip.getInnerPoly(i);
//System.out.println("found a non hole");
for( int j = 0 ;j < ipp.getNumPoints(); j++ )
{
jp.addPoint( ipp.getX(j), ipp.getY(j));
}
}
//set all points relative to the centroid;
Point c;
try{
if(ip.isHole()){
jp.reversePoints();
}
c = Geom.findCentroid(jp);
if(c==null){
return null;
}
if(ip.isHole()){
jp.reversePoints();
}
//System.out.println("centroid of polygon="+c.getX()+","+c.getY());
jp.setPointsRelativeTo(c) ;
//System.out.println("holes for hole count="+holeCount);
return jp;
}
catch(IllegalStateException e){
return null;
}
}
}