/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
*
* 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;
* version 2.1 of the License.
*
* 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.
*/
package org.geotools.geometry.iso.util.elem2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;
/**
* @author roehrig
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*
* @source $URL$
*/
public class Geo2DFactory {
private static class TN {
Node2D nodeObject;
Vector<Triangle2D> tri = new Vector<Triangle2D>(6,2);
public TN(Object o) {
nodeObject = (Node2D)o;
}
/**
* returns the side of the left and of the right triangles
* @param n0
* @param n1
* @return
*/
public static int[] getTriangles(Node2D n0, Node2D n1) {
TN tn0 = (TN)n0.object;
TN tn1 = (TN)n1.object;
int side[] = new int[2];
side[0] = -1;
side[1] = -1;
for (Iterator<Triangle2D> it0 = tn0.tri.iterator(); it0.hasNext(); ) {
Triangle2D t0 = it0.next();
Node2D p0[] = t0.getPoints();
for (int i=0; i<3; ++i) {
if (p0[i]==n0 && p0[(i+1)%3]==n1) {
side[0] = i;
}
}
}
for (Iterator<Triangle2D> it1 = tn0.tri.iterator(); it1.hasNext(); ) {
Triangle2D t1 = it1.next();
Node2D p1[] = t1.getPoints();
for (int i=0; i<3; ++i) {
if (p1[i]==n1 && p1[(i+1)%3]==n0) {
side[i] = i;
}
}
}
return side;
}
}
public static Edge2D getEdge(Node2D n0, Node2D n1) {
if (n0==null || n1==null) return null;
return n0.getEdge(n1);
// Edge2D edges0[] = n0.getEdges();
// Edge2D edges1[] = n1.getEdges();
// if (edges0==null || edges1==null) return null;
// for (int i=0; i<edges0.length; ++i) {
// for (int j=0; j<edges1.length; ++j) {
// if (edges0[i]==edges1[j]) return edges0[i];
// }
// }
// return null;
}
public static Edge2D createEdgeAndNodes(double x0, double y0, double x1, double y1) {
Node2D n0 = new Node2D(x0,y0);
Node2D n1 = new Node2D(x1,y1);
Edge2D edge = new Edge2D(n0,n1);
n0.linkEdge(edge);
n1.linkEdge(edge);
return edge;
}
public static Edge2D createEdgeAndNode(Node2D n0, double x1, double y1) {
Node2D n1 = new Node2D(x1,y1);
Edge2D edge = new Edge2D(n0,n1);
n0.linkEdge(edge);
n1.linkEdge(edge);
return edge;
}
public static Edge2D createEdgeAndNode(double x0, double y0, Node2D n1) {
Node2D n0 = new Node2D(x0,y0);
Edge2D edge = new Edge2D(n0,n1);
n0.linkEdge(edge);
n1.linkEdge(edge);
return edge;
}
public static Edge2D createEdgeFromNodes(Node2D n0, Node2D n1) {
if (n0==null || n1==null) return null;
Edge2D edge = new Edge2D(n0,n1);
n0.linkEdge(edge);
n1.linkEdge(edge);
return edge;
}
public static Edge2D createEdge(Node2D nodeFrom, Node2D nodeTo, Simplex2D rightSimplex, Simplex2D leftSimplex) {
if (nodeFrom==null || nodeTo==null) return null;
assert nodeFrom.getEdge(nodeTo)==null;
assert nodeTo.getEdge(nodeFrom)==null;
Edge2D edge = new Edge2D(nodeFrom,nodeTo);
nodeFrom.linkEdge(edge);
nodeTo.linkEdge(edge);
if (rightSimplex!=null) {
int side = rightSimplex.getSide(nodeFrom,nodeTo);
if (side==-1) return null;
rightSimplex.linkEdge(side,edge);
edge.setSimplex(rightSimplex, Edge2D.RIGHTSIDE);
}
if (leftSimplex!=null) {
int side = leftSimplex.getSide(nodeFrom,nodeTo);
if (side==-1) return null;
leftSimplex.linkEdge(side,edge);
edge.setSimplex(leftSimplex, Edge2D.LEFTSIDE);
}
return edge;
}
public static boolean connectEdgeSimplex(Edge2D edge, Simplex2D simplex, int edgeSide) {
if (edge==null || simplex==null || (edgeSide!=Edge2D.RIGHTSIDE && edgeSide!=Edge2D.LEFTSIDE) ) return false;
int simplexSide = simplex.getSide(edge.getNode1(), edge.getNode2());
if (simplexSide==-1) return false;
simplex.linkEdge(simplexSide,edge);
edge.setSimplex(simplex,edgeSide);
return true;
}
public static boolean connectSimplexSimplex(Simplex2D simplex0, Simplex2D simplex1) {
if (simplex0==null || simplex1==null) return false;
return simplex0.linkSimplex(simplex1);
}
public static Object[] splitEdge(Edge2D edge, Point2D p) {
if (edge.getLeftSimplex()!=null || edge.getRightSimplex()!=null) {
System.out.println("error connectSimplexSimplex(Simplex2D simplex0, Simplex2D simplex1)");
return null;
}
Node2D n1 = edge.getNode1();
Node2D n2 = edge.getNode2();
n1.unlinkEdge(edge);
n2.unlinkEdge(edge);
Node2D newNode = new Node2D(p);
edge.setNodes(n1,newNode);
Edge2D newEdge = new Edge2D(newNode, n2);
n1.linkEdge(edge);
n2.linkEdge(newEdge);
newNode.linkEdge(edge);
newNode.linkEdge(newEdge);
newEdge.object = edge.object;
return new Object[] {newEdge,newNode};
}
/**
* @param edge
* @param n1
* @param ns
*/
private static void connect(Edge2D edge, Node2D n0, Node2D n1) {
if (edge.hasPoint(n0) && edge.hasPoint(n1)) {
System.out.println("error connect(Edge2D edge, Node2D n0, Node2D n1)");
}
edge.setNodes(n0, n1);
n0.linkEdge(edge);
n1.linkEdge(edge);
}
/**
* removes the edge, maintains the nodes
* @param edge
*/
public static void removeEdge(Edge2D edge) {
Node2D n1 = edge.getNode1();
Node2D n2 = edge.getNode2();
n1.unlinkEdge(edge);
n2.unlinkEdge(edge);
}
/**
* @param p1
* @param p2
*/
public static void setEdgeNodes(Edge2D e, Node2D n1, Node2D n2) {
assert (e.getLeftSimplex()==null && e.getRightSimplex()==null);
assert getEdge(n1,n2)==null;
Node2D nn1 = e.getNode1();
Node2D nn2 = e.getNode2();
if (n1!=nn1) {
n1.appendEdges(nn1.getEdges());
}
if (n2!=nn2) {
n2.appendEdges(nn2.getEdges());
}
e.setNodes(n1,n2);
}
public static void setTriangleNodes(Triangle2D tri, Node2D n0, Node2D n1, Node2D n2) {
tri.point[0] = n0;
tri.point[1] = n1;
tri.point[2] = n2;
}
public static void setTopology(ArrayList<Triangle2D> triangles, ArrayList<Edge2D> edges) {
if (edges == null) edges = new ArrayList<Edge2D>();
if (triangles == null) triangles = new ArrayList<Triangle2D>();
// unlink eventually linked triangles, link the nodes of each triangle
// with its triangle, create a temporary list node-triangles and insert
// the triangles associated to each node
for (Iterator<Triangle2D> it = triangles.iterator(); it.hasNext();) {
Triangle2D tri = it.next();
tri.linkSimplex(0,null);
tri.linkSimplex(1,null);
tri.linkSimplex(2,null);
Node2D n[] = tri.getPoints();
for (int i=0; i<3; ++i) {
n[i].linkSimplex(tri);
if ( !(n[i].object instanceof TN) ) n[i].object = new TN(n[i].object);
((TN)n[i].object).tri.add(tri);
}
}
// set the triangle-triangle association for triangles sharing two nodes
for (Iterator<Triangle2D> it = triangles.iterator(); it.hasNext();) {
Triangle2D tri = it.next();
Node2D n[] = tri.getPoints();
for (int i=0; i<3; ++i) {
if (tri.hasNeighbour(i)) continue;
TN tn = ((TN)n[i].object);
for (Iterator<Triangle2D> itt = tn.tri.iterator(); itt.hasNext(); ) {
Triangle2D t = itt.next();
if ( t == tri ) continue;
int side = t.getSide(n[i],n[(i+1)%3]);
if ( side != -1 ) {
tri.linkSimplex(i,t);
t.linkSimplex(side,tri);
break;
}
}
}
}
// edge-triangle associations
for (Iterator<Edge2D> it = edges.iterator(); it.hasNext();) {
Edge2D e = it.next();
Node2D n0 = e.getNode1();
Node2D n1 = e.getNode2();
TN tn0 = (TN)n0.object;
TN tn1 = (TN)n1.object;
int side0 = -1;
int side1 = -1;
Triangle2D tri0 = null;
Triangle2D tri1 = null;
for (Iterator<Triangle2D> it0 = tn0.tri.iterator(); it0.hasNext(); ) {
Triangle2D t0 = it0.next();
Node2D p0[] = t0.getPoints();
for (int i=0; i<3; ++i) {
if (p0[i]==n0 && p0[(i+1)%3]==n1) {
side0 = i;
tri0 = t0;
break;
}
}
if (tri0!=null) break;
}
for (Iterator<Triangle2D> it1 = tn1.tri.iterator(); it1.hasNext(); ) {
Triangle2D t1 = it1.next();
Node2D p1[] = t1.getPoints();
for (int i=0; i<3; ++i) {
if (p1[i]==n1 && p1[(i+1)%3]==n0) {
side1 = i;
tri1 = t1;
break;
}
}
if (tri1!=null) break;
}
assert ( (side0!=-1) && (side1!=-1) );
if (side0!=-1) {
e.surfaceLeft = tri0;
tri0.linkEdge(side0,e);
}
if (side1!=-1) {
e.surfaceRight = tri1;
tri1.linkEdge(side1,e);
}
}
// now the edges. An edge-node connection will prevail over triangle-triangle associations
for (Iterator<Edge2D> it = edges.iterator(); it.hasNext();) {
Edge2D e = it.next();
e.surfaceRight = null;
e.surfaceLeft = null;
Node2D n1 = e.getNode1();
Node2D n2 = e.getNode2();
n1.linkEdge(e);
n2.linkEdge(e);
}
// reset the temporary list of triangles connected to each node.
// Reestablish the former object values of each node
for (Iterator<Triangle2D> it = triangles.iterator(); it.hasNext();) {
Triangle2D tri = it.next();
Node2D n[] = tri.getPoints();
for (int i=0; i<3; ++i) {
if ( (n[i].object instanceof TN) ) n[i].object = ((TN)n[i].object).nodeObject;
}
}
}
/**
* the nodes will be merged. The edges from the second node (n1) will be
* connected from n1 and connected to n0
*
* @param n0
* @param n1
*/
public static void mergeNodes(Node2D n0, Node2D n1) {
Edge2D edges[] = n1.getEdges();
for (int i = 0; i < edges.length; ++i ) {
Edge2D e = edges[i];
n1.unlinkEdge(e);
if ( !n0.hasEdge(e) ) n0.linkEdge(e);
}
}
/**
* @param post
* @return
*/
public static Node2D createNode(Point2D p) {
return new Node2D(p);
}
/**
* @param x
* @param y
* @param x2
* @param y2
* @param x3
* @param y3
* @return
*/
public static Triangle2D createTriangleAndNodes(double x0, double y0, double x1, double y1, double x2, double y2) {
Node2D n0 = new Node2D(x0,y0);
Node2D n1 = new Node2D(x1,y1);
Node2D n2 = new Node2D(x2,y2);
return new Triangle2D(n0,n1,n2);
}
}