165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/*
265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project
365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License");
565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License.
665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at
765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *      http://www.apache.org/licenses/LICENSE-2.0
965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software
1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS,
1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and
1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License.
1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "core/geometry.h"
1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <cmath>
2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "base/logging.h"
2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennnamespace android {
2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennnamespace filterfw {
2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennfloat Point::Length() const {
2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return std::sqrt(x_ * x_ + y_ * y_);
2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool Point::ScaleTo(float new_length) {
3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  float length = Length();
3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (length == 0.0f) {
3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return false;
3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  x_ *= new_length / length;
3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  y_ *= new_length / length;
3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return true;
3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennfloat Point::Distance(const Point& p0, const Point& p1) {
4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point diff = p1 - p0;
4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return diff.Length();
4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennPoint Point::operator+(const Point& other) const {
4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point out;
4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.x_ = x_ + other.x_;
4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.y_ = y_ + other.y_;
4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return out;
5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennPoint Point::operator-(const Point& other) const {
5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point out;
5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.x_ = x_ - other.x_;
5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.y_ = y_ - other.y_;
5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return out;
5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennPoint Point::operator*(float factor) const {
6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point out;
6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.x_ = factor * x_;
6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.y_ = factor * y_;
6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return out;
6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid Point::Rotate90Clockwise() {
6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float x = x_;
6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  x_ = y_;
6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  y_ = -x;
7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool Rect::ExpandToAspectRatio(float ratio) {
7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (width <= 0.0f || height <= 0.0f || ratio <= 0.0f) {
7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return false;
7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float current_ratio = width / height;
7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (current_ratio < ratio) {
7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const float dx = width * (ratio / current_ratio - 1.0f);
8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    x -= dx / 2.0f;
8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    width += dx;
8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  } else {
8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const float dy = height * (current_ratio / ratio - 1.0f);
8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    y -= dy / 2.0f;
8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    height += dy;
8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return true;
8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool Rect::ExpandToMinLength(float length) {
9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (width <= 0.0f || height <= 0.0f || length <= 0.0f) {
9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return false;
9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float current_length = width > height ? width : height;
9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (length > current_length) {
9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const float dx = width * (length / current_length - 1.0f);
9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    x -= dx / 2.0f;
9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    width += dx;
10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const float dy = height * (length / current_length - 1.0f);
10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    y -= dy / 2.0f;
10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    height += dy;
10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return true;
10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool Rect::ScaleWithLengthLimit(float factor, float max_length) {
10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (width <= 0.0f || height <= 0.0f || factor <= 0.0f) {
10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return false;
11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float current_length = width > height ? width : height;
11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (current_length >= max_length) {
11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return true;
11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  float f = factor;
11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (current_length * f > max_length) {
11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    f *= max_length / (current_length * f);
12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float dx = width * (f - 1.0f);
12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  x -= dx / 2.0f;
12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  width += dx;
12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float dy = height * (f - 1.0f);
12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  y -= dy / 2.0f;
12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  height += dy;
12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return true;
12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennconst Point& Quad::point(int ix) const {
13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  ALOG_ASSERT(ix < static_cast<int>(points_.size()), "Access out of bounds");
13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return points_[ix];
13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} // namespace filterfw
13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} // namespace android
138