/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.model.spatialschema;
import org.deegree.model.crs.CoordinateSystem;
/**
*
*
* @version $Revision: 1.7 $
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
*/
class LinearIntersects {
/**
* the operations returns true if two the submitted points intersects
*/
public static boolean intersects( Position point1, Position point2 ) {
double mute = 0.001;
double d = 0;
double[] p1 = point1.getAsArray();
double[] p2 = point2.getAsArray();
for ( int i = 0; i < p1.length; i++ ) {
d += ( ( p1[i] - p2[i] ) * ( p1[i] - p2[i] ) );
}
return Math.sqrt( d ) < mute;
}
/**
* the operations returns true if the submitted point intersects
* the passed curve segment
*/
public static boolean intersects( Position point, CurveSegment curve ) throws Exception {
boolean inter = false;
double mute = 0.001;
Position[] points = curve.getPositions();
for ( int i = 0; i < ( points.length - 1 ); i++ ) {
if ( linesIntersect( points[i].getX(), points[i].getY(), points[i + 1].getX(),
points[i + 1].getY(), point.getX() - mute, point.getY() - mute,
point.getX() + mute, point.getY() - mute ) ||
linesIntersect( points[i].getX(), points[i].getY(), points[i + 1].getX(),
points[i + 1].getY(), point.getX() + mute, point.getY() - mute,
point.getX() + mute, point.getY() + mute ) ||
linesIntersect( points[i].getX(), points[i].getY(), points[i + 1].getX(),
points[i + 1].getY(), point.getX() + mute, point.getY() + mute,
point.getX() - mute, point.getY() + mute ) ||
linesIntersect( points[i].getX(), points[i].getY(), points[i + 1].getX(),
points[i + 1].getY(), point.getX() - mute, point.getY() + mute,
point.getX() - mute, point.getY() - mute ) ) {
inter = true;
break;
}
}
return inter;
}
/**
* the operation returns true if the submitted point intersects
* the submitted surface patch
*/
public static boolean intersects( Position point, SurfacePatch surface ) {
return LinearContains.contains( surface, point );
}
/**
* the operation returns true if the two submitted curves segments intersects
*/
public static boolean intersects( CurveSegment curve1, CurveSegment curve2 ) {
Position[] points = curve1.getPositions();
Position[] other = curve2.getPositions();
boolean inter = false;
for ( int i = 0; i < ( points.length - 1 ); i++ ) {
for ( int j = 0; j < ( other.length - 1 ); j++ ) {
if ( linesIntersect( points[i].getX(), points[i].getY(), points[i + 1].getX(),
points[i + 1].getY(), other[j].getX(), other[j].getY(),
other[j + 1].getX(), other[j + 1].getY() ) ) {
inter = true;
break;
}
}
}
return inter;
}
/**
* the operation returns true if the submitted curve segment intersects
* the submitted surface patch
*/
public static boolean intersects( CurveSegment curve, SurfacePatch surface )
throws Exception {
boolean inter = false;
// is the curve completly embedded within the surface patch
if ( LinearContains.contains( surface, curve ) ) {
inter = true;
}
// intersects the curve the exterior ring of the surface patch
if ( !inter ) {
Position[] ex = surface.getExteriorRing();
CurveSegment cs = new LineStringImpl( ex, surface.getCoordinateSystem() );
if ( intersects( curve, cs ) ) {
inter = true;
}
}
// intersects the curve one of the interior rings of the surface patch
if ( !inter ) {
Position[][] interior = surface.getInteriorRings();
if ( interior != null ) {
for ( int i = 0; i < interior.length; i++ ) {
CurveSegment cs = new LineStringImpl( interior[i],
surface.getCoordinateSystem() );
if ( intersects( curve, cs ) ) {
inter = true;
break;
}
}
}
}
return inter;
}
/**
* the operation returns true if the two submitted surface patches intersects
*/
public static boolean intersects( SurfacePatch surface1, SurfacePatch surface2 )
throws Exception {
boolean inter = false;
CoordinateSystem crs1 = surface1.getCoordinateSystem();
CoordinateSystem crs2 = surface2.getCoordinateSystem();
if ( LinearContains.contains( surface1, surface2 ) ||
LinearContains.contains( surface2, surface1 ) ) {
inter = true;
}
if ( !inter ) {
Position[] ex1 = surface1.getExteriorRing();
CurveSegment cs1 = new LineStringImpl( ex1, crs1 );
Position[] ex2 = surface2.getExteriorRing();
CurveSegment cs2 = new LineStringImpl( ex2, crs2 );
// intersects exterior rings ?
inter = intersects( cs1, cs2 );
// intersects first exterior ring one of the interior rings of the
// second szrface patch
if ( !inter ) {
Position[][] interior = surface2.getInteriorRings();
if ( interior != null ) {
for ( int i = 0; i < interior.length; i++ ) {
cs2 = new LineStringImpl( interior[i], crs2 );
if ( intersects( cs1, cs2 ) ) {
inter = true;
break;
}
}
}
}
// intersects the interior rings of the first surface patch with one
//of the interior rings of the second surface patch
if ( !inter ) {
Position[][] interior1 = surface1.getInteriorRings();
Position[][] interior2 = surface2.getInteriorRings();
if ( interior1 != null && interior2 != null ) {
for ( int i = 0; i < interior1.length; i++ ) {
cs1 = new LineStringImpl( interior1[i], crs1 );
for ( int j = 0; j < interior2.length; j++ ) {
cs2 = new LineStringImpl( interior2[j], crs2 );
if ( intersects( cs1, cs2 ) ) {
inter = true;
break;
}
}
if ( inter ) {
break;
}
}
}
}
}
return inter;
}
/**
* the operations returns true if two the submitted points intersects
*/
public static boolean intersects( Point point1, Point point2 ) {
return intersects( point1.getPosition(), point2.getPosition() );
}
/**
* the operations returns true if the submitted point intersects
* the submitted curve
*/
public static boolean intersects( Point point, Curve curve ) throws Exception {
boolean inter = false;
int cnt = curve.getNumberOfCurveSegments();
for ( int i = 0; i < cnt; i++ ) {
if ( intersects( point.getPosition(), curve.getCurveSegmentAt( i ) ) ) {
inter = true;
break;
}
}
return inter;
}
/**
* the operation returns true if the submitted point intersects
* the submitted surface
*/
public static boolean intersects( Point point, Surface surface ) throws Exception {
boolean inter = false;
int cnt = surface.getNumberOfSurfacePatches();
for ( int i = 0; i < cnt; i++ ) {
if ( intersects( point.getPosition(), surface.getSurfacePatchAt( i ) ) ) {
inter = true;
break;
}
}
return inter;
}
/**
* the operation returns true if the two submitted curves intersects
*/
public static boolean intersects( Curve curve1, Curve curve2 ) throws Exception {
boolean inter = false;
int cnt1 = curve1.getNumberOfCurveSegments();
int cnt2 = curve2.getNumberOfCurveSegments();
for ( int i = 0; ( i < cnt1 ) && !inter; i++ ) {
for ( int j = 0; j < cnt2; j++ ) {
if ( intersects( curve1.getCurveSegmentAt( i ), curve2.getCurveSegmentAt( j ) ) ) {
inter = true;
break;
}
}
}
return inter;
}
/**
* the operation returns true if the submitted curve intersects
* the submitted surface
*/
public static boolean intersects( Curve curve, Surface surface ) throws Exception {
boolean inter = false;
int cnt1 = curve.getNumberOfCurveSegments();
int cnt2 = surface.getNumberOfSurfacePatches();
for ( int i = 0; i < cnt1; i++ ) {
for ( int j = 0; j < cnt2; j++ ) {
if ( intersects( curve.getCurveSegmentAt( i ), surface.getSurfacePatchAt( j ) ) ) {
inter = true;
break;
}
}
if ( inter ) {
break;
}
}
return inter;
}
/**
* the operation returns true if the two submitted surfaces intersects
*/
public static boolean intersects( Surface surface1, Surface surface2 ) throws Exception {
boolean inter = false;
int cnt1 = surface1.getNumberOfSurfacePatches();
int cnt2 = surface2.getNumberOfSurfacePatches();
for ( int i = 0; i < cnt1; i++ ) {
for ( int j = 0; j < cnt2; j++ ) {
if ( intersects( surface1.getSurfacePatchAt( i ), surface2.getSurfacePatchAt( j ) ) ) {
inter = true;
break;
}
}
if ( inter ) {
break;
}
}
return inter;
}
/**
*
*
* @param X1
* @param Y1
* @param X2
* @param Y2
* @param PX
* @param PY
*
* @return
*/
protected static int relativeCCW( double X1, double Y1, double X2, double Y2, double PX, double PY ) {
X2 -= X1;
Y2 -= Y1;
PX -= X1;
PY -= Y1;
double ccw = ( PX * Y2 ) - ( PY * X2 );
if ( ccw == 0.0 ) {
ccw = ( PX * X2 ) + ( PY * Y2 );
if ( ccw > 0.0 ) {
PX -= X2;
PY -= Y2;
ccw = ( PX * X2 ) + ( PY * Y2 );
if ( ccw < 0.0 ) {
ccw = 0.0;
}
}
}
return ( ccw < 0.0 ) ? ( -1 ) : ( ( ccw > 0.0 ) ? 1 : 0 );
}
/**
* Tests if the line segment from (x1, y1) to
* (x2, y2) intersects the line segment from (x3, y3)
* to (x4, y4).
* @return <code>true</code> if the first specified line segment
* and the second specified line segment intersect
* each other; <code>false</code> otherwise.
*/
protected static boolean linesIntersect( double x1, double y1, double x2, double y2, double x3,
double y3, double x4, double y4 ) {
return ( ( relativeCCW( x1, y1, x2, y2, x3, y3 ) * relativeCCW( x1, y1, x2, y2, x4, y4 ) <= 0 ) &&
( relativeCCW( x3, y3, x4, y4, x1, y1 ) * relativeCCW( x3, y3, x4, y4, x2, y2 ) <= 0 ) );
}
}/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: LinearIntersects.java,v $
Revision 1.7 2006/07/12 14:46:15 poth
comment footer added
********************************************************************** */