138 lines
4.3 KiB
C++
138 lines
4.3 KiB
C++
// Copyright 2019 The MediaPipe Authors.
|
|
//
|
|
// 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.
|
|
//
|
|
// Class to handle two-dimensional points.
|
|
//
|
|
// The aim of this class is to be able to do sensible geometric operations
|
|
// with points and vectors, which are distinct mathematical concepts.
|
|
// Operators +, -, =, ==, <, etc. are overloaded with the proper semantics
|
|
// (e.g. Point = Point + constant * vector or Vector = Point - Point).
|
|
// For more about Point expressions, see Goldman, Ronald N., "Illicit
|
|
// Expressions in Vector Algebra," ACM Transactions on Graphics, 4(3),
|
|
// pp. 223-243, July 1985 (http://portal.acm.org/citation.cfm?id=282969).
|
|
//
|
|
// Please be careful about overflows when using points with integer types
|
|
// The calculations are carried with the same type as the vector's components
|
|
// type, e.g. if you are using uint8 as the base type, all values will be modulo
|
|
// 256. This feature is necessary to use the class in a more general framework
|
|
// where T != plain old data type.
|
|
|
|
#ifndef MEDIAPIPE_DEPS_POINT2_H_
|
|
#define MEDIAPIPE_DEPS_POINT2_H_
|
|
|
|
#include <cmath>
|
|
#include <cstdlib>
|
|
#include <iosfwd>
|
|
|
|
#include "mediapipe/framework/deps/mathutil.h"
|
|
#include "mediapipe/framework/deps/vector.h"
|
|
#include "mediapipe/framework/port/integral_types.h"
|
|
#include "mediapipe/framework/port/logging.h"
|
|
|
|
// Template class for 2D points
|
|
template <typename T>
|
|
class Point2 {
|
|
public:
|
|
typedef T ElementType;
|
|
typedef Vector2<T> Coords;
|
|
|
|
Point2() {}
|
|
Point2(const T& x, const T& y) : c_(x, y) {}
|
|
explicit Point2(const Coords& v) : c_(v) {}
|
|
|
|
Coords ToVector() const { return c_; }
|
|
|
|
void Set(const T& x, const T& y) { *this = Point2(x, y); }
|
|
|
|
T* Data() { return c_.Data(); }
|
|
const T* Data() const { return c_.Data(); }
|
|
|
|
void Clear() { *this = Point2(); }
|
|
|
|
Point2& operator+=(const Coords& v) {
|
|
c_ += v;
|
|
return *this;
|
|
}
|
|
Point2& operator-=(const Coords& v) {
|
|
c_ -= v;
|
|
return *this;
|
|
}
|
|
|
|
const T& operator[](std::size_t b) const { return Data()[b]; }
|
|
T& operator[](std::size_t b) { return Data()[b]; }
|
|
|
|
const T& x() const { return (*this)[0]; }
|
|
const T& y() const { return (*this)[1]; }
|
|
void set_x(const T& x) { (*this)[0] = x; }
|
|
void set_y(const T& y) { (*this)[1] = y; }
|
|
|
|
// Compares two points, returns true if all their components are within
|
|
// a difference of a tolerance.
|
|
bool aequal(const Point2& p, double tolerance) const {
|
|
using std::abs;
|
|
return (abs(c_[0] - p.c_[0]) <= tolerance) &&
|
|
(abs(c_[1] - p.c_[1]) <= tolerance);
|
|
}
|
|
|
|
private:
|
|
// Friend arithmetic operators.
|
|
friend Point2 operator+(const Point2& p, const Coords& v) {
|
|
return Point2(p.c_ + v);
|
|
}
|
|
friend Point2 operator+(const Coords& v, const Point2& p) {
|
|
return Point2(v + p.c_);
|
|
}
|
|
friend Point2 operator-(const Point2& p, const Coords& v) {
|
|
return Point2(p.c_ - v);
|
|
}
|
|
friend Coords operator-(const Point2& p1, const Point2& p2) {
|
|
return p1.c_ - p2.c_;
|
|
}
|
|
|
|
// Friend relational nonmember operators.
|
|
friend bool operator==(const Point2& a, const Point2& b) {
|
|
return a.c_ == b.c_;
|
|
}
|
|
friend bool operator!=(const Point2& a, const Point2& b) {
|
|
return a.c_ != b.c_;
|
|
}
|
|
friend bool operator<(const Point2& a, const Point2& b) {
|
|
return a.c_ < b.c_;
|
|
}
|
|
friend bool operator>(const Point2& a, const Point2& b) {
|
|
return a.c_ > b.c_;
|
|
}
|
|
friend bool operator<=(const Point2& a, const Point2& b) {
|
|
return a.c_ <= b.c_;
|
|
}
|
|
friend bool operator>=(const Point2& a, const Point2& b) {
|
|
return a.c_ >= b.c_;
|
|
}
|
|
|
|
// Streaming operator.
|
|
friend std::ostream& operator<<(std::ostream& out, const Point2& p) {
|
|
return out << "Point with coordinates: (" << p.c_[0] << ", " << p.c_[1]
|
|
<< ")";
|
|
}
|
|
|
|
Coords c_; // coordinates
|
|
};
|
|
|
|
typedef Point2<uint8> Point2_b;
|
|
typedef Point2<int> Point2_i;
|
|
typedef Point2<float> Point2_f;
|
|
typedef Point2<double> Point2_d;
|
|
|
|
#endif // MEDIAPIPE_DEPS_POINT2_H_
|