119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard/* 219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * Copyright (C) 2012 The Android Open Source Project 319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * 419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * Licensed under the Apache License, Version 2.0 (the "License"); 519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * you may not use this file except in compliance with the License. 619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * You may obtain a copy of the License at 719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * 819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * http://www.apache.org/licenses/LICENSE-2.0 919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * 1019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * Unless required by applicable law or agreed to in writing, software 1119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * distributed under the License is distributed on an "AS IS" BASIS, 1219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * See the License for the specific language governing permissions and 1419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard * limitations under the License. 1519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard */ 1619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 1719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardpackage com.android.camera.crop; 1819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 1919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport android.graphics.Bitmap; 2019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport android.graphics.Canvas; 2119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport android.graphics.Matrix; 2219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport android.graphics.Paint; 2319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport android.graphics.Rect; 2419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport android.graphics.RectF; 2519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 2619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard/* 2719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.cache.BitmapCache; 2819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.cache.ImageLoader; 2919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.filters.FilterCropRepresentation; 3019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation; 3119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation.Mirror; 3219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.filters.FilterRepresentation; 3319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.filters.FilterRotateRepresentation; 3419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.filters.FilterRotateRepresentation.Rotation; 3519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.filters.FilterStraightenRepresentation; 3619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.gallery3d.filtershow.pipeline.ImagePreset; 3719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard*/ 3819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 3919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport java.util.Collection; 4019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport java.util.Iterator; 4119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 4219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardpublic final class GeometryMathUtils { 4319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard private static final String TAG = "GeometryMathUtils"; 4419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static final float SHOW_SCALE = .9f; 4519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 4619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard private GeometryMathUtils() {}; 4719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 4819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard // Math operations for 2d vectors 4919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float clamp(float i, float low, float high) { 5019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return Math.max(Math.min(i, high), low); 5119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 5219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 5319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float[] lineIntersect(float[] line1, float[] line2) { 5419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float a0 = line1[0]; 5519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float a1 = line1[1]; 5619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float b0 = line1[2]; 5719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float b1 = line1[3]; 5819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float c0 = line2[0]; 5919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float c1 = line2[1]; 6019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float d0 = line2[2]; 6119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float d1 = line2[3]; 6219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float t0 = a0 - b0; 6319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float t1 = a1 - b1; 6419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float t2 = b0 - d0; 6519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float t3 = d1 - b1; 6619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float t4 = c0 - d0; 6719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float t5 = c1 - d1; 6819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 6919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float denom = t1 * t4 - t0 * t5; 7019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard if (denom == 0) 7119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return null; 7219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float u = (t3 * t4 + t5 * t2) / denom; 7319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float[] intersect = { 7419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard b0 + u * t0, b1 + u * t1 7519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard }; 7619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return intersect; 7719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 7819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 7919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float[] shortestVectorFromPointToLine(float[] point, float[] line) { 8019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float x1 = line[0]; 8119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float x2 = line[2]; 8219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float y1 = line[1]; 8319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float y2 = line[3]; 8419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float xdelt = x2 - x1; 8519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float ydelt = y2 - y1; 8619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard if (xdelt == 0 && ydelt == 0) 8719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return null; 8819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float u = ((point[0] - x1) * xdelt + (point[1] - y1) * ydelt) 8919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard / (xdelt * xdelt + ydelt * ydelt); 9019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float[] ret = { 9119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard (x1 + u * (x2 - x1)), (y1 + u * (y2 - y1)) 9219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard }; 9319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float[] vec = { 9419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard ret[0] - point[0], ret[1] - point[1] 9519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard }; 9619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return vec; 9719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 9819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 9919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard // A . B 10019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float dotProduct(float[] a, float[] b) { 10119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return a[0] * b[0] + a[1] * b[1]; 10219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 10319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 10419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float[] normalize(float[] a) { 10519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float length = (float) Math.sqrt(a[0] * a[0] + a[1] * a[1]); 10619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float[] b = { 10719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard a[0] / length, a[1] / length 10819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard }; 10919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return b; 11019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 11119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 11219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard // A onto B 11319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float scalarProjection(float[] a, float[] b) { 11419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float length = (float) Math.sqrt(b[0] * b[0] + b[1] * b[1]); 11519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return dotProduct(a, b) / length; 11619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 11719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 11819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float[] getVectorFromPoints(float[] point1, float[] point2) { 11919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float[] p = { 12019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard point2[0] - point1[0], point2[1] - point1[1] 12119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard }; 12219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return p; 12319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 12419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 12519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float[] getUnitVectorFromPoints(float[] point1, float[] point2) { 12619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float[] p = { 12719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard point2[0] - point1[0], point2[1] - point1[1] 12819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard }; 12919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float length = (float) Math.sqrt(p[0] * p[0] + p[1] * p[1]); 13019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard p[0] = p[0] / length; 13119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard p[1] = p[1] / length; 13219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return p; 13319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 13419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 13519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static void scaleRect(RectF r, float scale) { 13619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard r.set(r.left * scale, r.top * scale, r.right * scale, r.bottom * scale); 13719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 13819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 13919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard // A - B 14019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float[] vectorSubtract(float[] a, float[] b) { 14119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard int len = a.length; 14219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard if (len != b.length) 14319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return null; 14419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard float[] ret = new float[len]; 14519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard for (int i = 0; i < len; i++) { 14619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard ret[i] = a[i] - b[i]; 14719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 14819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return ret; 14919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 15019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 15119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float vectorLength(float[] a) { 15219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return (float) Math.sqrt(a[0] * a[0] + a[1] * a[1]); 15319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 15419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 15519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static float scale(float oldWidth, float oldHeight, float newWidth, float newHeight) { 15619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard if (oldHeight == 0 || oldWidth == 0 || (oldWidth == newWidth && oldHeight == newHeight)) { 15719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return 1; 15819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 15919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return Math.min(newWidth / oldWidth, newHeight / oldHeight); 16019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 16119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 16219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard public static Rect roundNearest(RectF r) { 16319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard Rect q = new Rect(Math.round(r.left), Math.round(r.top), Math.round(r.right), 16419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard Math.round(r.bottom)); 16519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return q; 16619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 16719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 16819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard private static int getRotationForOrientation(int orientation) { 16919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard switch (orientation) { 17019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard case ImageLoader.ORI_ROTATE_90: 17119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return 90; 17219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard case ImageLoader.ORI_ROTATE_180: 17319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return 180; 17419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard case ImageLoader.ORI_ROTATE_270: 17519ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return 270; 17619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard default: 17719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard return 0; 17819ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 17919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard } 18019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard 18119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard} 182