/src/org/mt4j/util/math/ConvexQuickHull2D.java
Java | 159 lines | 87 code | 13 blank | 59 comment | 20 complexity | d893d15bf956b14128a651108a69cfaf MD5 | raw file
1/*********************************************************************** 2 * mt4j Copyright (c) 2008 - 2009 C.Ruff, Fraunhofer-Gesellschaft All rights reserved. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * 17 ***********************************************************************/ 18package org.mt4j.util.math; 19 20import java.util.ArrayList; 21 22/** 23 * The Class ConvexQuickHull2D. 24 */ 25public class ConvexQuickHull2D{ 26 27 /** 28 * Gets the convex hull2 d. 29 * 30 * @param Vector3Ds the vector3 ds 31 * 32 * @return the convex hull2 d 33 */ 34 @SuppressWarnings("unchecked") 35public static ArrayList<Vector3D> getConvexHull2D(ArrayList<Vector3D> Vector3Ds) { 36 ArrayList<Vector3D> convexHull = new ArrayList<Vector3D>(); 37 if (Vector3Ds.size() < 3) return (ArrayList<Vector3D>) Vector3Ds.clone(); 38 // find extremals 39 int minVector3D = -1, maxVector3D = -1; 40 float minX = Float.POSITIVE_INFINITY; 41 float maxX = Float.NEGATIVE_INFINITY; 42 for (int i = 0; i < Vector3Ds.size(); i++) { 43 if (Vector3Ds.get(i).getX() < minX) { 44 minX = Vector3Ds.get(i).getX(); 45 minVector3D = i; 46 } 47 if (Vector3Ds.get(i).getX() > maxX) { 48 maxX = Vector3Ds.get(i).getX(); 49 maxVector3D = i; 50 } 51 } 52 Vector3D A = Vector3Ds.get(minVector3D); 53 Vector3D B = Vector3Ds.get(maxVector3D); 54 convexHull.add(A); 55 convexHull.add(B); 56 Vector3Ds.remove(A); 57 Vector3Ds.remove(B); 58 59 ArrayList<Vector3D> leftSet = new ArrayList<Vector3D>(); 60 ArrayList<Vector3D> rightSet = new ArrayList<Vector3D>(); 61 62 for (Vector3D p : Vector3Ds) { 63 if (Vector3DLocation(A, B, p) == -1) 64 leftSet.add(p); 65 else 66 rightSet.add(p); 67 } 68 hullSet(A,B,rightSet,convexHull); 69 hullSet(B,A,leftSet,convexHull); 70 71 return convexHull; 72 } 73 74 /* 75 * Computes the square of the distance of Vector3D C to the segment defined by Vector3Ds AB 76 */ 77 /** 78 * Distance. 79 * 80 * @param A the a 81 * @param B the b 82 * @param C the c 83 * 84 * @return the float 85 */ 86 private static float distance(Vector3D A, Vector3D B, Vector3D C) { 87 float ABx = B.getX()-A.getX(); 88 float ABy = B.getY()-A.getY(); 89 float num = ABx*(A.getY()-C.getY())-ABy*(A.getX()-C.getX()); 90 if (num < 0) num = -num; 91 return num; 92 } 93 94 /** 95 * Hull set. 96 * 97 * @param A the a 98 * @param B the b 99 * @param set the set 100 * @param hull the hull 101 */ 102 private static void hullSet(Vector3D A, Vector3D B, ArrayList<Vector3D> set, ArrayList<Vector3D> hull) { 103 int insertPosition = hull.indexOf(B); 104 if (set.size() == 0) return; 105 if (set.size() == 1) { 106 Vector3D p = set.get(0); 107 set.remove(p); 108 hull.add(insertPosition,p); 109 return; 110 } 111 float dist = Float.NEGATIVE_INFINITY; 112 int furthestVector3D = -1; 113 for (int i = 0; i < set.size(); i++) { 114 Vector3D p = set.get(i); 115 float distance = distance(A,B,p); 116 if (distance > dist) { 117 dist = distance; 118 furthestVector3D = i; 119 } 120 } 121 Vector3D P = set.get(furthestVector3D); 122 set.remove(furthestVector3D); 123 hull.add(insertPosition,P); 124 125 // Determine who's to the left of AP 126 ArrayList<Vector3D> leftSetAP = new ArrayList<Vector3D>(); 127 for (Vector3D M : set) { 128 if (Vector3DLocation(A, P, M) == 1) { 129 leftSetAP.add(M); 130 } 131 } 132 133 // Determine who's to the left of PB 134 ArrayList<Vector3D> leftSetPB = new ArrayList<Vector3D>(); 135 for (Vector3D M : set) { 136 if (Vector3DLocation(P, B, M) == 1) { 137 leftSetPB.add(M); 138 } 139 } 140 hullSet(A,P,leftSetAP,hull); 141 hullSet(P,B,leftSetPB,hull); 142 143 } 144 145 /** 146 * Vector3 d location. 147 * 148 * @param A the a 149 * @param B the b 150 * @param P the p 151 * 152 * @return the float 153 */ 154 private static float Vector3DLocation(Vector3D A, Vector3D B, Vector3D P) { 155 float cp1 = (B.getX()-A.getX())*(P.getY()-A.getY()) - (B.getY()-A.getY())*(P.getX()-A.getX()); 156 return (cp1>0)?1:-1; 157 } 158 159}