2 * Copyright (C) 2012 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.gallery3d.filtershow.imageshow;
19 import android.graphics.Matrix;
20 import android.graphics.RectF;
22 import java.util.Arrays;
24 public class CropMath {
27 * Gets a float array of the 2D coordinates representing a rectangles
29 * The order of the corners in the float array is:
35 * @param r the rectangle to get the corners of
36 * @return the float array of corners (8 floats)
39 public static float[] getCornersFromRect(RectF r) {
50 * Returns true iff point (x, y) is within or on the rectangle's bounds.
51 * RectF's "contains" function treats points on the bottom and right bound
52 * as not being contained.
54 * @param r the rectangle
55 * @param x the x value of the point
56 * @param y the y value of the point
59 public static boolean inclusiveContains(RectF r, float x, float y) {
60 return !(x > r.right || x < r.left || y > r.bottom || y < r.top);
64 * Takes an array of 2D coordinates representing corners and returns the
65 * smallest rectangle containing those coordinates.
67 * @param array array of 2D coordinates
68 * @return smallest rectangle containing coordinates
70 public static RectF trapToRect(float[] array) {
71 RectF r = new RectF(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY,
72 Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
73 for (int i = 1; i < array.length; i += 2) {
74 float x = array[i - 1];
76 r.left = (x < r.left) ? x : r.left;
77 r.top = (y < r.top) ? y : r.top;
78 r.right = (x > r.right) ? x : r.right;
79 r.bottom = (y > r.bottom) ? y : r.bottom;
86 * If edge point [x, y] in array [x0, y0, x1, y1, ...] is outside of the
87 * image bound rectangle, clamps it to the edge of the rectangle.
89 * @param imageBound the rectangle to clamp edge points to.
90 * @param array an array of points to clamp to the rectangle, gets set to
93 public static void getEdgePoints(RectF imageBound, float[] array) {
96 for (int x = 0; x < array.length; x += 2) {
97 array[x] = GeometryMath.clamp(array[x], imageBound.left, imageBound.right);
98 array[x + 1] = GeometryMath.clamp(array[x + 1], imageBound.top, imageBound.bottom);
103 * Takes a point and the corners of a rectangle and returns the two corners
104 * representing the side of the rectangle closest to the point.
106 * @param point the point which is being checked
107 * @param corners the corners of the rectangle
108 * @return two corners representing the side of the rectangle
110 public static float[] closestSide(float[] point, float[] corners) {
111 int len = corners.length;
112 float oldMag = Float.POSITIVE_INFINITY;
113 float[] bestLine = null;
114 for (int i = 0; i < len; i += 2) {
116 corners[i], corners[(i + 1) % len],
117 corners[(i + 2) % len], corners[(i + 3) % len]
119 float mag = GeometryMath.vectorLength(
120 GeometryMath.shortestVectorFromPointToLine(point, line));
130 * Checks if a given point is within a rotated rectangle.
132 * @param point 2D point to check
133 * @param bound rectangle to rotate
134 * @param rot angle of rotation about rectangle center
135 * @return true if point is within rotated rectangle
137 public static boolean pointInRotatedRect(float[] point, RectF bound, float rot) {
138 Matrix m = new Matrix();
139 float[] p = Arrays.copyOf(point, 2);
140 m.setRotate(rot, bound.centerX(), bound.centerY());
141 Matrix m0 = new Matrix();
145 return inclusiveContains(bound, p[0], p[1]);
149 * Checks if a given point is within a rotated rectangle.
151 * @param point 2D point to check
152 * @param rotatedRect corners of a rotated rectangle
153 * @param center center of the rotated rectangle
154 * @return true if point is within rotated rectangle
156 public static boolean pointInRotatedRect(float[] point, float[] rotatedRect, float[] center) {
157 RectF unrotated = new RectF();
158 float angle = getUnrotated(rotatedRect, center, unrotated);
159 return pointInRotatedRect(point, unrotated, angle);
163 * Resizes rectangle to have a certain aspect ratio (center remains
166 * @param r rectangle to resize
167 * @param w new width aspect
168 * @param h new height aspect
170 public static void fixAspectRatio(RectF r, float w, float h) {
171 float scale = Math.min(r.width() / w, r.height() / h);
172 float centX = r.centerX();
173 float centY = r.centerY();
174 float hw = scale * w / 2;
175 float hh = scale * h / 2;
176 r.set(centX - hw, centY - hh, centX + hw, centY + hh);
179 private static float getUnrotated(float[] rotatedRect, float[] center, RectF unrotated) {
180 float dy = rotatedRect[1] - rotatedRect[3];
181 float dx = rotatedRect[0] - rotatedRect[2];
182 float angle = (float) (Math.atan(dy / dx) * 180 / Math.PI);
183 Matrix m = new Matrix();
184 m.setRotate(-angle, center[0], center[1]);
185 float[] unrotatedRect = new float[rotatedRect.length];
186 m.mapPoints(unrotatedRect, rotatedRect);
187 unrotated.set(trapToRect(unrotatedRect));