package graphics; import java.awt.geom.AffineTransform; import java.awt.geom.Path2D; import java.awt.geom.PathIterator; import java.awt.geom.Rectangle2D; import java.awt.geom.RectangularShape; public class HatchedRectangle extends RectangularShape { private Path2D.Double shape = new Path2D.Double(); private double x; private double y; private double w; private double h; private double hatchWidth; private double hatchDistance; public HatchedRectangle(double x, double y, double w, double h, double hatchWidth, double hatchDistance) { this.x = x; this.y = y; this.w = w; this.h = h; this.hatchWidth = hatchWidth; this.hatchDistance = hatchDistance; makeShape(); } private void makeShape() { double startY = hatchDistance; while((startY - w) < h) { if(((startY+hatchWidth) < h)) { // start left // i don't think we can have partially visible hatch shapes in this case if((startY+hatchWidth) < w) { // hit top makeShape(0d, startY, startY, 0d, startY+hatchWidth, 0d, 0d, startY+hatchWidth); } else if(startY<w) { // hit corner makeShape(0d, startY, startY, 0d, w, 0d, w, hatchWidth-(w-startY), 0d, startY+hatchWidth); } else { // hit right makeShape(0d, startY, w, startY-w, w, startY-w+hatchWidth, 0d, startY+hatchWidth); } } else if(startY < h) { if((startY-w+hatchWidth) > h) { // start corner but only partially visible hatch if((startY+hatchWidth) < w) { // hit top // not sure if this can happen, ignore } else if(startY<w) { // hit corner makeShape(0d, startY, startY, 0d, w, 0d, w, h, 0d, h); } else { // hit right makeShape(0d, startY, w, startY-w, w, h, 0d, h); } } else { // start corner if((startY+hatchWidth) < w) { // hit top makeShape(0d, startY, startY, 0d, startY+hatchWidth, 0d, hatchWidth-(h-startY), h, 0d, h); } else if(startY<w) { // hit corner makeShape( 0d, startY, startY, 0d, w,0d, w, hatchWidth-(w-startY), hatchWidth-(h-startY), h, 0d, h ); } else { // hit right makeShape(0d, startY, w, startY-w, w, startY-w+hatchWidth, hatchWidth-(h-startY), h, 0d, h); } } } else { if((startY-w+hatchWidth) > h) { // start bottom but only partially visible hatch // start bottom if((startY+hatchWidth) < w) { // hit top // not sure if this can happen, ignore } else if(startY<w) { // hit corner makeShape(startY-h, h, startY, 0d, w, 0d, w, h); } else { // hit right makeShape(startY-h, h, w, startY-w, w, h); } } else { // start bottom if((startY+hatchWidth) < w) { // hit top makeShape(startY-h, h, startY, 0d, startY+hatchWidth, 0d, startY-h+hatchWidth, h); } else if(startY<w) { // hit corner makeShape(startY-h, h, startY, 0d, w, 0d, w, hatchWidth-(w-startY), startY-h+hatchWidth, h); } else { // hit right makeShape(startY-h, h, w, startY-w, w, startY-w+hatchWidth, startY-h+hatchWidth, h); } } } startY += hatchWidth + hatchDistance; } } private void makeShape(double x1, double y1, double x2, double y2, double x3, double y3) { shape.moveTo(x1+x, y1+y); shape.lineTo(x2+x, y2+y); shape.lineTo(x3+x, y3+y); shape.closePath(); } private void makeShape(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { shape.moveTo(x1+x, y1+y); shape.lineTo(x2+x, y2+y); shape.lineTo(x3+x, y3+y); shape.lineTo(x4+x, y4+y); shape.closePath(); } private void makeShape(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5) { shape.moveTo(x1+x, y1+y); shape.lineTo(x2+x, y2+y); shape.lineTo(x3+x, y3+y); shape.lineTo(x4+x, y4+y); shape.lineTo(x5+x, y5+y); shape.closePath(); } private void makeShape(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, double x6, double y6) { shape.moveTo(x1+x, y1+y); shape.lineTo(x2+x, y2+y); shape.lineTo(x3+x, y3+y); shape.lineTo(x4+x, y4+y); shape.lineTo(x5+x, y5+y); shape.lineTo(x6+x, y6+y); shape.closePath(); } @Override public Rectangle2D getBounds2D() { return shape.getBounds2D(); } @Override public boolean contains(double x, double y) { return shape.contains(x, y); } @Override public boolean intersects(double x, double y, double w, double h) { return shape.intersects(x, y, w, h); } @Override public boolean contains(double x, double y, double w, double h) { return shape.contains(x, y, w, h); } @Override public PathIterator getPathIterator(AffineTransform at) { return shape.getPathIterator(at); } @Override public double getX() { return x; } @Override public double getY() { return y; } @Override public double getWidth() { return w; } @Override public double getHeight() { return h; } @Override public boolean isEmpty() { throw new RuntimeException("not implemented"); } @Override public void setFrame(double x, double y, double w, double h) { throw new RuntimeException("not implemented"); } }