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 <cutils/log.h>
1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <cmath>
1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "geometry.h"
2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennnamespace android {
2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennnamespace filterfw {
2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennfloat Point::Length() const {
2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return std::sqrt(x_ * x_ + y_ * y_);
2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool Point::ScaleTo(float new_length) {
3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  float length = Length();
3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (length == 0.0f) {
3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return false;
3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  x_ *= new_length / length;
3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  y_ *= new_length / length;
3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return true;
3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennfloat Point::Distance(const Point& p0, const Point& p1) {
4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point diff = p1 - p0;
4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return diff.Length();
4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennPoint Point::operator+(const Point& other) const {
4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point out;
4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.x_ = x_ + other.x_;
4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.y_ = y_ + other.y_;
4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return out;
4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennPoint Point::operator-(const Point& other) const {
5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point out;
5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.x_ = x_ - other.x_;
5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.y_ = y_ - other.y_;
5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return out;
5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennPoint Point::operator*(float factor) const {
5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point out;
6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.x_ = factor * x_;
6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  out.y_ = factor * y_;
6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return out;
6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid Point::Rotate90Clockwise() {
6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float x = x_;
6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  x_ = y_;
6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  y_ = -x;
6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool Rect::ExpandToAspectRatio(float ratio) {
7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (width <= 0.0f || height <= 0.0f || ratio <= 0.0f) {
7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return false;
7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float current_ratio = width / height;
7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (current_ratio < ratio) {
7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const float dx = width * (ratio / current_ratio - 1.0f);
7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    x -= dx / 2.0f;
8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    width += dx;
8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  } else {
8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const float dy = height * (current_ratio / ratio - 1.0f);
8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    y -= dy / 2.0f;
8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    height += dy;
8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return true;
8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool Rect::ExpandToMinLength(float length) {
9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (width <= 0.0f || height <= 0.0f || length <= 0.0f) {
9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return false;
9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float current_length = width > height ? width : height;
9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (length > current_length) {
9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const float dx = width * (length / current_length - 1.0f);
9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    x -= dx / 2.0f;
9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    width += dx;
9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const float dy = height * (length / current_length - 1.0f);
10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    y -= dy / 2.0f;
10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    height += dy;
10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return true;
10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool Rect::ScaleWithLengthLimit(float factor, float max_length) {
10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (width <= 0.0f || height <= 0.0f || factor <= 0.0f) {
10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return false;
10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float current_length = width > height ? width : height;
11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (current_length >= max_length) {
11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return true;
11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  float f = factor;
11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (current_length * f > max_length) {
11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    f *= max_length / (current_length * f);
11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float dx = width * (f - 1.0f);
12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  x -= dx / 2.0f;
12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  width += dx;
12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  const float dy = height * (f - 1.0f);
12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  y -= dy / 2.0f;
12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  height += dy;
12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return true;
12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennconst Point& Quad::point(int ix) const {
13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  ALOG_ASSERT(ix < static_cast<int>(points_.size()), "Access out of bounds");
13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return points_[ix];
13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool SlantedRect::FromCenterAxisAndLengths(const Point& center,
13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                           const Point& vert_axis,
13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                           const Point& lengths) {
13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point dy = vert_axis;
13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!dy.ScaleTo(lengths.y() / 2.0f)) {
14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    ALOGE("Illegal axis: %f %f", vert_axis.x(), vert_axis.y());
14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return false;
14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  Point dx = dy;
14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  dx.Rotate90Clockwise();
14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  dx.ScaleTo(lengths.x() / 2.0f);
14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  points_[0] = center - dx - dy;
14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  points_[1] = center + dx - dy;
15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  points_[2] = center - dx + dy;
15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  points_[3] = center + dx + dy;
15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  width_ = lengths.x();
15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  height_ = lengths.y();
15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return true;
15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} // namespace filterfw
16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} // namespace android
161