Files
secondo/Algebras/Fuzzy/fuzzyobjects/basic/BasicSegment.java
2026-01-23 17:03:45 +08:00

478 lines
12 KiB
Java

//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.basic;
import fuzzyobjects.*;
/**
* in this class are BasicSegments of the X-triangulation
* defined
* @author Thomas Behr
*/
public class BasicSegment implements BasicObject{
/**
* creates a new BasicSegment between P1 and P2
* no check whether this
* results a valid BasicSegment
* @see isValid()
*/
public BasicSegment(BasicPoint P1, BasicPoint P2) {
// creates a BasicSegment from the parameters
// no checking of correctness
// the points are ordered
if (P1.compareTo(P2)<0){
EP_1 = P1;
EP_2 = P2;
}
else{
EP_2 = P1;
EP_1 = P2;
}
}
/**
* returns the BasicPoints of this
* @return the both endpoints of this in a array
*/
public BasicPoint[] getBasicPoints(){
// returns the two endpoints of this segment in a array
BasicPoint[] BPs = new BasicPoint[2];
BPs[0] = EP_1.copy();
BPs[1] = EP_2.copy();
return BPs;
}
/**
* provides a readable form of this
* @return a String representing this
*/
public String toString(){
return "BL : ("+EP_1+"->"+EP_2+")";
}
/**
* returns a copy of this
* @return a new BasicSegment on the same location as this
*/
public BasicSegment copy() {
return new BasicSegment(EP_1.copy() , EP_2.copy());
}
/**
* check equality with L
* @return true if L is on the same location as this
*/
public boolean equals(BasicSegment L) {
// check for Equality whith L
return (EP_1.equals(L.EP_1) && EP_2.equals(L.EP_2) );
}
/**
* check: is this a Segment of the X-triangulation ?
* @return true if this is a valid segment i.e.
* both endpoints are valid and neightbooring
*/
public boolean isValid(){
boolean ok = EP_1.isValid() & EP_2.isValid();
if(ok){
return EP_1.neightbooring(EP_2);
}
return false;
}
/**
* compares this with another BasicObject
* @param O the BasicObject to compare
* @return
* <ul>
* <li>-1 if O not a BasicSegment or this is smaller then O </li>
* <li> 0 if O equals to this </li>
* <li> 1 if O is a BasicSegment and this is greater then O </li>
* </ul>
*/
public int compareTo(BasicObject O) {
if (! (O instanceof BasicSegment))
return -1;
BasicSegment L = (BasicSegment) O;
int c = EP_1.compareTo(L.EP_1);
if (c!=0)
return c;
else
return EP_2.compareTo(L.EP_2);
}
/** check whether P is a EndPoint of this
* @param P the to checked BasicPoint
* @return true if P is a endpoint of this
*/
public boolean isEndpoint(BasicPoint P) {
return EP_1.equals(P) || EP_2.equals(P);
}
/**
* check whether L and this have one common endpoint
* @param L the to checked BasicSegment
* @return true if L and this are connected
*/
public boolean connected(BasicSegment L) {
// **** check whether L is connected with this Segment ******
return !this.equals(L) &&
( EP_1.equals(L.EP_1) || EP_1.equals(L.EP_2) ||
EP_2.equals(L.EP_1) || EP_2.equals(L.EP_2) );
}
/**
* computes the length of this segment
* @return the euclic distance between both endpoints
*/
public double length(){
return EP_1.euclid_distance(EP_2);
}
/**
* computes the euclidic distance between this an
* another BasicObject
* @param BO the another BasicObject
* @return the smallest euclidic distance between
* both endpoints to all BasicPoints of BO
*/
public double euclid_distance(BasicObject BO){
double m1 = EP_1.q_euclid_distance(BO);
double m2 = EP_2.q_euclid_distance(BO);
return Math.sqrt( Math.min(m1,m2));
}
/**
* computes the quadratic euclidic distance to BO
* @params BO the another BasicObject
* @return the smallest quadratic euclidic distance between both
* endpoints of this to all BasicPoints from BO
* @see euclidic_distance(BasicObject)
*/
public double q_euclid_distance(BasicObject BO){
double m1 = EP_1.q_euclid_distance(BO);
double m2 = EP_2.q_euclid_distance(BO);
return ( Math.min(m1,m2));
}
/**
* check whether (x,y) is a point on this segment
* @param x the x-coordinate of the to checked point
* @param y the y-coordinate of the to checked point
* @return true if (x,y) contained in the pointset of this
* segment
*/
public boolean on(double x, double y){
// check : "(x,y) is a Point on this Segment ?"
double x1 = EP_1.getX();
double x2 = EP_2.getX();
double y1 = EP_1.getY();
double y2 = EP_2.getY();
if(x2!=x1){
double delta = (x-x1) / (x2-x1);
if ((delta<0) | (delta>1))
return false;
else
return y == y1 + delta*(y2-y1);
}
else{
double minY = Math.min(y1,y2);
double maxY = y1+y2-minY;
return x==x1 & y>=minY & y<=maxY;
}
}
/**
* get a endpoint of this segment
* @return the smallest endpoint of this
*/
public BasicPoint getEP1(){
return EP_1;
}
/**
* get a endpoint of this segment
* @return the greates endpoint of this
*/
public BasicPoint getEP2(){
return EP_2;
}
/**
* computes all neigtboors of this segment
* @return all segments which have one common Point with this
*/
public BasicSegment[] getNeightboors(){
BasicPoint[] ToEP1 = EP_1.getNeightboors();
BasicPoint[] ToEP2 = EP_2.getNeightboors();
BasicSegment[] result;
result = new BasicSegment[ ToEP1.length + ToEP2.length -2 ];
// all neightbooring points without EP1 or EP2 respectively
int j=0; // current position in result
for(int i=0;i<ToEP1.length;i++) {
if (!ToEP1[i].equals(EP_2)) {
result[j]= new BasicSegment(ToEP1[i],EP_1);
j++;
} else{
System.out.println("ignore point ");
}
}
for(int i=0;i<ToEP2.length;i++){
if(!ToEP2[i].equals(EP_1)){
result[j]= new BasicSegment(ToEP2[i],EP_2);
j++;
} else {
System.out.println("ignore point ");
}
}
return result;
}
/**
* computes the 2 BasicTriangles having this as a side
* @return the triangles
*/
public BasicTriangle[] getTriangles(){
BasicPoint[] Ns1 = EP_1.getNeightboors();
BasicPoint[] Ns2 = EP_2.getNeightboors();
BasicPoint cN1 = null; // common neightboors
BasicPoint cN2 = null;
boolean firstfound = false;
boolean secondfound = false;
for(int i=0;i<Ns1.length;i++)
for(int j=0;j<Ns2.length;j++)
if(Ns1[i].equals(Ns2[j])) {
if(!firstfound){
firstfound=true;
cN1 = Ns1[i];
}
else{
secondfound=true;
cN2 =Ns1[i];
}
}
BasicTriangle[] result=null;
if(secondfound){
result=new BasicTriangle[2];
result[0] = new BasicTriangle(EP_1.copy(),EP_2.copy(),cN1);
result[1] = new BasicTriangle(EP_1.copy(),EP_2.copy(),cN2);
}
else if(firstfound){
result=new BasicTriangle[1];
result[0] = new BasicTriangle(EP_1.copy(),EP_2.copy(),cN1);
}
return result;
}
/**
* computes a common Point with BS
* @param BS the another Segment
* @return the first found common endpoint or null if
* not exists one
*/
public BasicPoint commonPoint(BasicSegment BS){
if(EP_1.equals(BS.EP_1) | EP_1.equals(BS.EP_2)) return EP_1;
if(EP_2.equals(BS.EP_1) | EP_2.equals(BS.EP_2)) return EP_2;
return null;
}
/**
* check whether this BasicSegment contains (x,y)
* @param x the x coordinate of checked Point
* @param y the y coordinate of checked Point
* @return true if (x,y) on this
*/
public boolean contains(double x, double y){
BasicSegment[] Segs = getSegments(x,y);
if (Segs==null){
return false;
}
else{
boolean found=false;
for(int i=0;i<Segs.length;i++){
if(this.equals(Segs[i]))
found = true;
}
return found;
}
}
/**
* computes all BasicSegments having BP as endpoint
* @param BP the to checked point
* @return all segments having BP as endpoint
*/
public static BasicSegment[] getSegments(BasicPoint BP){
// returns all Segments, which have BP as EndPoint
BasicPoint[] Neightboors = BP.getNeightboors();
BasicSegment[] result = new BasicSegment[Neightboors.length];
for(int i=0;i<Neightboors.length;i++)
result[i] = new BasicSegment(BP,Neightboors[i]);
return result;
}
/**
* computes all BasicSegments having (x,y) in their pointset
* @param x the x coordinate of the to checked point
* @param y the y coordinate of the to checked point
* @return all Segemnts having (x,y) in their pointset
*/
public static BasicSegment[] getSegments(double x, double y){
// first check : (x,y) is a BasicPoint ?
if (BasicPoint.isBasicPoint(x,y)){
BasicPoint BP = new BasicPoint((int)x,(int)y);
return getSegments(BP);
}
else{
// max 1 Segments
BasicSegment[] result;
int a = fuzzyobjects.Params.a;
int b = fuzzyobjects.Params.b;
// compute "rectangle" of the x-triangulation which
// contains (x,y)
int ix = (int) x;
int iy = (int) y;
int ltx = (ix/a)*a;
int lty = (iy/b)*b;
if(ltx ==(int)x){ // a vertical Segment
result = new BasicSegment[1];
BasicPoint BP1 = new BasicPoint(ltx,lty);
BasicPoint BP2;
if(y>=0)
BP2 = new BasicPoint(ltx,lty+b);
else
BP2 = new BasicPoint(ltx,lty-b);
result[0] = new BasicSegment(BP1,BP2);
}// if vertical segment
else
if(lty==y){ // the horizontal Segment
result = new BasicSegment[1];
BasicPoint BP1 = new BasicPoint(ltx,lty);
BasicPoint BP2;
if(x>=0)
BP2 = new BasicPoint(ltx+a,lty);
else
BP2 = new BasicPoint(ltx-a,lty);
result[0] = new BasicSegment(BP1,BP2);
} // if horizontal segment
else {
// a diagonale or nothing
if(x<0)
ltx = ltx-a;
if(y<0)
lty = lty-b;
x = x-ltx;
y = y-lty;
double m = (double)b/(double)a;
double q = Math.sqrt(m*m+1.0);
double distance_up = Math.abs((x*m-y) / q);
double distance_down = Math.abs((-x*m-y+b)/q);
boolean left,bottom;
bottom = y<b/2.0;
left = x<a/2.0;
if(distance_up<epsilon){
result = new BasicSegment[1];
BasicPoint BP1,BP2;
BP1 = new BasicPoint(ltx+a/2,lty+b/2);
if(bottom)
BP2 = new BasicPoint(ltx,lty);
else
BP2 = new BasicPoint(ltx+a,lty+b);
result[0] = new BasicSegment(BP1,BP2);
}
else{
if(distance_down<epsilon){
result = new BasicSegment[1];
BasicPoint BP1,BP2;
BP1 = new BasicPoint(ltx+a/2,lty+b/2);
if(left)
BP2 = new BasicPoint(ltx,lty+b);
else
BP2 = new BasicPoint(ltx+a,lty);
result[0] = new BasicSegment(BP1,BP2);
}
else{
result = null;
}
}
} // diagonale or nothing
return result;
} // else : not a BasicPoint
} // getSegments
/** get the x-Coordinate of a endpoint */
public int getX1(){return EP_1.getX();}
/** get the x-Coordinate of a endpoint */
public int getX2(){return EP_2.getX();}
/** get the y-Coordinate of a endpoint */
public int getY1(){return EP_1.getY();}
/** get the y-Coordinate of a endpoint */
public int getY2(){return EP_2.getY();}
/** returns the minimum X of the bounding box */
public int getMinX(){
return Math.min(EP_1.getX(),EP_2.getX());
}
/** returns the minimum Y of the bounding box */
public int getMinY(){
return Math.min(EP_1.getY(),EP_2.getY());
}
/** returns the maximum x of the bounding box */
public int getMaxX(){
return Math.max(EP_1.getX(),EP_2.getX());
}
/** returns the maximum Y of the bounding box */
public int getMaxY(){
return Math.max(EP_1.getY(),EP_2.getY());
}
/**
* a endpoint of this segment
*/
protected BasicPoint EP_1,EP_2;
/** for approximate test "a point is containg in
this segment ?" */
private static double epsilon = 0.3;
} // class