/* * 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.Line2D; import java.awt.geom.Point2D; import org.geotools.geometry.iso.util.algorithm2D.AlgoLine2D; import org.geotools.geometry.iso.util.algorithm2D.AlgoPoint2D; import org.geotools.geometry.iso.util.algorithm2D.AlgoRectangle2D; import org.geotools.geometry.iso.util.algorithm2D.LineLineIntersection2D; /** * @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 Triangle2D extends Simplex2D { private static int SIDE[] = { (1<<0) | (1<<1), // v[0] && v[1] (1<<1) | (1<<2), // v[1] && v[2] (1<<2) | (1<<0) // v[2] && v[0] }; /** * @param startPoint * @param p2 * @param endPoint */ public Triangle2D (Node2D p0, Node2D p1, Node2D p2) { super(new Node2D[] {p0,p1,p2}); } /* (non-Javadoc) * @see de.fhkoeln.tt.core.geo.GeoSimplex2D#n() */ public int n() { return 3; } /* (non-Javadoc) * @see de.fhkoeln.tt.core.geo.GeoSimplex2D#side(int) */ public int sideBits(int s) { return SIDE[s]; } public double getArea(){ Point2D p[] = this.getPoints(); return Math.abs((0.5 * (((p[0].getX() - p[1].getX()) * (p[0].getY() + p[1].getY())) + ((p[1].getX() - p[2].getX()) * (p[1].getY() + p[2].getY())) + ((p[2].getX() - p[0].getX()) * (p[2].getY() + p[0].getY()))))); } // fill side with value public void setSide(int s, Edge2D e){ this.linkEdge(s,e); } public void setSide(int s, Triangle2D f){ this.linkSimplex(s,f); } public int getSideNr(Point2D p0, Point2D p1){ int n = 0; n = this.getSide(p0,p1); return n; } public double getRadiusU(){ Point2D pts[] = new Point2D[n()]; pts = this.getPoints(); Point2D p0 = new Point2D.Double(); Point2D p1 = new Point2D.Double(); Point2D p2 = new Point2D.Double(); p0 = pts[0]; p1 = pts[1]; p2 = pts[2]; Point2D pm = new Point2D.Double(((0.5 * p1.getX())+(0.5 * p0.getX())),((0.5 * p1.getY())+(0.5* p0.getY()))); double c = Math.sqrt((pm.getX() * pm.getX())- (2 * (pm.getX() * p2.getX())) + (p2.getX() * p2.getX())+ (pm.getY() * pm.getY()) - (2 * (pm.getY() * p2.getY()))+ (p2.getY() * p2.getY())); double l = 2 * Math.sqrt((pm.getX() * pm.getX()) - (2 * (pm.getX() * p0.getX())) + (p0.getX() * p0.getX()) + (pm.getY() * pm.getY()) - (2 * (pm.getY() * p0.getY())) + (p0.getY() * p0.getY())); Point2D p0_1 = AlgoPoint2D.subtract(p0,pm); Point2D p1_1 = AlgoPoint2D.subtract(p1,pm); Point2D p2_1 = AlgoPoint2D.subtract(p2,pm); Point2D p0_2 = new Point2D.Double((-0.5 * l), 0); Point2D p1_2 = new Point2D.Double((0.5 * l), 0); double angle = Math.acos(((p0_1.getX() * p0_2.getX()) / (Math.sqrt(Math.pow(p0_1.getX(), 2)+ Math.pow(p0_1.getY() , 2)) * Math.sqrt((p0_2.getX() * p0_2.getX()))))); if (p1_1.getY() >0) { angle = ((2 * Math.PI) - angle); } Point2D p2_2 = new Point2D.Double((Math.cos(angle) * (p2.getX() - pm.getX())) - (Math.sin(angle) * (p2.getY() - pm.getY())), (Math.sin(angle) * (p2.getX() - pm.getX())) + (Math.cos(angle) * (p2.getY() - pm.getY()))); double b = (1 / (2 * p2_2.getY())) * ((c * c) - ( (l * l)/4)); return ((Math.sqrt((4*(b*b))+ (l*l)))/2); } public double getRadiusI(){ Point2D p[] = this.getPoints(); double p0x = p[0].getX(); double p0y = p[0].getY(); double p1x = p[1].getX(); double p1y = p[1].getY(); double p2x = p[2].getX(); double p2y = p[2].getY(); double umfang = Math.sqrt(((p0x * p0x)-(2*p0x*p1x)+(p1x * p1x)+(p0y * p0y) - (2*p0y *p1y)+ (p1y*p1y))) + Math.sqrt(((p1x * p1x)-(2*p1x*p2x)+(p2x * p2x)+(p1y * p1y) - (2*p1y *p2y)+ (p2y*p2y))) + Math.sqrt(((p2x * p2x)-(2*p2x*p0x)+(p0x * p0x)+(p2y * p2y) - (2*p2y *p0y)+ (p0y*p0y))); return this.getArea() / (umfang * 0.5); } public double getQuality(){ return this.getRadiusI()/this.getRadiusU(); } public boolean containsPoints(Point2D[] p) { for (int i = 0, n = p.length; i<n; ++i) { if (containsPoint(p[i])) return true; } return false; } /** * @return */ public boolean containsPoint(Point2D p) { for (int i=0; i<3; ++i) { if (p.equals(point[i])) return false; if (AlgoLine2D.rightSide(this.point[i],this.point[(i+1)%3],p)) return false; } return true; } private boolean validPatch(Line2D lineA[], Line2D lineB[]) { int nA = lineA.length; int nB = lineB.length; final LineLineIntersection2D intsc = new LineLineIntersection2D(); for (int iA = 0; iA<nA; ++iA) { for (int iB = 0; iB<nB; ++iB) { intsc.setValues(lineA[iA],lineB[iB]); if (!intsc.isCoincident() && (intsc.isBI() || intsc.isIB())) { return false; } } } return true; } /** * return true if the interiors of both simplices intersect * valid only for counterclockwise simplices */ public boolean intersects(Triangle2D other) { if (!AlgoRectangle2D.intersects(this.getRectangle(),other.getRectangle())) return false; int nA = 3; int nB = 3; Line2D lineA[] = new Line2D[nA]; Line2D lineB[] = new Line2D[nB]; for (int iA = 0; iA<nA; ++iA) { lineA[iA] = new Line2D.Double(this.point[iA],this.point[(iA+1)%nA]); } for (int iB = 0; iB<nB; ++iB) { lineB[iB] = new Line2D.Double(other.point[iB],other.point[(iB+1)%nB]); } if (!validPatch(lineA, lineB) || !validPatch(lineB, lineA)) return true; if (this.containsPoints(other.point)) return true; if (other.containsPoints(this.point)) return true; return false; } }