//This file is part of SECONDO. //Copyright (C) 2004, University in Hagen, Department of Computer Science, //Database Systems for New Applications. //SECONDO 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. //SECONDO 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 SECONDO; if not, write to the Free Software //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package fuzzyobjects.composite; import fuzzyobjects.basic.*; import fuzzyobjects.simple.*; import java.util.Vector; import sj.lang.ListExpr; import java.io.*; /** * this class provides a implementation of * fuzzy spatial points * @author Thomas Behr */ public class FPoint implements CompositeObject{ /** the factor of scale */ protected double SF; /** * the set of fuzzy elementary objects * this set must be ordered */ protected SortedObjects feP; // the fuzzy elementary points /** the Bounding box of this FPoint */ protected BoundingBox BB = new BoundingBox(); /** set a new factor of scale * @param SF the new factor, must be greater then 0 * @result true if sucessfull */ public boolean setSF(double SF){ if (SF>0){ this.SF = SF; return true; } else return false; } /* returns the number of containing fuzzy elementary points */ public int getSize(){ return feP.getSize(); } public fEPoint getPointAt(int index){ if(index<0 || index >=feP.getSize()) return null; else return (fEPoint) feP.get(index); } /** * creates a new FPoint * whith given factor of scale */ public FPoint(double scale){ feP = new SortedObjects(); SF = scale; no++; } /** * creates a new FPoint * with a factor of scale of 1.0 */ public FPoint() { this(1.0); } /** * returns the current factor of scale */ public double getSF(){ return SF;} /** returns the bounding box of this point */ public BoundingBox getBoundingBox(){ return BB; } /** * returns the dimension of a point, * i.e. 0 */ public int getDim() { return 0; } /** * check whether this is a valid point * i.e. here is ckecked whether all containing fuzzy * elementary points * are valid and the factor of scale is greater then 0 */ public boolean isValid(){ return SF>0 & feP.allValid(); } /** * returns a readable representation of this fPoint */ public String toString(){ return "FPoint (SF="+SF+")\n"+feP.toString(); } /** prints out a representation of this FPoint to * the standard-oiutput * it's for debuggng only */ public void print(){ System.out.println(this); } /** computes the bounding boxc of this point */ private void computeBoundingBox(){ if(feP.isEmpty()) BB.setBox(0,0,0,0); else{ fEPoint FP = (fEPoint) feP.get(0); int minX = FP.getMinX(); int minY = FP.getMinY(); int maxX = FP.getMaxX(); int maxY = FP.getMaxY(); int cX,cY; for (int i=1;i maxX) maxX = cX; if(cY > maxY) maxY = cY; } BB.setBox(minX,minY,maxX,maxY); } } /** * inserted a new fuzzy elementary point to this FPoint * @param SP the fEPoint to inserted * @return * */ public boolean add(fEPoint SP){ boolean first = feP.isEmpty(); boolean ok = feP.insert(SP.copy()); if(ok) { // update bounding box if(!first){ int minX = BB.getMinX(); int minY = BB.getMinY(); int maxX = BB.getMaxX(); int maxY = BB.getMaxY(); if(minX>SP.getMinX()) minX = SP.getMinX(); if(minY>SP.getMinY()) minY = SP.getMinY(); if(maxX *
  • true if SP is containing in this *
  • false SP is not a element of this, nothing to update * */ public boolean update(fEPoint SP){ if(feP.update(SP.copy())){ int minX = BB.getMinX(); int minY = BB.getMinY(); int maxX = BB.getMaxX(); int maxY = BB.getMaxY(); if(minX>SP.getMinX()) minX = SP.getMinX(); if(minY>SP.getMinY()) minY = SP.getMinY(); if(maxXSP.getMinX()) minX = SP.getMinX(); if(minY>SP.getMinY()) minY = SP.getMinY(); if(maxX * overwrite(fEPoint) * @return true if (x,y,Z) is a valid fEPoint */ public boolean overwrite(int x, int y , double Z){ fEPoint P = new fEPoint(x,y,Z); boolean result = P.isValid(); if (result) overwrite(P); return result; } /** * deletes a fEPoint with Basic BP from this * @return true if this contains BP */ public boolean delete(BasicPoint BP){ boolean result = feP.delete(BP); if(result & ( BP.getMinX()==BB.getMinX() | BP.getMaxX()==BB.getMaxX() | BP.getMinY()==BB.getMinY() | BP.getMaxY()==BB.getMaxY() ) ) computeBoundingBox(); return result; } /** * computes all membershipvalues of this on (x,y) */ public double[] ZRel(double x, double y) { double[] Rel = new double[1]; Rel[0] = 0.0; if ( (int)x == x && (int)y==y){ // x and y are integers fEPoint P = (fEPoint) feP.search( new BasicPoint((int)x,(int)y) ); if (P!=null) Rel[0] = P.getZ(); } return Rel; } // ZRel /** * computes the minimal membershipvalue on (x,y) */ public double minZfkt(double x, double y){ double[] Rel = ZRel(x,y); double min = Rel[0]; for(int i=1;iRel[i]) min =Rel[i]; return min; } /** * computes the maximal membership-value on (x,y) */ public double maxZfkt(double x, double y){ double[] Rel = ZRel(x,y); double max = Rel[0]; for(int i=1;iRel[i]) min =Rel[i]; return min; } /** computes the maximal membership-value on BP */ public double maxZfkt(BasicPoint BP){ double[] Rel = ZRel(BP); double max = Rel[0]; for(int i=1;i ((fEPoint)feP.get(i)).getZ()) min = ((fEPoint)feP.get(i)).getZ(); return min; } } // minZ /** * returns a copy of this */ public FPoint copy(){ FPoint C = new FPoint(SF); C.feP = feP.copy(); C.BB = BB.copy(); return C; } /** * check whether this is containing elements */ public boolean isEmpty(){ return feP.isEmpty(); } /** * set the set of fEPoints from P1 equal to the set of P2 */ protected static void setfeP(FPoint P1, FPoint P2){ P1.feP = P2.feP; P1.BB = P2.BB; } /************************************************************* Operators *************************************************************/ /** computes the union from this with With */ public FPoint union(FPoint With){ return operator(With,UNION); } /** computes the scaled_union from this with With */ public FPoint scaledUnion(FPoint With){ FPoint result = operator(With,SCALEDUNION); result.norm(); return result; } /** computes the intersection from this with With */ public FPoint intersection(FPoint With){ return operator(With,INTERSECTION); } /** computes the scaled_intersection from this with With */ public FPoint scaledIntersection(FPoint With){ FPoint result = operator(With,SCALEDINTERSECTION); result.norm(); return result; } /** computes the operator add from this with With */ public FPoint add(FPoint With){ return operator(With,ADD); } /** computes the operator scaled_add from this with With */ public FPoint scaledAdd(FPoint With){ FPoint result = operator(With,SCALEDADD); result.norm(); return result; } /** computes the difference from this with With */ public FPoint difference(FPoint With){ return operator(With,SUBTRACT); } /** computes the scaled_difference from this with With */ public FPoint scaledDifference(FPoint With){ FPoint result = operator(With,SCALEDDIFFERENCE); result.norm(); return result; } /** computes the alpha-cut of this */ public FPoint alphaCut(double alpha, boolean strong){ FPoint result = new FPoint(SF); fEPoint Current; boolean isValid; double Z; for(int i=0; ialpha; else isValid = Z>= alpha; if(isValid) result.feP.insert(Current.copy()); } result.computeBoundingBox(); return result; } /** computes the number of elements in this */ public double basicCard(){ return feP.getSize(); } /** computes the weighted number of elements in this */ public double card(){ double result = 0; for(int i=0;i0 is nothing to do } // not the first coordinate } // current Point contains unprocessing coordinates } // for all Pts // all smallest Points are in Vector allSmallest and // the positions of this one are in Numbers if(!allready){ double Z=0; BasicPoint BP = (BasicPoint) ((fEPoint) allSmallest.get(0)).basic(); fEPoint CP; for(int i=0;i0 is nothing to do } // not the first coordinate } // current Point contains unprocessing coordinates } // for all Pts // all smallest Points are in Vector allSmallest and // the positions of this one are in Numbers if(!allready){ double Z=0; BasicPoint BP = (BasicPoint) ((fEPoint) allSmallest.get(0)).basic(); fEPoint CP; for(int i=0;i0) { newFEP=new fEPoint((BasicPoint)F1.basic(),Z); Goal.feP.insert(newFEP); } } } break; case SCALEDUNION : { fEPoint newfePoint; if (F1==null) newfePoint = new fEPoint((BasicPoint)F2.basic(), F2.getZ()*scale2); else if (F2==null) newfePoint=new fEPoint((BasicPoint)F1.basic(), F1.getZ()*scale1); else { Z = Math.max(F1.getZ()*scale1,F2.getZ()*scale2); newfePoint = new fEPoint((BasicPoint)F1.basic(), Z); } // else Goal.add(newfePoint); } break; // scaled union case SCALEDINTERSECTION : if (F1==null || F2==null) ; else { Z = Math.min(F1.getZ()*scale1, F2.getZ()*scale2); Goal.add(new fEPoint( (BasicPoint) F1.basic(),Z)); } break; case SCALEDADD : { if(F1==null) Goal.add(new fEPoint( (BasicPoint)F2.basic(), F2.getZ()*scale2)); else if(F2==null) Goal.add(new fEPoint( (BasicPoint)F1.basic(), F1.getZ()*scale1 )); else { Goal.add(new fEPoint((BasicPoint)F1.basic(), F1.getZ()*scale1 + F2.getZ()*scale2 )); } } break; case SCALEDDIFFERENCE : { if(F1==null) Goal.add(new fEPoint( (BasicPoint) F2.basic(), -F2.getZ()*scale2 )); else if(F2==null) Goal.add(new fEPoint( (BasicPoint) F1.basic(), F1.getZ()*scale1 )); else { Goal.add(new fEPoint( (BasicPoint) F1.basic(), F1.getZ()*scale1 - F2.getZ()*scale2 )); } } break; default : System.out.println("operator not implemented"); } // switch } // processElements /** * the 'template' for many operators * @param FP the second operand * @param op the operator */ protected FPoint operator(FPoint FP, int op){ // a kind of mergesort int my = 0; int fromFP = 0; // already processed int maxMy = feP.getSize(); // numbers of elements int maxFromFP = FP.feP.getSize(); FPoint result = new FPoint(1); fEPoint myFirst=null; // the first unprocessed elements fEPoint FPFirst=null; if(maxMy>0) // needed if a empty point is involve myFirst= (fEPoint) feP.get(0); if(maxFromFP>0) FPFirst = (fEPoint) FP.feP.get(0); if (maxMy >0 && maxFromFP>0){ myFirst = (fEPoint) feP.get(my); FPFirst = (fEPoint) FP.feP.get(fromFP); int compareResult; while(my 0){ processElements(null,SF,FPFirst,FP.SF,result,op); fromFP++; if(fromFPZmax) Zmax = Current.getZ(); if(Current.getZ() 0) Zmin=0; if(Zmax==0 & Zmin==0) feP.makeEmpty(); else{ double SFnew = Zmax - Zmin; SortedObjects newfePs= new SortedObjects(); double Z; fEPoint fePnew; for(int i=0;i0) newfePs.insert(fePnew); } // for SF = SFnew*SF; feP = newfePs; } computeBoundingBox(); } /************************************************************* * * * topological relationships * * * *************************************************************/ /************************************************************ * * * Topology in the basic * * * *************************************************************/ /** * returns a String representing the topological relationship * between this and P2 * if fuzzy is false the membershipvalues are not evaluated */ public String basicTopolRelationString(FPoint P2){ M9Int matrix = basicTopolRelation(P2); String result; if (matrix ==null) result="undefined"; else{ result = matrix.toString(); } return result; } // relations between 2 points /** * compute the topological relations of the basic between * this and P2 */ M9Int basicTopolRelation(FPoint P2){ if(this.isEmpty() | P2.isEmpty()) return null; M9Int result = new M9Int(); // the standard-entries for 2 points result.setValue(false,M9Int.BOUNDARY,M9Int.INTERIOR); result.setValue(false,M9Int.BOUNDARY,M9Int.BOUNDARY); result.setValue(false,M9Int.BOUNDARY,M9Int.EXTERIOR); result.setValue(false,M9Int.INTERIOR,M9Int.BOUNDARY); result.setValue(false,M9Int.EXTERIOR,M9Int.BOUNDARY); result.setValue(true,M9Int.EXTERIOR,M9Int.EXTERIOR); // compute the next intersections // merge sort like int currentThis=0; int currentP2=0; int maxThis = feP.getSize(); int maxP2 = P2.feP.getSize(); fEPoint FirstThis = (fEPoint)feP.get(0); fEPoint FirstP2 = (fEPoint)P2.feP.get(0); int compareResult; boolean ready = false; // all possible intersections are true ? while(currentThis0){ // a (basic)Point of P2 is in the exterior of this result.setValue(true,M9Int.EXTERIOR,M9Int.INTERIOR); currentP2++; if(currentP21){ result.setValue(true,M9Int.INTERIOR,M9Int.INTERIOR); } ready = result.getValue(M9Int.INTERIOR,M9Int.INTERIOR) & result.getValue(M9Int.INTERIOR,M9Int.BOUNDARY) & result.getValue(M9Int.INTERIOR,M9Int.EXTERIOR); // all 3 entrys are true, this is no change more possible } // intersection exterior of Point / boundary of Line FPoint LB = Line.boundary(); ready =false; fEPoint inThis; for(int i=0;i no more changes } // for return result; } /** * returns the topological relationship between this and a *composite Object(FPoint,FLine or FRegion) **/ public M9Int basicTopolRelation(CompositeObject CO){ if(CO instanceof FPoint) return basicTopolRelation( (FPoint) CO); if(CO instanceof FLine) return basicTopolRelation( (FLine) CO); if( CO instanceof FRegion) return basicTopolRelation((FRegion) CO); return null; } /********************************************************* * * * Topology on fuzzy objects * * * *********************************************************/ /** computes the fuzzy top. Relation between this and P2 */ public FuzzyTopRel topolRelation(FPoint P2){ FuzzyTopRel result = new FuzzyTopRel(); int maxThis = feP.getSize(); int maxP2 = P2.feP.getSize(); int currentThis = 0; int currentP2 = 0; int compare; BasicPoint BP1,BP2; fEPoint Q1; fEPoint Q2; double Z1,Z2; while( currentThis0){ currentP2++; } if(compare==0){ Z1 = Q1.getZ(); Z2 = Q2.getZ(); // by definition are Z1 and Z2 greater then 0 if(Z1==Z2) result.setValue(3,true); if(Z1>Z2) result.setValue(4,true); if(Z2>Z1) result.setValue(5,true); currentThis++; currentP2++; } // compare==0 } // while return result; } /** computes the fuzzy top. Relation between this and L */ public FuzzyTopRel topolRelation(FLine L){ FuzzyTopRel result = new FuzzyTopRel(); int max = feP.getSize(); BasicPoint BP; fEPoint FP; double Z1,Z2; for(int current=0; current0){ if(Z1==Z2) result.setValue(3,true); if(Z1>Z2) result.setValue(4,true); if(Z2>Z1) result.setValue(5,true); } else { // Z2==0 result.setValue(1,true); } // else } // if } // for return result; } // topolRelation /** computes the fuzzy top. Relation between this and L */ public FuzzyTopRel topolRelation(FRegion R){ FuzzyTopRel result = new FuzzyTopRel(); int max = feP.getSize(); BasicPoint BP; fEPoint FP; double Z1,Z2; for(int current=0; current0){ if(Z1==Z2) result.setValue(3,true); if(Z1>Z2) result.setValue(4,true); if(Z2>Z1) result.setValue(5,true); } else { // Z2==0 result.setValue(1,true); } // else } // if } // for return result; } // topolRelation /** computes the topological relationship between this and CO */ public FuzzyTopRel topolRelation(CompositeObject CO){ if(CO instanceof FPoint) return topolRelation((FPoint)CO); if(CO instanceof FLine) return topolRelation((FLine)CO); if(CO instanceof FRegion) return topolRelation((FRegion)CO); return null; } /** returns the ListExpr representation of this FPoint * (SF , ()) */ public ListExpr toListExpr(){ // first create the PointList ListExpr Points; ListExpr Last=null; if(feP.getSize()==0) Points = ListExpr.theEmptyList(); else { Points = ListExpr.oneElemList( ((fEPoint)feP.get(0)).toListExpr()); Last = Points; } fEPoint NextPoint; for(int i=1;i*/ public ListExpr toTypedListExpr(){ return ListExpr.twoElemList( ListExpr.symbolAtom("fpoint"),toListExpr()); } /** read the FPoint from a String representation of a ListExpr * @return true if List is a String of a ListExpr containing * a correct FPoint */ public boolean readFromListString(String List){ ListExpr LE = new ListExpr(); if(LE.readFromString(List)!=0){ return false; } else{ return readFromListExpr(LE); } } /** compares two FPoints */ public int compareTo(FPoint P){ if(SFP.SF) return 1; return feP.compareTo(P.feP); } /** read this FPoint from a ListExpr * @return true if LE is a valid Representaion of a FPoint * all valid Points of this List are insertet */ public boolean readFromListExpr(ListExpr LE){ SF = 1.0; feP.makeEmpty(); computeBoundingBox(); if(LE==null) return false; if(LE.listLength()!=2) return false; ListExpr SFList = LE.first(); if( !( SFList.isAtom() && (SFList.atomType()==ListExpr.INT_ATOM || SFList.atomType()==ListExpr.REAL_ATOM))) return false; double z= SFList.atomType()==ListExpr.INT_ATOM ? SFList.intValue() : SFList.realValue(); if(z<=0) return false; this.SF = z; ListExpr Points = LE.second(); fEPoint P; boolean ok = true; while( !Points.isEmpty() & ok) { P = new fEPoint(0,0,0); if(P.readFromListExpr(Points.first())){ add(P); Points=Points.rest(); } else{ ok = false; } } return ok; } /** this method is used for reading a fuzzy point from * a byte array; * returns null if the construction of the object failed */ public static FPoint readFrom(byte[] buffer){ try{ ObjectInputStream ois; ois = new ObjectInputStream( new ByteArrayInputStream(buffer)); FPoint res = (FPoint) ois.readObject(); ois.close(); return res; } catch(Exception e){ return null; } } /** this method serialized an object */ public byte[] writeToByteArray(){ try{ ByteArrayOutputStream byteout; byteout = new ByteArrayOutputStream(feP.getSize()*16+25); ObjectOutputStream objectout; objectout = new ObjectOutputStream(byteout); objectout.writeObject(this); objectout.flush(); byte[] res = byteout.toByteArray(); objectout.close(); return res; } catch(Exception e){ return null; } } /** computes a hash-value for this FPoint */ public int getHashValue(){ return Math.abs((BB.getMaxX()-BB.getMinX())* (BB.getMaxY()-BB.getMinY())+BB.getMinX() +BB.getMinY()); } /** save the byte representation of this object in a file, *for debugging only */ public void save(){ String FileName = "fpoint"+no; try{ OutputStream out = new FileOutputStream(FileName); byte[] content = writeToByteArray(); System.out.println("write "+content.length+ " bytes to "+FileName); for(int i=0;i