/** * Copyright 2008 - 2015 The Loon Game Engine Authors * * 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. * * @project loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.5 */ package loon.geom; import loon.utils.MathUtils; /*最简化的整型体积处理类,以减少对象大小*/ public class RectI implements XY { public static class Range implements XY { public int left; public int top; public int right; public int bottom; public Range() { } public Range(RectI rect) { this(rect.left(), rect.top(), rect.right(), rect.bottom()); } public Range(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } public Range(Range r) { left = r.left; top = r.top; right = r.right; bottom = r.bottom; } @Override public boolean equals(Object obj) { Range r = (Range) obj; if (r != null) { return left == r.left && top == r.top && right == r.right && bottom == r.bottom; } return false; } public final boolean isEmpty() { return left >= right || top >= bottom; } public final int x() { return left; } public final int y() { return top; } public final int width() { return right - left; } public final int height() { return bottom - top; } public final int centerX() { return (left + right) >> 1; } public final int centerY() { return (top + bottom) >> 1; } public final float exactCenterX() { return (left + right) * 0.5f; } public final float exactCenterY() { return (top + bottom) * 0.5f; } public void setEmpty() { left = right = top = bottom = 0; } public void set(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } public void set(Range src) { this.left = src.left; this.top = src.top; this.right = src.right; this.bottom = src.bottom; } public void offset(int dx, int dy) { left += dx; top += dy; right += dx; bottom += dy; } public void offsetTo(int newLeft, int newTop) { right += newLeft - left; bottom += newTop - top; left = newLeft; top = newTop; } public void inset(int dx, int dy) { left += dx; top += dy; right -= dx; bottom -= dy; } public boolean contains(int x, int y) { return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom; } public boolean contains (Circle circle) { float xmin = circle.x - circle.radius; float xmax = xmin + 2f * circle.radius; float ymin = circle.y - circle.radius; float ymax = ymin + 2f * circle.radius; return ((xmin > getX() && xmin < getX() + width()) && (xmax > getX() && xmax < getX() + width())) && ((ymin > getY() && ymin < getY() + height()) && (ymax > getY() && ymax < getY() + height())); } public boolean contains(int left, int top, int right, int bottom) { return this.left < this.right && this.top < this.bottom && this.left <= left && this.top <= top && this.right >= right && this.bottom >= bottom; } public boolean contains(Range r) { return this.left < this.right && this.top < this.bottom && left <= r.left && top <= r.top && right >= r.right && bottom >= r.bottom; } public boolean intersect(int left, int top, int right, int bottom) { if (this.left < right && left < this.right && this.top < bottom && top < this.bottom) { if (this.left < left) { this.left = left; } if (this.top < top) { this.top = top; } if (this.right > right) { this.right = right; } if (this.bottom > bottom) { this.bottom = bottom; } return true; } return false; } public boolean intersect(Range r) { return intersect(r.left, r.top, r.right, r.bottom); } public boolean setIntersect(Range a, Range b) { if (a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom) { left = MathUtils.max(a.left, b.left); top = MathUtils.max(a.top, b.top); right = MathUtils.min(a.right, b.right); bottom = MathUtils.min(a.bottom, b.bottom); return true; } return false; } public boolean intersects(int left, int top, int right, int bottom) { return this.left < right && left < this.right && this.top < bottom && top < this.bottom; } public boolean intersects(Range a, Range b) { return a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom; } public void union(int left, int top, int right, int bottom) { if ((left < right) && (top < bottom)) { if ((this.left < this.right) && (this.top < this.bottom)) { if (this.left > left) this.left = left; if (this.top > top) this.top = top; if (this.right < right) this.right = right; if (this.bottom < bottom) this.bottom = bottom; } else { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } } } public void union(Range r) { union(r.left, r.top, r.right, r.bottom); } public void union(int x, int y) { if (x < left) { left = x; } else if (x > right) { right = x; } if (y < top) { top = y; } else if (y > bottom) { bottom = y; } } public void sort() { if (left > right) { int temp = left; left = right; right = temp; } if (top > bottom) { int temp = top; top = bottom; bottom = temp; } } public void scale(float scale) { if (scale != 1.0f) { left = (int) (left * scale + 0.5f); top = (int) (top * scale + 0.5f); right = (int) (right * scale + 0.5f); bottom = (int) (bottom * scale + 0.5f); } } public RectI getRect() { return new RectI(this); } @Override public float getX() { return x(); } @Override public float getY() { return y(); } } public int width = 0; public int height = 0; public int x = 0; public int y = 0; public RectI() { } public RectI(RectI rect) { this(rect.x, rect.y, rect.width, rect.height); } public RectI(Range range) { this(range.x(), range.y(), range.width(), range.height()); } public RectI(int x1, int y1, int w1, int h1) { this.x = x1; this.y = y1; this.width = w1; this.height = h1; } public RectI set(RectI r) { this.x = r.x; this.y = r.y; this.width = r.width; this.height = r.height; return this; } public RectI set(int x1, int y1, int w1, int h1) { this.x = x1; this.y = y1; this.width = w1; this.height = h1; return this; } public boolean inside(int x, int y) { return (x >= this.x) && ((x - this.x) < this.width) && (y >= this.y) && ((y - this.y) < this.height); } public int getRight() { return this.x + this.width; } public int getBottom() { return this.y + this.height; } public RectI getIntersection(RectI rect) { int x1 = MathUtils.max(x, rect.x); int x2 = MathUtils.min(x + width, rect.x + rect.width); int y1 = MathUtils.max(y, rect.y); int y2 = MathUtils.min(y + height, rect.y + rect.height); return new RectI(x1, y1, x2 - x1, y2 - y1); } public static RectI getIntersection(RectI a, RectI b) { int a_x = a.x; int a_r = a.getRight(); int a_y = a.y; int a_t = a.getBottom(); int b_x = b.x; int b_r = b.getRight(); int b_y = b.y; int b_t = b.getBottom(); int i_x = MathUtils.max(a_x, b_x); int i_r = MathUtils.min(a_r, b_r); int i_y = MathUtils.max(a_y, b_y); int i_t = MathUtils.min(a_t, b_t); return i_x < i_r && i_y < i_t ? new RectI(i_x, i_y, i_r - i_x, i_t - i_y) : null; } public static RectI getIntersection(RectI a, RectI b, RectI result) { int a_x = a.x; int a_r = a.getRight(); int a_y = a.y; int a_t = a.getBottom(); int b_x = b.x; int b_r = b.getRight(); int b_y = b.y; int b_t = b.getBottom(); int i_x = MathUtils.max(a_x, b_x); int i_r = MathUtils.min(a_r, b_r); int i_y = MathUtils.max(a_y, b_y); int i_t = MathUtils.min(a_t, b_t); if (i_x < i_r && i_y < i_t) { result.set(i_x, i_y, i_r - i_x, i_t - i_y); return result; } return result; } public int left() { return this.x; } public int right() { return this.x + this.width; } public int top() { return this.y; } public int bottom() { return this.y + this.height; } public int middleX() { return this.x + this.width / 2; } public int middleY() { return this.y + this.height / 2; } public int centerX() { return x + width / 2; } public int centerY() { return y + height / 2; } public Range getRange() { return new Range(this); } @Override public float getX() { return x; } @Override public float getY() { return y; } }