001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017/** 018 * @author Denis M. Kishenko 019 * @version $Revision$ 020 */ 021//THIS CLASS MODIFIED TO WORK ON ANDROID 022 023package armyc2.c5isr.graphics2d; 024 025 026import android.graphics.Path; 027import android.graphics.RectF; 028import java.util.Arrays; 029 030/** 031 * 032* 033 */ 034public class Polygon { 035 036 /** 037 * The points buffer capacity 038 */ 039 private static final int BUFFER_CAPACITY = 4; 040 041 public int npoints; 042 public int xpoints[]; 043 public int ypoints[]; 044 protected Rectangle bounds; 045 046 public Polygon() { 047 xpoints = new int[BUFFER_CAPACITY]; 048 ypoints = new int[BUFFER_CAPACITY]; 049 } 050 051 /** 052 * 053 * @param xpoints 054 * @param ypoints 055 * @param npoints 056 */ 057 public Polygon(int xpoints[], int ypoints[], int npoints) { 058 059 if (npoints > xpoints.length || npoints > ypoints.length) { 060 // awt.111=Parameter npoints is greater than array length 061 throw new IndexOutOfBoundsException("Parameter npoints is greater than array length"); 062 } 063 064 if (npoints < 0) { 065 // awt.112=Negative number of points 066 throw new NegativeArraySizeException("Negative number of points"); 067 } 068 069 this.npoints = npoints; 070 this.xpoints = Arrays.copyOf(xpoints, npoints); 071 this.ypoints = Arrays.copyOf(ypoints, npoints); 072 } 073 074 public void reset() { 075 npoints = 0; 076 bounds = null; 077 } 078 public void invalidate() { 079 bounds = null; 080 } 081 082 083 public void addPoint(int px, int py) { 084 if (npoints == xpoints.length) { 085 int[] tmp; 086 087 tmp = new int[xpoints.length + BUFFER_CAPACITY]; 088 System.arraycopy(xpoints, 0, tmp, 0, xpoints.length); 089 xpoints = tmp; 090 091 tmp = new int[ypoints.length + BUFFER_CAPACITY]; 092 System.arraycopy(ypoints, 0, tmp, 0, ypoints.length); 093 ypoints = tmp; 094 } 095 xpoints[npoints] = px; 096 ypoints[npoints] = py; 097 npoints++; 098 if (bounds != null) { 099 100 Rectangle temp = new Rectangle(Math.min(bounds.getMinX(), px), 101 Math.min(bounds.getMinY(), py), 102 Math.max(bounds.getMaxX() - bounds.getMinX(), px - bounds.getMinX()), 103 Math.max(bounds.getMaxY() - bounds.getMinY(), py - bounds.getMinY())); 104 105 bounds.setRect(temp.getX(), temp.getY(), temp.getWidth(), temp.getHeight()); 106 } 107 } 108 109 110 public Rectangle getBounds() { 111 if (bounds != null) { 112 return bounds; 113 } 114 if (npoints == 0) { 115 return new Rectangle(); 116 } 117 118 int bx1 = xpoints[0]; 119 int by1 = ypoints[0]; 120 int bx2 = bx1; 121 int by2 = by1; 122 123 for (int i = 1; i < npoints; i++) { 124 int x = xpoints[i]; 125 int y = ypoints[i]; 126 if (x < bx1) { 127 bx1 = x; 128 } else if (x > bx2) { 129 bx2 = x; 130 } 131 if (y < by1) { 132 by1 = y; 133 } else if (y > by2) { 134 by2 = y; 135 } 136 } 137 138 return bounds = new Rectangle(bx1, by1, bx2 - bx1, by2 - by1); 139 140 } 141 142 public Rectangle getBoundingBox() { 143 return getBounds(); 144 } 145 146 public boolean contains(Point p) { 147 return contains(p.x, p.y); 148 } 149 150 public boolean contains(int x, int y) { 151 return contains((double) x, (double) y); 152 } 153 154 155 156 public Rectangle2D getBounds2D() { 157 //return getBounds(); 158 return null; 159 }// 160 161 162 public boolean contains(double x, double y) { 163 if (npoints <= 2 || !getBoundingBox().contains((int)x, (int)y)) { 164 return false; 165 } 166 int hits = 0; 167 168 int lastx = xpoints[npoints - 1]; 169 int lasty = ypoints[npoints - 1]; 170 int curx, cury; 171 172 for (int i = 0; i < npoints; lastx = curx, lasty = cury, i++) { 173 curx = xpoints[i]; 174 cury = ypoints[i]; 175 176 if (cury == lasty) { 177 continue; 178 } 179 180 int leftx; 181 if (curx < lastx) { 182 if (x >= lastx) { 183 continue; 184 } 185 leftx = curx; 186 } else { 187 if (x >= curx) { 188 continue; 189 } 190 leftx = lastx; 191 } 192 193 double test1, test2; 194 if (cury < lasty) { 195 if (y < cury || y >= lasty) { 196 continue; 197 } 198 if (x < leftx) { 199 hits++; 200 continue; 201 } 202 test1 = x - curx; 203 test2 = y - cury; 204 } else { 205 if (y < lasty || y >= cury) { 206 continue; 207 } 208 if (x < leftx) { 209 hits++; 210 continue; 211 } 212 test1 = x - lastx; 213 test2 = y - lasty; 214 } 215 216 if (test1 < (test2 / (lasty - cury) * (lastx - curx))) { 217 hits++; 218 } 219 } 220 221 return ((hits & 1) != 0); 222 } 223 224 225 226 public boolean contains(Point2D p) { 227 return contains(p.getX(), p.getY()); 228 } 229 230 231 public boolean intersects(double x, double y, double w, double h) { 232 if (npoints <= 0 || !getBoundingBox().intersects(x, y, w, h)) { 233 return false; 234 } 235 236 if (bounds != null) { 237 float fx = (float) x; 238 float fy = (float) y; 239 float fw = (float) w; 240 float fh = (float) h; 241//not sure if math is correct here 242 Path that = new Path(); 243//start 244 that.moveTo(fx, fy); 245//go right 246 that.lineTo(fx + fw, fy); 247//go down 248 that.lineTo(fx + fw, fy - fh); 249//go left 250 that.lineTo(fx, fy - fh); 251//close 252 that.close(); 253//bounds holder 254 RectF thatBounds = new RectF(); 255 RectF rectf=new RectF((float)bounds.x,(float)bounds.y,(float)bounds.x+(float)bounds.width,(float)bounds.y+(float)bounds.height); 256 return RectF.intersects(rectf, thatBounds); 257 } 258 else 259 { 260 return false; 261 } 262 } 263 264 public boolean intersects(Rectangle2D r) { 265 return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); 266 } 267 268 public boolean contains(double x, double y, double w, double h) { 269 if (npoints <= 0 || !getBoundingBox().intersects(x, y, w, h)) { 270 return false; 271 } 272 273 return false; 274 } 275 276 public boolean contains(Rectangle2D r) { 277 return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); 278 } 279 280 281 public PathIterator getPathIterator(AffineTransform at) { 282 283 PathIterator pi=new PathIterator(null); 284 int j=0; 285 if(npoints>0) 286 { 287 pi.moveTo(xpoints[0], ypoints[0]); 288 for(j=1;j<npoints;j++) 289 { 290 pi.lineTo(xpoints[j], ypoints[j]); 291 } 292 } 293 pi.reset(); 294 return pi; 295 } 296 public PathIterator getPathIterator(AffineTransform at, double flatness) { 297 return getPathIterator(at); 298 } 299}