Files
secondo/Algebras/Fuzzy/fuzzyobjects/composite/FLine.java

1955 lines
50 KiB
Java
Raw Normal View History

2026-01-23 17:03:45 +08:00
//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 Lines
* in the X-triangulation
* @author Thomas Behr
*/
public class FLine implements CompositeObject{
/**
* the factor of scale
*/
protected double SF;
/** the fuzzy segments */
protected SortedObjects fSeg;
/** returns the SortedObjects of this Line */
SortedObjects getSortedObjects(){
return fSeg;
}
/** remove all conataing segments */
public void clear(){
fSeg.makeEmpty();
}
/** returns the number of containing fuzzy segments */
public int getSize(){
return fSeg.getSize();
}
/* retuns the fuzzy segment at position index,
if this object not exists null is returned
*/
public fSegment getSegmentAt(int index){
if(index<0 || index>=fSeg.getSize())
return null;
return (fSegment) fSeg.get(index);
}
/** the bounding box */
protected BoundingBox BB = new BoundingBox();
/** returns the bounding box of this line */
public BoundingBox getBoundingBox(){ return BB; }
/** overwrite the given Path by a new FLine by
* linear aprox.
*/
public boolean overwritePath(Path P, double Start, double End){
if(P==null | Start<0 | Start>1 | End<0 | End>1)
return false;
else{
boolean removePath = (Start+End==0);
double length = P.getLength();
double currentLength = 0;
int max = P.getNumberOfSegments();
double delta = End-Start;
double CLength;
BasicSegment C;
double M1,M2;
BasicPoint BP;
for(int i=0;i<max;i++){
C = P.getSegment(i);
BP = P.getPoint(i);
CLength = C.length();
if (removePath){
fSeg.delete(C);
}
else {
M1 = Start+delta*(currentLength/length);
M2 = Start+delta*((currentLength+CLength)/length);
if(BP.equals( (BasicPoint) C.getEP1()))
overwrite(new fSegment(C,M1,M2));
else
overwrite(new fSegment(C,M2,M1));
}
currentLength += CLength;
}
return true;
} // else
}
/** computes the bounding box of this line */
private void computeBoundingBox(){
if(fSeg.isEmpty())
BB.setBox(0,0,0,0);
else{
SimpleObject FS = fSeg.get(0);
int minX = FS.getMinX();
int minY = FS.getMinY();
int maxX = FS.getMaxX();
int maxY = FS.getMaxY();
int cX,cY;
for (int i=1;i<fSeg.getSize();i++){
FS = fSeg.get(i);
cX = FS.getMinX();
cY = FS.getMinY();
if(cX < minX)
minX = cX;
if(cY < minY)
minY = cY;
cX = FS.getMaxX();
cY = FS.getMaxY();
if(cX > maxX)
maxX = cX;
if(cY > maxY)
maxY = cY;
}
BB.setBox(minX,minY,maxX,maxY);
}
}
/**
* creates a new FLine
* with scale as factor of scale
*/
public FLine(double scale){
fSeg = new SortedObjects();
SF = scale;
}
/** set the new factor of scale */
public boolean setSF(double SF){
if(SF>0){
this.SF=SF;
return true;
}
else return false;
}
/**
* creates a new FLine
* with 1 as factor of scale
*/
public FLine() {
this(1.0);
}
/** get the factor of scale */
public double getSF(){ return SF; }
/**
* get the dimension of a line
* i.e. 1
*/
public int getDim(){ return 1; }
/**
* is this a valid line in the X-triangulation ?
* i.e. check whether SF greater then 0 and all
* containing fuzzy segments are valid
*/
public boolean isValid(){
return SF>0 & fSeg.allValid();
}
/**
* returns a readable String of this FLine
*/
public String toString(){
return "FLine (SF="+SF+")\n" + fSeg.toString();
}
/**
* adds a new fuzzy Segment to this Line
* if this FLine contains a segment whith same basic as fS
* the fS not added and the result ist false
*/
public boolean add(fSegment fS){
boolean first = fSeg.isEmpty();
boolean ok = fSeg.insert(fS.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>fS.getMinX())
minX = fS.getMinX();
if(minY>fS.getMinY())
minY = fS.getMinY();
if(maxX<fS.getMaxX())
maxX = fS.getMaxX();
if(maxY<fS.getMaxY())
maxY = fS.getMaxY();
BB.setBox(minX,minY,maxX,maxY);
}
else
BB.setBox(fS.getMinX(),fS.getMinY(),
fS.getMaxX(),fS.getMaxY());
}
return ok;
}
/**
* updated a fuzzy Segments in this fLine
* if not a segment whith same basic as fS in this
* FLine then the result is false
*/
public boolean update(fSegment fS){
return fSeg.update(fS.copy());
}
/**
* updated/added a fuzzy Segment of this FLine
* if this FLine contains a Segment wthis same basic as fS
* then this Segment was updates
* else fS is added to this FLine
*/
public void overwrite(fSegment fS){
boolean first = fSeg.isEmpty();
if (! fSeg.update(fS))
fSeg.insert(fS);
if(!first){
int minX = BB.getMinX();
int minY = BB.getMinY();
int maxX = BB.getMaxX();
int maxY = BB.getMaxY();
if(minX>fS.getMinX())
minX = fS.getMinX();
if(minY>fS.getMinY())
minY = fS.getMinY();
if(maxX<fS.getMaxX())
maxX = fS.getMaxX();
if(maxY<fS.getMaxY())
maxY = fS.getMaxY();
BB.setBox(minX,minY,maxX,maxY);
}
else
BB.setBox(fS.getMinX(),fS.getMinY(),
fS.getMaxX(),fS.getMaxY());
}
/**
* creates a new fuzzy Segments from the Parameters and
* if this yield a valid fuzzy segment
* then invoked <A href="#overwrite(fSegment)">
* overwrite(fSegment) </A>
*/
public boolean overwrite(int x1,int y1,double Z1,
int x2,int y2,double Z2 ){
fSegment fS = new fSegment(x1,y1,Z1, x2,y2,Z2);
if (fS.isValid()){
overwrite(fS);
return true;
}
else return false;
}
/**
* deletes the fuzzy Segment from this FLine
* with basic BS
* returns false if this FLine not contains such fSegment
*/
public boolean delete(BasicSegment BS){
boolean ok = fSeg.delete(BS);
if(ok & ( BS.getMinX()==BB.getMinX() |
BS.getMaxX()==BB.getMaxX() |
BS.getMinY()==BB.getMinY() |
BS.getMaxY()==BB.getMaxY() ) )
computeBoundingBox();
return ok;
}
/**
* computes all membershipvalues on (x,y)
*/
public double[] ZRel(double x, double y) {
double[] result;
BasicSegment[] Segs = BasicSegment.getSegments(x,y);
if(Segs == null){
result = new double[1];
result[0]=0;
}
else{
Vector tmp = new Vector();
fSegment current;
Double Z;
for(int i=0;i<Segs.length;i++){
current = (fSegment) fSeg.search(Segs[i]);
if (current!=null){
Z = new Double(current.Zfkt(x,y));
if(!tmp.contains(Z))
tmp.add(Z);
}
else{
if(!tmp.contains(new Double(0)))
tmp.add(new Double(0));
}
}
if(tmp.size()==0){
result = new double[1];
result[0]=0;
}
else{
result=new double[tmp.size()];
for(int i=0;i<tmp.size();i++)
result[i] = ((Double)tmp.get(i)).doubleValue();
}
}
return result;
} // ZRel
/** computes all membershipvalues on BP */
public double[] ZRel(BasicPoint BP){
Vector tmp = new Vector();
BasicPoint[] Neightboors = BP.getNeightboors();
for(int i=0;i<Neightboors.length;i++){
fSegment fS= (fSegment) fSeg.search(
new BasicSegment(
BP,Neightboors[i]));
if(fS!=null)
tmp.add(new Double( fS.Zfkt(BP)));
} // for all Neighboors
double[] result = new double[tmp.size()];
for(int j=0;j<tmp.size();j++)
result[j] = ( (Double) tmp.get(j)).doubleValue();
return result;
}
/** computes the maximal membershipvalue on BP */
public double maxZfkt(BasicPoint BP){
double[] cand = ZRel(BP);
double result = 0;
for(int i=0;i<cand.length;i++)
if(cand[i]>result)
result=cand[i];
return result;
}
/** computes the maximal membershipvalue on (x,y) */
public double maxZfkt(double x, double y){
double[] values = ZRel(x,y);
double result =0;
for(int i=0;i<values.length;i++)
if (values[i]>result) result = values[i];
return result;
}
/** computes the minimal membershipvalue on (x,y) */
public double minZfkt(double x, double y){
double[] values = ZRel(x,y);
double result =1;
for(int i=0;i<values.length;i++)
if (values[i]<result) result = values[i];
return result;
}
/** computes the middle membershipvalue on (x,y) */
public double midZfkt(double x, double y){
double[] values = ZRel(x,y);
double result =0;
for(int i=0;i<values.length;i++)
result += values[i];
result = result / values.length;
return result;
}
/** computes the membershipvalue on BP by given basic element */
public double Zfkt(BasicPoint BP, BasicSegment BS){
fSegment Fs = (fSegment) fSeg.search(BS);
double result = 0;
if(Fs!=null) {
result = Fs.Zfkt(BP);
}
return result;
}
/** computes the membershipvalue on (x,y) by given
* basic segment
*/
public double Zfkt(double x, double y, BasicSegment BS){
double result = 0;
if (BS.contains(x,y)){
fSegment Fs = (fSegment) fSeg.search(BS);
if(Fs!=null) {
result = Fs.Zfkt(x,y);
}
}
return result;
}
/** returns all containing basic segments of this FLine
* the Segments of result are sorted*/
public BasicSegment[] basics() {
BasicSegment[] result = new BasicSegment[fSeg.getSize()];
if(fSeg.isEmpty())
return result;
else{
for(int i=0;i<fSeg.getSize();i++)
result[i] = (BasicSegment) (
(fSegment)fSeg.get(i)).basic();
}
return result;
} // basics
/** returns the maximal membershipvalue in this FLine */
public double maxZ(){
double max = 0.0;
fSegment current;
for(int i=0;i<fSeg.getSize();i++){
current = (fSegment) fSeg.get(i);
if (max < Math.max(current.getZ1(),current.getZ2() ))
max = Math.max(current.getZ1(), current.getZ2());
}
return max;
} // maxZ
/** returns the minimal membershipvalue in this FLine */
public double minZ(){
double min = 1.0;
fSegment current;
for(int i=0;i<fSeg.getSize();i++){
current = (fSegment) fSeg.get(i);
if (min > Math.min(current.getZ1(),current.getZ2()) )
min = Math.min(current.getZ1(), current.getZ2());
}
return min;
} // minZ
/** returns a copy from this FLine */
public FLine copy(){
FLine C = new FLine(SF);
C.fSeg = fSeg.copy();
C.BB = BB.copy();
return C;
}
/** check whether this FLine contains elements */
public boolean isEmpty(){
return fSeg.isEmpty();
}
/** set the containing segments from this on the same
* as L2's one
*/
protected static void setfSeg(FLine L1, FLine L2){
L1.fSeg = L2.fSeg;
L1.BB = L2.BB;
}
/** computes the selfcuts of this Line */
public BasicPoint[] selfcuts(){
BasicSegment Current;
BasicPoint BP;
int n;
boolean found;
Vector tmp = new Vector(fSeg.getSize());
for(int i=0;i<fSeg.getSize();i++){
Current = (BasicSegment) ((fSegment)fSeg.get(i)).basic();
BP = Current.getEP1();
n = numberOfSegments(BP);
if(n>2){
found=false;
for(int j=0;j<tmp.size();j++)
if( ( (BasicPoint) tmp.get(j)).equals(BP))
found=true;
if(!found)
tmp.add(BP);
}
BP = Current.getEP2();
n = numberOfSegments(BP);
if(n>2){
found=false;
for(int j=0;j<tmp.size();j++)
if( ( (BasicPoint) tmp.get(j)).equals(BP))
found=true;
if(!found)
tmp.add(BP);
} // if
} // for all containing segments
BasicPoint[] result = new BasicPoint[tmp.size()];
for(int i=0;i<result.length;i++)
result[i] = (BasicPoint) tmp.get(i);
return result;
} // selfcuts
/*************************************************************
Operators
*************************************************************/
/** the union of 2 FLines */
public FLine union(FLine With){
return operator(With,UNION);
}
/** the scaled union of 2 FLines */
public FLine scaledUnion(FLine With){
FLine result = operator(With,SCALEDUNION);
result.norm();
return result;
}
/** the intersectionof 2 FLines */
public FLine intersection(FLine With){
return operator(With,INTERSECTION);
}
/** the scaled intersection of 2 FLines */
public FLine scaledIntersection(FLine With){
FLine result = operator(With,SCALEDINTERSECTION);
result.norm();
return result;
}
/** added With to this FLine */
public FLine add(FLine With){
return operator(With,ADD);
}
/** added scaled Witdh to this FLine */
public FLine scaledAdd(FLine With){
FLine result = operator(With,SCALEDADD);
result.norm();
return result;
}
/** computes the difference from this FLine and With */
public FLine difference(FLine With){
return operator(With,SUBTRACT);
}
/** computes the scaled difference from this FLine and With */
public FLine scaledDifference(FLine With){
FLine result = operator(With,SCALEDDIFFERENCE);
result.norm();
return result;
}
/**
* computes the alpha-cut of this FLine
* i.e. removes all FSegments whith a middle membershipvalue
* less (less or equal) as alpha
*/
public FLine alphaCut(double alpha, boolean strong){
FLine CutL = new FLine(SF);
fSegment Current;
boolean isValid;
double midZ;
for(int i=0; i<fSeg.getSize(); i++){
Current = (fSegment) fSeg.get(i);
midZ = (Current.getZ1()+ Current.getZ2())/2;
if (strong)
isValid = midZ>alpha;
else
isValid = midZ>= alpha;
if(isValid)
CutL.fSeg.insert(Current.copy());
}
CutL.computeBoundingBox();
return CutL;
}
/**
* computes the length of the basic of this FLine
*/
public double basicLen(){
double sum = 0.0;
for(int i=0;i<fSeg.getSize();i++){
sum += ((BasicSegment) fSeg.get(i).basic()).length();
}
return sum;
}
/**
* computes the len of the 3d-structure of this FLine
*/
public double len3D(){
double sum = 0.0;
for(int i=0;i<fSeg.getSize();i++){
sum += ((fSegment) fSeg.get(i)).length();
}
return sum;
}
/**
* computes the weigthed length of this FLine
*/
public double length(){
double sum = 0.0;
double Z;
fSegment Current;
for(int i=0;i<fSeg.getSize();i++){
Current = (fSegment) fSeg.get(i);
Z = (Current.getZ1() + Current.getZ2())/2;
sum += Z*( (BasicSegment) Current.basic()).length();
}
return sum;
}
/**
* computes how similar is the basic of 2 FLines
*/
public double basicSimilar(FLine L2){
FLine Funion = this.union(L2);
FLine Fintersection = this.intersection(L2);
if (Funion.isEmpty())
return 1.0;
else
return Fintersection.basicLen() / Funion.basicLen();
}
/**
* how similar are 2 FLines ?
*/
public double similar(FLine L2){
FLine Funion = this.union(L2);
FLine Fintersection = this.intersection(L2);
if (Funion.isEmpty())
return 1.0;
else
return Fintersection.length() / Funion.length();
}
/**
* make this FLine sharp
* i.e. the membershipvalues of the result are ever 1.0
*/
public FLine sharp(){
FLine result = new FLine(1);
fSegment CurrentSegment;
for(int i=0;i<fSeg.getSize();i++){
CurrentSegment = new fSegment(
(BasicSegment)
(fSeg.get(i).basic()),1,1);
result.add(CurrentSegment);
}
return result;
}
/**
* computes the boundary of this FLine
*/
public FPoint boundary(){
return endPoints();
}
/**
* computes the boundary of this FLine
*/
public FPoint endPoints(){
FPoint result = new FPoint(1);
BasicSegment current;
BasicPoint EP1;
BasicPoint EP2;
BasicPoint[] Neightboors;
boolean found;
for(int i=0;i<fSeg.getSize();i++){
// a endPoint of each segment is a candidate
current = (BasicSegment) fSeg.get(i).basic();
EP1 = current.getEP1();
EP2 = current.getEP2();
// check EP1
Neightboors = EP1.getNeightboors();
found=false;
for(int j=0;j<Neightboors.length&!found;j++){
if(!EP2.equals(Neightboors[j])) {
// exclude current Basicsegment
found = fSeg.search(
new BasicSegment(EP1,Neightboors[j]))!=null;
}
}
if(!found) // EP1 is a endpoint
result.add(new fEPoint(EP1,1));
// check EP2
Neightboors = EP2.getNeightboors();
found=false;
for(int j=0;j<Neightboors.length&!found;j++){
if(!EP1.equals(Neightboors[j])) {
found = fSeg.search(
new BasicSegment(EP2,Neightboors[j]))!=null;
}
}
if(!found) // EP2 is a endpoint
result.add(new fEPoint(EP2,1));
}
return result;
}
/**
* computed the maximal connected part of this FLine
* containing FS
*/
private void getComponent(fSegment FS, FLine result){
// computes a connected part of a line
BasicSegment BS = (BasicSegment) FS.basic();
result.add(FS);
BasicSegment[] Neightboors = BS.getNeightboors();
for(int i=0;i<Neightboors.length;i++) {
if(result.fSeg.getPos(Neightboors[i])<0){ // not in result
fSegment NB = (fSegment) this.fSeg.search(Neightboors[i]);
if(NB!=null){
getComponent(NB,result);
}
}
}
}
public boolean equals(FLine L2){
return fSeg.equals(L2.fSeg) & SF==L2.SF;
}
/**
* computes the connected parts of this FLine
*/
public FLine[] faces(){
if(isEmpty()) return null;
Vector tmp = new Vector(); // for the faces ;
// use Vector hence number of faces unknow
FLine Copy = this.copy();
while( ! Copy.isEmpty()){
FLine nextFace = new FLine(SF);
fSegment First = (fSegment) Copy.fSeg.get(0);
getComponent(First,nextFace);
tmp.add(nextFace);
Copy = Copy.difference(nextFace);
}
FLine[] result = new FLine[tmp.size()];
for(int i=0;i<tmp.size();i++)
result[i] = (FLine) tmp.get(i);
return result;
}
/**
* check whether this FLine contains BP
*/
public boolean contains(BasicPoint BP){
// returns true, if BP a Point of this Line
return numberOfSegments(BP)>0;
}
/**
* check whether BP is on boundary of this FLine
*/
public boolean isEndPoint(BasicPoint BP){
return numberOfSegments(BP)==1;
}
/**
* returns the number of Basicsegments containing in this FLine
* having BP as endpoint
*/
public int numberOfSegments(BasicPoint BP){
BasicPoint[] Neightboors = BP.getNeightboors();
int found =0;
for(int i=0;i<Neightboors.length;i++)
if (fSeg.search(new BasicSegment(BP,Neightboors[i]))!=null)
found ++;
return found;
}
/**
* a implementation of the mid-operator for a set of FLines
*/
public static FLine mid(FLine[] Lns){
if(Lns.length==0) return null;
FLine result = new FLine(1);
int[] current = new int[Lns.length];
int[] max = new int[Lns.length];
boolean[] ready = new boolean[Lns.length];
boolean allready = true;
// initialize the variables
for(int i=0;i<Lns.length;i++){
current[i]=0;
max[i]= Lns[i].fSeg.getSize();
ready[i] = current[i]<max[i];
if(!ready[i]) allready=false;
}
Vector allSmallest = new Vector(); // the smallest Segments
Vector Numbers = new Vector(); // the positions in Lns
while(!allready){
allready=true;
allSmallest = new Vector();
Numbers = new Vector();
// search all smallest Segment
fSegment currentS;
BasicSegment compareS;
for(int i=0;i<Lns.length;i++){
if(current[i]<max[i]) {
allready=false;
currentS = (fSegment) Lns[i].fSeg.get(current[i]);
if(allSmallest.size()==0) {
allSmallest.add(currentS);
Numbers.add(new Integer(i));
}
else {
compareS = (BasicSegment)
((fSegment) allSmallest.get(0)).basic();
int comp = currentS.basic().compareTo(compareS);
if(comp==0) { // a Segement with smallest Basic
allSmallest.add(currentS);
Numbers.add(new Integer(i));
}
if(comp<0) { // new smallest Segment
allSmallest = new Vector();
Numbers = new Vector();
allSmallest.add(currentS);
Numbers.add(new Integer(i));
}
// in the case comp>0 is nothing to do
} // not the first Segment
} // current Line contains unprocessing Segments
} // for all Lines
if(!allready){
double Z1=0,Z2=0;
BasicSegment BS = (BasicSegment)
((fSegment) allSmallest.get(0)).basic();
fSegment CS;
for(int i=0;i<allSmallest.size();i++){
// update numbers
int c = ((Integer)Numbers.get(i)).intValue();
current[c]++;
CS = (fSegment) allSmallest.get(i);
Z1 += CS.getZ1();
Z2 += CS.getZ2();
}
Z1 = Z1 / Lns.length;
Z2 = Z2 / Lns.length;
result.fSeg.insert( new fSegment(BS,Z1,Z2));
}
} // while not all ready
result.computeBoundingBox();
return result;
}
/**
* a implementation of the scaled mid
* operator for a set of FLines
*/
public static FLine scaledMid(FLine[] Lns){
if(Lns.length==0) return null;
FLine result = new FLine(1);
int[] current = new int[Lns.length];
int[] max = new int[Lns.length];
boolean[] ready = new boolean[Lns.length];
boolean allready = true;
// initialize the variables
for(int i=0;i<Lns.length;i++){
current[i]=0;
max[i]= Lns[i].fSeg.getSize();
ready[i] = current[i]<max[i];
if(!ready[i]) allready=false;
}
Vector allSmallest = new Vector(); // the smallest Segments
Vector Numbers = new Vector(); // the positions in Lns
while(!allready){
allready=true;
allSmallest = new Vector();
Numbers = new Vector();
// search all smallest Segment
fSegment currentS;
BasicSegment compareS;
for(int i=0;i<Lns.length;i++){
if(current[i]<max[i]) {
allready=false;
currentS = (fSegment) Lns[i].fSeg.get(current[i]);
if(allSmallest.size()==0) {
allSmallest.add(currentS);
Numbers.add(new Integer(i));
}
else {
compareS = (BasicSegment)
((fSegment) allSmallest.get(0)).basic();
int comp = currentS.basic().compareTo(compareS);
if(comp==0) { // a Segement with smallest Basic
allSmallest.add(currentS);
Numbers.add(new Integer(i));
}
if(comp<0) { // new smallest Segment
allSmallest = new Vector();
Numbers = new Vector();
allSmallest.add(currentS);
Numbers.add(new Integer(i));
}
// in the case comp>0 is nothing to do
} // not the first Segment
} // current Line contains unprocessing Segments
} // for all Lines
if(!allready){
double Z1=0,Z2=0;
BasicSegment BS = (BasicSegment)
((fSegment) allSmallest.get(0)).basic();
fSegment CS;
for(int i=0;i<allSmallest.size();i++){
// update numbers
int c = ((Integer)Numbers.get(i)).intValue();
current[c]++;
CS = (fSegment) allSmallest.get(i);
Z1 += CS.getZ1()*Lns[c].SF;
Z2 += CS.getZ2()*Lns[c].SF;
}
Z1 = Z1 / Lns.length;
Z2 = Z2 / Lns.length;
result.fSeg.insert( new fSegment(BS,Z1,Z2));
}
} // while not all ready
result.norm();
result.computeBoundingBox();
return result;
}
/**
* computes the common points of 2 FLines
* i.e. Points containing in this and L2 <b>and </b>
* not endpoint of a common segment of this FLines
*/
public FPoint commonPoints(FLine L2){
FPoint result = new FPoint();
FLine SI = operator(L2,SHARPINTERSECTION);
BasicSegment current;
BasicPoint BP1,BP2;
for(int i=0;i<fSeg.getSize();i++){
current = (BasicSegment) fSeg.get(i).basic();
BP1 = current.getEP1();
BP2 = current.getEP2();
if ( L2.contains(BP1) && // a common point
!SI.contains(BP1) ) // not a point of a common Line
result.add(new fEPoint(BP1,1));
if( L2.contains(BP2) &&
!SI.contains(BP2) )
result.add(new fEPoint(BP2,1));
} // for
return result;
}
/************************************************************
end of operators
*************************************************************/
/** process a single Segment for many operators */
private void processElements(fSegment F1, double scale1,
fSegment F2, double scale2,
FLine Goal,
int Operator){
// 1 input parameter can be null
// if both fTriangles not null, then they must
// have the same basic
if( F1==null & F2==null) return;
double Z1,Z2;
fSegment newFS;
switch (Operator){
case UNION : { // the union of 2 Lines ignoring SFs
if(F1==null)
Goal.fSeg.insert(F2.copy());
else if(F2==null)
Goal.fSeg.insert(F1.copy());
else { // both fTriangles are not null
Z1 = Math.max(F1.getZ1(),F2.getZ1());
Z2 = Math.max(F1.getZ2(),F2.getZ2());
newFS = new fSegment((BasicSegment)
F1.basic(),
Z1,Z2);
Goal.fSeg.insert(newFS);
} // else
}
break;
case INTERSECTION : {
if (F1==null | F2==null)
;
else { // both are not null
Z1 = Math.min(F1.getZ1(),F2.getZ1());
Z2 = Math.min(F1.getZ2(),F2.getZ2());
if(Z1+Z2>0){
newFS = new fSegment((BasicSegment)
F1.basic(),
Z1,Z2 );
Goal.fSeg.insert(newFS);
}
}
}
break;
case ADD : {
if(F1==null)
Goal.fSeg.insert(F2.copy());
else
if(F2==null)
Goal.fSeg.insert(F1.copy());
else { // both fSegments are not null
Z1 = Math.min(1,F1.getZ1()+F2.getZ1());
Z2 = Math.min(1,F1.getZ2()+F2.getZ2());
newFS = new fSegment((BasicSegment)
F1.basic(),
Z1,Z2);
Goal.fSeg.insert(newFS);
} // else
}
break;
case SUBTRACT :{
if(F1 == null)
;
else if(F2==null)
Goal.fSeg.insert(F1.copy());
else { // both not null
Z1 = Math.max(0,F1.getZ1()-F2.getZ1());
Z2 = Math.max(0,F1.getZ2()-F2.getZ2());
if ((Z1+Z2)>0) {
newFS = new fSegment( (BasicSegment)
F1.basic(),Z1,Z2);
Goal.fSeg.insert(newFS);
}
}
} break;
case SCALEDUNION : {
fSegment newSegment;
if (F1==null)
newSegment = new fSegment( (BasicSegment)
F2.basic(),
F2.getZ1()*scale2,
F2.getZ2()*scale2);
else if (F2==null)
newSegment = new fSegment( (BasicSegment)
F1.basic(),
F1.getZ1()*scale1,
F1.getZ2()*scale1);
else {
Z1 = Math.max(F1.getZ1()*scale1,
F2.getZ1()*scale2);
Z2 = Math.max(F1.getZ2()*scale1,
F2.getZ2()*scale2);
newSegment = new fSegment( (BasicSegment)
F1.basic(),
Z1,Z2);
} // else
Goal.add(newSegment);
}
break; // scaled union
case SCALEDINTERSECTION :
if (F1==null || F2==null)
;
else {
Z1 = Math.min(F1.getZ1()*scale1,
F2.getZ1()*scale2);
Z2 = Math.min(F1.getZ2()*scale1,
F2.getZ2()*scale2);
Goal.add(new fSegment( (BasicSegment)
F1.basic(),
Z1,Z2));
}
break;
case SCALEDADD : {
if(F1==null)
Goal.add(new fSegment( (BasicSegment)
F2.basic(),
F2.getZ1()*scale2,
F2.getZ2()*scale2));
else if(F2==null)
Goal.add(new fSegment( (BasicSegment)
F1.basic(),
F1.getZ1()*scale1,
F1.getZ2()*scale1));
else {
Goal.add(new fSegment( (BasicSegment)
F1.basic(),
F1.getZ1()*scale1 +
F2.getZ1()*scale2 ,
F1.getZ2()*scale1 +
F2.getZ2()*scale2 ));
}
}
break;
case SCALEDDIFFERENCE : {
if(F1==null)
Goal.add(new fSegment( (BasicSegment)
F2.basic(),
-F2.getZ1()*scale2,
-F2.getZ2()*scale2));
else if(F2==null)
Goal.add(new fSegment( (BasicSegment)
F1.basic(),
F1.getZ1()*scale1,
F1.getZ2()*scale1));
else {
Goal.add(new fSegment( (BasicSegment)
F1.basic(),
F1.getZ1()*scale1 -
F2.getZ1()*scale2 ,
F1.getZ2()*scale1 -
F2.getZ2()*scale2 ));
}
}
break;
case SHARPINTERSECTION :{
if (F1==null | F2==null)
;
else {
newFS = new fSegment((BasicSegment)F1.basic(),1,1);
Goal.fSeg.insert(newFS);
}
}
break;
default : System.err.println("operator not implemented");
} // switch
} // processElements
/** the 'template' for many operators */
protected FLine operator(FLine FL, int op){
// a kind of mergesort
int my = 0;
int fromFL = 0; // already processed
int maxMy = fSeg.getSize(); // numbers of elements
int maxFromFL = FL.fSeg.getSize();
FLine result = new FLine(1);
fSegment myFirst=null; // the first unprocessed elements
fSegment FLFirst=null;
if(maxMy>0)
myFirst = (fSegment) fSeg.get(0);
if(maxFromFL>0)
FLFirst = (fSegment) FL.fSeg.get(0);
if (maxMy >0 && maxFromFL>0){
myFirst = (fSegment) fSeg.get(my);
FLFirst = (fSegment) FL.fSeg.get(fromFL);
int compareResult;
while(my<maxMy && fromFL<maxFromFL){
// both sets have unprocessed elements
compareResult=myFirst.basic().compareTo(FLFirst.basic());
if(compareResult < 0) {
processElements(myFirst,SF,null,FL.SF,result,op);
my++;
if (my<maxMy)
myFirst = (fSegment) fSeg.get(my);
}
else if(compareResult > 0){
processElements(null,SF,FLFirst,FL.SF,result,op);
fromFL++;
if(fromFL<maxFromFL)
FLFirst = (fSegment) FL.fSeg.get(fromFL);
}
else { // elements have the same basic
processElements(myFirst,SF,FLFirst,FL.SF,result,op);
my++;
fromFL++;
if (my<maxMy)
myFirst = (fSegment) fSeg.get(my);
if (fromFL<maxFromFL)
FLFirst = (fSegment) FL.fSeg.get(fromFL);
}
} // while
} // if
// elements from one (or both) regions are processed
while(my < maxMy){ // this have still elements
processElements(myFirst,SF,null,FL.SF,result,op);
my++;
if (my<maxMy)
myFirst = (fSegment) fSeg.get(my);
}
while (fromFL < maxFromFL){ // FL have still elements
processElements(null,SF,FLFirst,FL.SF,result,op);
fromFL++;
if(fromFL<maxFromFL)
FLFirst = (fSegment) FL.fSeg.get(fromFL);
}
result.computeBoundingBox();
return result;
}
/** normalize this FLine */
private void norm(){
if (isEmpty()) return; // nothing to do
// first compute Zmin and Zmax
double Zmin = 0;
double Zmax = 0;
fSegment Current;
for (int i=0; i< fSeg.getSize();i++){
Current = (fSegment) fSeg.get(i);
if(Current.getMaxZ()>Zmax)
Zmax = Current.getMaxZ();
if(Current.getMinZ()<Zmin)
Zmin = Current.getMinZ();
}
if(Zmin > 0) Zmin=0;
if(Zmax==0 & Zmin==0)
fSeg.makeEmpty();
else{
double SFnew = Zmax - Zmin;
SortedObjects newfSeg = new SortedObjects();
double Z1,Z2,Z3;
fSegment fSnew;
for(int i=0;i<fSeg.getSize();i++){
Current = (fSegment) fSeg.get(i);
Z1 = Current.getZ1();
Z2 = Current.getZ2();
fSnew = new fSegment( (BasicSegment) Current.basic(),
(Z1-Zmin)/SFnew ,
(Z2-Zmin)/SFnew );
if (fSnew.getMaxZ() >0)
newfSeg.insert(fSnew);
} // for
SF = SFnew*SF;
fSeg = newfSeg;
}
computeBoundingBox();
}
/*************************************************************
* *
* topological Relationships *
* *
*************************************************************/
/*************************************************************
* *
* Topology in the basic *
* *
*************************************************************/
/** helping method to compute the top Rel in the basic */
private static void checkPointsBasic(
int Segs1, int Segs2,
M9Int goal ){
/* this method checks the intersection of two lines in a
BasicPoint BP
Paramters :
Segs1, Segs2 : numberOfSegments of each Line in BP
Z1,Z2 : maxZfkt(BP) for each Line
fuzzy : basic or fuzzy intersections ?
goal : here saving the result(s)
*/
if(Segs1==0) { // exterior of L1
if(Segs2==0) // exterior
goal.setValue(true,M9Int.EXTERIOR,M9Int.EXTERIOR);
if(Segs2==1) // boundary
goal.setValue(true,M9Int.EXTERIOR,M9Int.BOUNDARY);
if(Segs2>1){ // interior
goal.setValue(true,M9Int.EXTERIOR,M9Int.INTERIOR);
} // interior of l2
} // exterior of L1
if(Segs1==1) { // boundary of L1
if(Segs2==0)
goal.setValue(true,M9Int.BOUNDARY,M9Int.EXTERIOR);
if(Segs2==1)
goal.setValue(true,M9Int.BOUNDARY,M9Int.BOUNDARY);
if(Segs2>1){ // interior of L2
goal.setValue(true,M9Int.BOUNDARY,M9Int.INTERIOR);
}// interior of L2
} // boundary of L1
if(Segs1>1) { // a interior Point of Line 1
if(Segs2==0){
goal.setValue(true,M9Int.INTERIOR,M9Int.EXTERIOR);
} // Segs1==0
if(Segs2==1){ // boundary of L2
goal.setValue(true,M9Int.INTERIOR,M9Int.BOUNDARY);
} // boundary of L2
if(Segs2>1){ // intersection of both interiors
goal.setValue(true,M9Int.INTERIOR,M9Int.INTERIOR);
} // both interiors
} // interior of L1
} // checkPointsBasic
/** helping method to compute top Rel in the basic */
private static void checkEndPoints(FLine L1,FLine L2,
BasicPoint BP,
M9Int goal){
int Segs1 = L1.numberOfSegments(BP);
int Segs2 = L2.numberOfSegments(BP);
checkPointsBasic(Segs1,Segs2,goal);
}
/**
* computed the 9-Intersection-matrix from this FLine and L2
*/
M9Int basicTopolRelation(FLine L2){
M9Int result = new M9Int();
if (this.isEmpty() || L2.isEmpty()) return null;
result.setValue(true,M9Int.EXTERIOR,M9Int.EXTERIOR);
int currentThis=0;
int currentL2=0;
int maxThis = fSeg.getSize();
int maxL2 = L2.fSeg.getSize();
fSegment thisFirst;
fSegment L2First;
BasicSegment thisBasic;
BasicSegment L2Basic;
BasicSegment Smallest=null;
BasicPoint BP1,BP2;
int compare;
int thisSegs;
int L2Segs;
while(currentThis<maxThis & currentL2<maxL2){
thisFirst = (fSegment) fSeg.get(currentThis);
L2First = (fSegment) L2.fSeg.get(currentL2);
thisBasic = (BasicSegment) thisFirst.basic();
L2Basic = (BasicSegment) L2First.basic();
compare = (thisBasic.compareTo(L2Basic));
if( compare==0) { // a common Segment
currentThis++;
currentL2++;
result.setValue(true,M9Int.INTERIOR,M9Int.INTERIOR);
Smallest=thisBasic; // special role of endpoints
}
if(compare < 0) { // process single segment of this
result.setValue(true,M9Int.INTERIOR,M9Int.EXTERIOR);
Smallest=thisBasic;
currentThis++;
}
if(compare > 0) { // process single Segment of L2
result.setValue(true,M9Int.EXTERIOR,M9Int.INTERIOR);
Smallest=L2Basic;
currentL2++;
}
// process Endpoints of Segment(s)
BP1 = Smallest.getEP1();
BP2 = Smallest.getEP2();
checkEndPoints(this,L2,BP1,result);
checkEndPoints(this,L2,BP2,result);
}// while
while(currentThis<maxThis){
thisFirst = (fSegment) fSeg.get(currentThis);
currentThis++;
thisBasic = (BasicSegment) thisFirst.basic();
result.setValue(true,M9Int.INTERIOR,M9Int.EXTERIOR);
BP1 = thisBasic.getEP1();
BP2 = thisBasic.getEP2();
checkEndPoints(this,L2,BP1,result);
checkEndPoints(this,L2,BP2,result);
}
while(currentL2<maxL2){
L2First = (fSegment) L2.fSeg.get(currentL2);
currentL2++;
L2Basic = (BasicSegment) L2First.basic();
result.setValue(true,M9Int.EXTERIOR,M9Int.INTERIOR);
BP1 = L2Basic.getEP1();
BP2 = L2Basic.getEP2();
checkEndPoints(this,L2,BP1,result);
checkEndPoints(this,L2,BP2,result);
}
return result;
} // basicTopolRelation
/** computes the 9-intersection-matrix from this and R */
M9Int basicTopolRelation(FRegion R){
M9Int result = new M9Int();
// the 'defaults'
result.setValue(true,M9Int.EXTERIOR,M9Int.EXTERIOR);
result.setValue(true,M9Int.EXTERIOR,M9Int.INTERIOR);
fSegment currentSeg;
BasicSegment currentBS;
int TriNumberSeg;
int SegNumber1,SegNumber2;
BasicPoint BP1,BP2;
boolean onBound1,onBound2;
for(int i=0;i<fSeg.getSize();i++){
currentSeg = (fSegment) fSeg.get(i);
currentBS = (BasicSegment) currentSeg.basic();
BP1 = currentBS.getEP1();
BP2 = currentBS.getEP2();
SegNumber1 = numberOfSegments(BP1);
SegNumber2 = numberOfSegments(BP2);
TriNumberSeg = R.numberOfTriangles(currentBS);
onBound1 = R.onBoundary(BP1);
onBound2 = R.onBoundary(BP2);
if(TriNumberSeg==0) { //segment is in exterior of R
result.setValue(true,M9Int.INTERIOR,M9Int.EXTERIOR);
if(onBound1){
if(SegNumber1==1)
result.setValue(true,M9Int.BOUNDARY,M9Int.BOUNDARY);
else // a interior point of the Line
result.setValue(true,M9Int.INTERIOR,M9Int.BOUNDARY);
} // onBound1
if(onBound2) {
if(SegNumber2==1)
result.setValue(true,M9Int.BOUNDARY,M9Int.BOUNDARY);
else
result.setValue(true,M9Int.INTERIOR,M9Int.BOUNDARY);
} // onBound2
} // TriNumberSeg==0
if(TriNumberSeg==1) { // Segment on boundary of R
result.setValue(true,M9Int.INTERIOR,M9Int.BOUNDARY);
if(SegNumber1==1 | SegNumber2==1)
result.setValue(true,M9Int.BOUNDARY,M9Int.BOUNDARY);
}
if(TriNumberSeg==2){ // Segment in interior of R
result.setValue(true,M9Int.INTERIOR,M9Int.INTERIOR);
if(onBound1){
if(SegNumber1==1)
result.setValue(true,M9Int.BOUNDARY,M9Int.BOUNDARY);
else // a interior point of the Line
result.setValue(true,M9Int.INTERIOR,M9Int.BOUNDARY);
} // onBound1
if(onBound2) {
if(SegNumber2==1)
result.setValue(true,M9Int.BOUNDARY,M9Int.BOUNDARY);
else
result.setValue(true,M9Int.INTERIOR,M9Int.BOUNDARY);
} // onBound2
} // TriNumberSeg==2
}
// a boundary-Segment of R in exterior of L
FLine RegionBoundary = R.boundary();
boolean found=false;
for(int i=0;i<RegionBoundary.fSeg.getSize() & !found;i++){
currentBS = (BasicSegment) RegionBoundary.fSeg.get(i).basic();
if (fSeg.search(currentBS)==null){
result.setValue(true,M9Int.INTERIOR,M9Int.EXTERIOR);
found = true;
}
}
return result;
}
/** compute the 9-intersection-matrix from this and CO */
public M9Int basicTopolRelation(CompositeObject CO){
if(CO instanceof FPoint){
M9Int result = (( (FPoint)CO).basicTopolRelation(this));
result.makeSym();
return result;
}
if(CO instanceof FLine)
return basicTopolRelation( (FLine) CO);
if(CO instanceof FRegion)
return basicTopolRelation( (FRegion) CO);
return null;
}
/**********************************************************
*
* Topology of fuzzy objects
*
**********************************************************/
/**
* returns the membership-value on given pos on a given
* BasicSegment <br>
* pos must be in [0,1]
*/
double getMaxValue(BasicSegment BS, double pos){
if(pos<0 || pos>1)
return 0;
fSegment FS = (fSegment) fSeg.search(BS);
if(FS==null)
return 0;
double Z1,Z2;
Z1 = FS.getZ1();
Z2 = FS.getZ2();
return Z1+pos*(Z2-Z1);
}
/** compute the top Rel between this and L */
public FuzzyTopRel topolRelation(FLine L){
int currentThis=0;
int currentL=0;
int maxThis=fSeg.getSize();
int maxL = fSeg.getSize();
fSegment fST,fSL;
BasicSegment BST,BSL;
int compare;
BasicPoint BP1,BP2;
double Z1T,Z2T,Z1L,Z2L;
FuzzyTopRel result = new FuzzyTopRel();
while(currentThis<maxThis & currentL<maxL){
fST = (fSegment) fSeg.get(currentThis);
BST = (BasicSegment) fST.basic();
fSL = (fSegment) fSeg.get(currentL);
BSL = (BasicSegment) fSL.basic();
compare = BST.compareTo(BSL);
if(compare<0){ // test on boundary of L
currentThis++;
BP1 = BST.getEP1();
BP2 = BST.getEP2();
if(L.contains(BP1)){
Z1T = fST.getZ1();
Z1L = L.maxZfkt(BP1);
result.computeValue(Z1T,Z1L);
}
if(L.contains(BP2)){
Z1T = fST.getZ2();
Z1L = L.maxZfkt(BP2);
result.computeValue(Z1T,Z1L);
}
}
if(compare>0){ // test on boundary of this
currentL++;
BP1 = BSL.getEP1();
BP2 = BSL.getEP2();
if(this.contains(BP1)){
Z1L = fSL.getZ1();
Z1T = this.maxZfkt(BP1);
result.computeValue(Z1T,Z1L);
}
if(this.contains(BP2)){
Z1L = fSL.getZ2();
Z1T = this.maxZfkt(BP2);
result.computeValue(Z1T,Z1L);
}
}
if(compare==0){ // common segment
currentL++;
currentThis++;
Z1T = fST.getZ1();
Z2T = fST.getZ2();
Z1L = fSL.getZ1();
Z2L = fSL.getZ2();
if( Z1T==Z1L | Z2T==Z2L){
result.computeValue(Z1T,Z1L);
result.computeValue(Z2T,Z2L);
}
else{
if( (Z1T>Z1L & Z2T>Z2L) | (Z1T<Z1L & Z2T<Z2L) )
result.computeValue(Z1T,Z1L);
else{ // the functions are crossing
result.computeValue(Z1T,Z1L);
result.computeValue(Z2T,Z2L);
result.computeValue(0.5,0.5); // the intersection
if(Z1T==0 | Z2T==0)
result.computeValue(0.1,0.2);
if(Z1L==0 | Z2L==0)
result.computeValue(0.2,0.1);
} // else
} // else
} // compare==0
} // while
while(currentThis<maxThis){
fST = (fSegment) fSeg.get(currentThis);
BST = (BasicSegment) fST.basic();
BP1 = BST.getEP1();
BP2 = BST.getEP2();
currentThis++;
if(L.contains(BP1)) {
Z1T = fST.getZ1();
Z1L = L.maxZfkt(BP1);
result.computeValue(Z1T,Z1L);
}
if(L.contains(BP2)){
Z1T = fST.getZ2();
Z1L = L.maxZfkt(BP2);
result.computeValue(Z1T,Z1L);
}
}
while(currentL<maxL){
fSL = (fSegment) fSeg.get(currentL);
BSL = (BasicSegment) fSL.basic();
BP1 = BSL.getEP1();
BP2 = BSL.getEP2();
currentL++;
if(this.contains(BP1)){
Z1L = fSL.getZ1();
Z1T = this.maxZfkt(BP1);
result.computeValue(Z1T,Z1L);
}
if(this.contains(BP2)){
Z1L = fSL.getZ2();
Z1T = this.maxZfkt(BP2);
result.computeValue(Z1T,Z1L);
}
} // while
return result;
} // topolRelation
/** computes the top Rel between this Line and R */
public FuzzyTopRel topolRelation(FRegion R){
FuzzyTopRel result = new FuzzyTopRel();
int max = fSeg.getSize();
fSegment FS;
BasicSegment BS;
BasicPoint BP1,BP2;
double Z1L,Z2L,Z1R,Z2R;
for(int current=0;current<max;current++){
FS = (fSegment) fSeg.get(current);
BS = (BasicSegment) FS.basic();
BP1 = BS.getEP1();
BP2 = BS.getEP2();
Z1L = FS.getZ1();
Z2L = FS.getZ2();
if(R.contains(BS)){
double values[] = R.getValues(BS);
if(values.length==2){
Z1R = values[0];
Z2R = values[1];
if(Z1L!=Z1R) // only inner values
result.computeValue(Z1L,Z1R);
if(Z2L!=Z2R) // only inner values
result.computeValue(Z2L,Z2R);
if( (Z1L-Z1R)*(Z2L-Z2R)<0 ) // crossing => equal value
result.computeValue(0.5,0.5);
if( (Z1L==Z1R) & (Z2L==Z2R) ) // equals segments
result.computeValue(0.5,0.5);
}
else{
// in the regions exists crossing triangles over this BS
Z1R = values[0];
Z2R = values[1];
double ZMR = values[3];
double ZML = Z1L + values[2]*(Z2L-Z1L);
if(Z1L!=Z1R) // only inner values
result.computeValue(Z1L,Z1R);
result.computeValue(ZML,ZMR);
if(Z2L!=Z2R)
result.computeValue(Z2L,Z2R);
if( ((Z1L-Z1R)*(ZML-ZMR)<0) || ((ZML-ZMR)*(Z2L-Z2R)<0) )
result.computeValue(0.5,0.5);
}
} // R contains Segment
if(R.contains(BP1)){
Z1R = R.maxZfkt(BP1);
result.computeValue(Z1L,Z1R);
}
if(R.contains(BP2)){
Z2R = R.maxZfkt(BP2);
result.computeValue(Z2L,Z2R);
}
} // for
return result;
}
/** computes the top.rel. between this and CO */
public FuzzyTopRel topolRelation(CompositeObject CO){
FuzzyTopRel result;
if(CO instanceof FPoint){
result = ((FPoint) CO).topolRelation(this);
result.makeSym();
return result;
}
if(CO instanceof FLine)
return topolRelation((FLine) CO);
if(CO instanceof FRegion)
return topolRelation((FRegion) CO);
return null;
}
/** returns the ListExpr representation of this FLine
* (SF , (<SegmentList>))
*/
public ListExpr toListExpr(){
// first create the SegmentList
ListExpr Segments;
ListExpr Last=null;
if(fSeg.getSize()==0)
Segments = ListExpr.theEmptyList();
else {
Segments = ListExpr.oneElemList(
((fSegment)fSeg.get(0)).toListExpr());
Last = Segments;
}
fSegment NextSegment;
for(int i=1;i<fSeg.getSize();i++){
NextSegment = (fSegment) fSeg.get(i);
Last=ListExpr.append(Last,NextSegment.toListExpr());
}
return ListExpr.twoElemList(
ListExpr.realAtom((float)SF),Segments);
}
/** creates a new ListEXpr <type,value>*/
public ListExpr toTypedListExpr(){
return ListExpr.twoElemList(
ListExpr.symbolAtom("fline"),toListExpr());
}
/** read this FLine from a ListExpr
* @return true if LE is a valid Representaion of a FLine
* all valid Segments of this List are inserted
*/
public boolean readFromListExpr(ListExpr LE){
SF = 1.0;
fSeg.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 Segments = LE.second();
fSegment S;
boolean ok = true;
while( !Segments.isEmpty() & ok) {
S = new fSegment(0,0,0,0,0,0);
if(S.readFromListExpr(Segments.first())){
add(S);
Segments=Segments.rest();
}
else
ok = false;
}
return ok;
}
/** returns a String representation of
* the corresponding ListExpr
*/
public String toListString(){
return toListExpr().writeListExprToString();
}
/** read the FLine from a String representation of a ListExpr
* @return true if List is a String of a ListExpr
* containing a correct FLine
*/
public boolean readFromListString(String List){
ListExpr LE = new ListExpr();
if(LE.readFromString(List)!=0){
return false;
}
else{
return readFromListExpr(LE);
}
}
/** this method is used for reading a fuzzy line
* from a byte array;
* returns null if the construction of the object failed
*/
public static FLine readFrom(byte[] buffer){
try{
ObjectInputStream ois;
ois= new ObjectInputStream(
new ByteArrayInputStream(buffer));
FLine res = (FLine) 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(fSeg.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());
}
// define constants for the operators
private static final int UNION = 0;
private static final int INTERSECTION=1;
private static final int ADD=2;
private static final int SUBTRACT=3;
private static final int SCALEDUNION=4;
private static final int SCALEDINTERSECTION=5;
private static final int SCALEDADD=6;
private static final int SCALEDDIFFERENCE=7;
private static final int SHARPINTERSECTION=8;
// == intersection(sharp(L1),sharp(L2))
} // FLine;