1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17#include <cutils/log.h> 18#include <cmath> 19 20#include "geometry.h" 21 22namespace android { 23namespace filterfw { 24 25float Point::Length() const { 26 return std::sqrt(x_ * x_ + y_ * y_); 27} 28 29bool Point::ScaleTo(float new_length) { 30 float length = Length(); 31 if (length == 0.0f) { 32 return false; 33 } 34 x_ *= new_length / length; 35 y_ *= new_length / length; 36 return true; 37} 38 39float Point::Distance(const Point& p0, const Point& p1) { 40 Point diff = p1 - p0; 41 return diff.Length(); 42} 43 44Point Point::operator+(const Point& other) const { 45 Point out; 46 out.x_ = x_ + other.x_; 47 out.y_ = y_ + other.y_; 48 return out; 49} 50 51Point Point::operator-(const Point& other) const { 52 Point out; 53 out.x_ = x_ - other.x_; 54 out.y_ = y_ - other.y_; 55 return out; 56} 57 58Point Point::operator*(float factor) const { 59 Point out; 60 out.x_ = factor * x_; 61 out.y_ = factor * y_; 62 return out; 63} 64 65void Point::Rotate90Clockwise() { 66 const float x = x_; 67 x_ = y_; 68 y_ = -x; 69} 70 71bool Rect::ExpandToAspectRatio(float ratio) { 72 if (width <= 0.0f || height <= 0.0f || ratio <= 0.0f) { 73 return false; 74 } 75 76 const float current_ratio = width / height; 77 if (current_ratio < ratio) { 78 const float dx = width * (ratio / current_ratio - 1.0f); 79 x -= dx / 2.0f; 80 width += dx; 81 } else { 82 const float dy = height * (current_ratio / ratio - 1.0f); 83 y -= dy / 2.0f; 84 height += dy; 85 } 86 return true; 87} 88 89bool Rect::ExpandToMinLength(float length) { 90 if (width <= 0.0f || height <= 0.0f || length <= 0.0f) { 91 return false; 92 } 93 94 const float current_length = width > height ? width : height; 95 if (length > current_length) { 96 const float dx = width * (length / current_length - 1.0f); 97 x -= dx / 2.0f; 98 width += dx; 99 const float dy = height * (length / current_length - 1.0f); 100 y -= dy / 2.0f; 101 height += dy; 102 } 103 return true; 104} 105 106bool Rect::ScaleWithLengthLimit(float factor, float max_length) { 107 if (width <= 0.0f || height <= 0.0f || factor <= 0.0f) { 108 return false; 109 } 110 111 const float current_length = width > height ? width : height; 112 if (current_length >= max_length) { 113 return true; 114 } 115 116 float f = factor; 117 if (current_length * f > max_length) { 118 f *= max_length / (current_length * f); 119 } 120 121 const float dx = width * (f - 1.0f); 122 x -= dx / 2.0f; 123 width += dx; 124 const float dy = height * (f - 1.0f); 125 y -= dy / 2.0f; 126 height += dy; 127 return true; 128} 129 130const Point& Quad::point(int ix) const { 131 ALOG_ASSERT(ix < static_cast<int>(points_.size()), "Access out of bounds"); 132 return points_[ix]; 133} 134 135bool SlantedRect::FromCenterAxisAndLengths(const Point& center, 136 const Point& vert_axis, 137 const Point& lengths) { 138 Point dy = vert_axis; 139 if (!dy.ScaleTo(lengths.y() / 2.0f)) { 140 ALOGE("Illegal axis: %f %f", vert_axis.x(), vert_axis.y()); 141 return false; 142 } 143 144 Point dx = dy; 145 dx.Rotate90Clockwise(); 146 dx.ScaleTo(lengths.x() / 2.0f); 147 148 points_[0] = center - dx - dy; 149 points_[1] = center + dx - dy; 150 points_[2] = center - dx + dy; 151 points_[3] = center + dx + dy; 152 153 width_ = lengths.x(); 154 height_ = lengths.y(); 155 156 return true; 157} 158 159} // namespace filterfw 160} // namespace android 161