/* * Copyright 2003-2010 Tufts University Licensed under the * Educational Community License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. */ package tufts.vue.shape; import java.awt.geom.RectangularShape; import java.awt.geom.Rectangle2D; import java.awt.geom.PathIterator; import java.awt.geom.AffineTransform; /** * This class implements a triangular polygon shape. * @author Scott Fraize */ public class Triangle2D extends RectangularShape { protected double x; protected double y; protected double width; protected double height; protected boolean upsidedown = false; public Triangle2D(double x, double y, double width, double height, boolean upsidedown) { setFrame(x, y, width, height); this.upsidedown = upsidedown; } public Triangle2D(double x, double y, double width, double height) { this(x, y, width, height, false); } /** does shape contain point? */ public boolean contains(double px, double py) { // first, do a simple bounds check if (px < x || py < y || px > x + width || py > y + height) return false; //for each segment:if CCW < 0 for all segments (and all segments ordered "clockwise") // then point is in this polygon //Line2D.relativeCCW(x1, y1, x2, y2, px, py); return true; } /** does shape entirely contain rectangle? */ public boolean contains(double x, double y, double w, double h) { return contains(x, y) && contains(x+w, y+h); // todo: should work to check opposite corners for regular polygons, // but will need to check other corners if shape is irregular } /** does any part of shape intersect rectangle? */ public boolean intersects(double x, double y, double w, double h) { return contains(x, y) || contains(x+w, y+h); // todo: need to do intersection check for each of the 4 lines in the rectangle } public Rectangle2D getBounds2D() { return new Rectangle2D.Double(x, y, width, height); } public double getHeight() { return height; } public double getWidth() { return width; } public double getX() { return x; } public double getY() { return y; } public boolean isEmpty() { return width <= 0 || height <= 0; } public void setFrame(double x, double y, double width, double height) { this.x = x; this.y = y; this.width = width; this.height = height; } public PathIterator getPathIterator(AffineTransform affineTransform) { return new TriIterator(affineTransform); } class TriIterator implements PathIterator { int index = 0; AffineTransform affine; public TriIterator(AffineTransform affine) { this.affine = affine; } double[][] dCurrentPoint = { {x + width/2, y}, {x, y + height}, {x + width, y + height}, {0,0}, }; // upsidedown triangle double[][] dCurrentPointUD = { {x, y}, {x + width/2, y + height}, {x + width, y}, {0,0} }; final int[] segment = { SEG_MOVETO, SEG_LINETO, SEG_LINETO, SEG_CLOSE }; public int currentSegment(double[] coords) { if (upsidedown) { coords[0] = dCurrentPointUD[index][0]; coords[1] = dCurrentPointUD[index][1]; } else { coords[0] = dCurrentPoint[index][0]; coords[1] = dCurrentPoint[index][1]; } if (affine != null) affine.transform(coords, 0, coords, 0, 1); //System.out.println("i"+index + " TriIterator(double)coords=" +coords[0] + "," + coords[1]); return segment[index]; } public int currentSegment(float[] coords){ if (upsidedown) { coords[0] = (float)dCurrentPointUD[index][0]; coords[1] = (float)dCurrentPointUD[index][1]; } else { coords[0] = (float)dCurrentPoint[index][0]; coords[1] = (float)dCurrentPoint[index][1]; } if (affine != null) affine.transform(coords, 0, coords, 0, 1); //System.out.println("i"+index + " TriIterator(float)coords=" +coords[0] + "," + coords[1]); return segment[index]; } public int getWindingRule() { return PathIterator.WIND_NON_ZERO; } public boolean isDone() { return index == 4; } public void next() { index++ ; } } }