/* Copyright 2014 The jeo project. All rights reserved. * * Licensed under the Apache 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.apache.org/licenses/LICENSE-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 io.jeo.util; import java.util.Locale; import com.vividsolutions.jts.geom.Envelope; /** * Rectangle class. * <p> * Rectangle coordinates use an "image" coordinate system in which the top left corner * is considered (0,0) and the bottom right corner considered (width, height). * </p> */ public class Rect { public final int left, bottom, right, top; public Rect(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } public Rect(int left, int top, Dimension size) { this.left = left; this.top = top; this.right = left + size.width(); this.bottom = top + size.height(); } /** * Width of rectangle. */ public int width() { return right - left; } /** * Height of rectangle. */ public int height() { return bottom - top; } /** * Dimensions of rectangle. */ public Dimension size() { return new Dimension(width(), height()); } /** * Area of rectangle. * <p> * For rectangles representing raster images this is the number of pixels * in the image. * </p> */ public int area() { return width() * height(); } /** * Scales the rectangle. * * @param scx The horizontal scaling factor. * @param scy The vertical scaling factor. * * @return The new scaled rectangle. */ public Rect scale(double scx, double scy) { return new Rect(left, top, (int)(left+width()*scx), (int)(top+height()*scy)); } /** * Determines if this rectangle intersects another rectangle. * * @param other The other rectangle. * * @return True if the two rectangles intersect otherwise false. */ public boolean intersects(Rect other) { return !(other.left > right || other.right < left || other.top > bottom || other.bottom < top); } /** * Intersects two rectangles. * * @param other The other rectangle. * @return The rectangle intersection, otherwise <code>null</code> if the two don't * intersect. */ public Rect intersect(Rect other) { if (!intersects(other)) { return null; } int l = left > other.left ? left : other.left; int t = top > other.top ? top : other.top; int r = right < other.right ? right : other.right; int b = bottom < other.bottom ? bottom : other.bottom; return new Rect(l, t, r, b); } /** * Converts the rectangle to an Envelope. */ public Envelope envelope() { return new Envelope(left, right, top, bottom); } /** * Creates a new rectangle based on the relative positions of two envelopes. * * @param bbox The first envelope meant to correspond to this rectangle. * @param other The envelope corresponding to the return envelope. * * @return The rectangle corresponding to other. */ public Rect map(Envelope bbox, Envelope other) { int l = (int)((bbox.getMinX() - other.getMinX())/other.getWidth() * width()); int t = (int)((other.getMaxY() - bbox.getMaxY())/other.getHeight() * height()); int w = (int)(bbox.getWidth() / other.getWidth() * width()); int h = (int)(bbox.getHeight() / other.getHeight() * height()); return new Rect(l, t, l+w, t+h); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Rect rect = (Rect) o; if (bottom != rect.bottom) return false; if (left != rect.left) return false; if (right != rect.right) return false; if (top != rect.top) return false; return true; } @Override public int hashCode() { int result = left; result = 31 * result + bottom; result = 31 * result + right; result = 31 * result + top; return result; } @Override public String toString() { return String.format(Locale.ROOT,"Rect(%d,%d,%d,%d)", left, top, right, bottom); } }