| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * 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. |
| */ |
| |
| #include "core/geometry.h" |
| |
| #include <cmath> |
| |
| #include "base/logging.h" |
| |
| namespace android { |
| namespace filterfw { |
| |
| float Point::Length() const { |
| return std::sqrt(x_ * x_ + y_ * y_); |
| } |
| |
| bool Point::ScaleTo(float new_length) { |
| float length = Length(); |
| if (length == 0.0f) { |
| return false; |
| } |
| x_ *= new_length / length; |
| y_ *= new_length / length; |
| return true; |
| } |
| |
| float Point::Distance(const Point& p0, const Point& p1) { |
| Point diff = p1 - p0; |
| return diff.Length(); |
| } |
| |
| Point Point::operator+(const Point& other) const { |
| Point out; |
| out.x_ = x_ + other.x_; |
| out.y_ = y_ + other.y_; |
| return out; |
| } |
| |
| Point Point::operator-(const Point& other) const { |
| Point out; |
| out.x_ = x_ - other.x_; |
| out.y_ = y_ - other.y_; |
| return out; |
| } |
| |
| Point Point::operator*(float factor) const { |
| Point out; |
| out.x_ = factor * x_; |
| out.y_ = factor * y_; |
| return out; |
| } |
| |
| void Point::Rotate90Clockwise() { |
| const float x = x_; |
| x_ = y_; |
| y_ = -x; |
| } |
| |
| bool Rect::ExpandToAspectRatio(float ratio) { |
| if (width <= 0.0f || height <= 0.0f || ratio <= 0.0f) { |
| return false; |
| } |
| |
| const float current_ratio = width / height; |
| if (current_ratio < ratio) { |
| const float dx = width * (ratio / current_ratio - 1.0f); |
| x -= dx / 2.0f; |
| width += dx; |
| } else { |
| const float dy = height * (current_ratio / ratio - 1.0f); |
| y -= dy / 2.0f; |
| height += dy; |
| } |
| return true; |
| } |
| |
| bool Rect::ExpandToMinLength(float length) { |
| if (width <= 0.0f || height <= 0.0f || length <= 0.0f) { |
| return false; |
| } |
| |
| const float current_length = width > height ? width : height; |
| if (length > current_length) { |
| const float dx = width * (length / current_length - 1.0f); |
| x -= dx / 2.0f; |
| width += dx; |
| const float dy = height * (length / current_length - 1.0f); |
| y -= dy / 2.0f; |
| height += dy; |
| } |
| return true; |
| } |
| |
| bool Rect::ScaleWithLengthLimit(float factor, float max_length) { |
| if (width <= 0.0f || height <= 0.0f || factor <= 0.0f) { |
| return false; |
| } |
| |
| const float current_length = width > height ? width : height; |
| if (current_length >= max_length) { |
| return true; |
| } |
| |
| float f = factor; |
| if (current_length * f > max_length) { |
| f *= max_length / (current_length * f); |
| } |
| |
| const float dx = width * (f - 1.0f); |
| x -= dx / 2.0f; |
| width += dx; |
| const float dy = height * (f - 1.0f); |
| y -= dy / 2.0f; |
| height += dy; |
| return true; |
| } |
| |
| const Point& Quad::point(int ix) const { |
| ALOG_ASSERT(ix < static_cast<int>(points_.size()), "Access out of bounds"); |
| return points_[ix]; |
| } |
| |
| } // namespace filterfw |
| } // namespace android |