// 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 #include #include #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 class Point2 { public: typedef T ElementType; typedef Vector2 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 Point2_b; typedef Point2 Point2_i; typedef Point2 Point2_f; typedef Point2 Point2_d; #endif // MEDIAPIPE_DEPS_POINT2_H_