Face Engine SDK  5.25.0
A face detection, recognition and tracking engine.
include/fsdk/Types/Rect.h
00001 #pragma once
00002 
00003 #include <fsdk/Types/Vector2.h>
00004 
00005 namespace fsdk {
00008     template <typename Type>
00009     struct BaseRect {
00010         typedef Type ElementType;
00011 
00012         Type x;      
00013         Type y;      
00014         Type width;  
00015         Type height; 
00016 
00019         BaseRect() noexcept
00020             : x(0)
00021             , y(0)
00022             , width(0)
00023             , height(0) {
00024         }
00025 
00032         BaseRect(Type x_, Type y_, Type w_, Type h_) noexcept
00033             : x(x_)
00034             , y(y_)
00035             , width(w_)
00036             , height(h_) {
00037         }
00038 
00043         BaseRect(const Vector2<Type>& topLeft, const Vector2<Type>& bottomRight) noexcept {
00044             set(topLeft, bottomRight);
00045         }
00046 
00050         BaseRect(const BaseRect& other) noexcept {
00051             *this = other;
00052         }
00053 
00054         template <typename OtherType>
00055         BaseRect(const BaseRect<OtherType>& other) noexcept {
00056             *this = other;
00057         }
00058 
00061         void setLeft(Type l) noexcept {
00062             const auto r = right();
00063             x = l;
00064             setRight(r);
00065         }
00066 
00069         void setTop(Type t) noexcept {
00070             const auto b = bottom();
00071             y = t;
00072             setBottom(b);
00073         }
00074 
00077         void setRight(Type r) noexcept {
00078             width = r - x;
00079         }
00080 
00083         void setBottom(Type b) noexcept {
00084             height = b - y;
00085         }
00086 
00093         static BaseRect coords(Type x0, Type y0, Type x1, Type y1) noexcept {
00094             return BaseRect(x0, y0, x1 - x0, y1 - y0);
00095         }
00096 
00102         static float intersectionOverFirstRect(const BaseRect& rect1, const BaseRect& rect2) {
00103             const float inter = (rect1 & rect2).getArea();
00104             return inter / rect1.getArea();
00105         }
00106 
00112         static float intersectionOverUnion(const BaseRect& rect1, const BaseRect& rect2) {
00113             const float inter = (rect1 & rect2).getArea();
00114             return inter / (rect1.getArea() + rect2.getArea() - inter);
00115         }
00116 
00122         static float intersectionOverForeground(const BaseRect& rect1, const BaseRect& rect2) {
00123             if(rect1.getArea() < rect2.getArea()) {
00124                 return intersectionOverFirstRect(rect1, rect2);
00125             }
00126             return intersectionOverFirstRect(rect2, rect1);
00127         }
00128 
00133         template <typename OtherType>
00134         BaseRect& operator=(const BaseRect<OtherType>& other) noexcept {
00135             if(reinterpret_cast<const void*>(this) != reinterpret_cast<const void*>(&other)) {
00136                 x = static_cast<Type>(other.x);
00137                 y = static_cast<Type>(other.y);
00138                 width = static_cast<Type>(other.width);
00139                 height = static_cast<Type>(other.height);
00140             }
00141             return *this;
00142         }
00143 
00148         template <typename OtherType>
00149         bool operator==(const BaseRect<OtherType>& other) const noexcept {
00150             return x == other.x && y == other.y && width == other.width && height == other.height;
00151         }
00152 
00157         template <typename OtherType>
00158         bool operator!=(const BaseRect<OtherType>& other) const noexcept {
00159             return !(*this == other);
00160         }
00161 
00166         BaseRect operator&(const BaseRect& other) const noexcept {
00167             BaseRect newRect;
00168             newRect.x = x > other.x ? x : other.x;
00169             newRect.y = y > other.y ? y : other.y;
00170             newRect.width = (x + width < other.x + other.width ? x + width : other.x + other.width) - newRect.x;
00171             newRect.height =
00172                 (y + height < other.y + other.height ? y + height : other.y + other.height) - newRect.y;
00173             if(newRect.width <= 0 || newRect.height <= 0)
00174                 newRect = BaseRect();
00175             return newRect;
00176         }
00177 
00182         BaseRect operator&=(const BaseRect& other) noexcept {
00183             if(this != &other)
00184                 *this = *this & other;
00185 
00186             return *this;
00187         }
00188 
00193         BaseRect operator|(const BaseRect& other) const noexcept {
00194             BaseRect newRect;
00195             newRect.x = x < other.x ? x : other.x;
00196             newRect.y = y < other.y ? y : other.y;
00197             newRect.width = (x + width > other.x + other.width ? x + width : other.x + other.width) - newRect.x;
00198             newRect.height =
00199                 (y + height > other.y + other.height ? y + height : other.y + other.height) - newRect.y;
00200 
00201             return newRect;
00202         }
00203 
00208         BaseRect operator|=(const BaseRect& other) noexcept {
00209             if(this != &other)
00210                 *this = *this & other;
00211 
00212             return *this;
00213         }
00214 
00219         BaseRect operator*(float scaleFactor) const noexcept {
00220             BaseRect newRect;
00221             newRect.x = static_cast<Type>(x * scaleFactor);
00222             newRect.y = static_cast<Type>(y * scaleFactor);
00223             newRect.width = static_cast<Type>(width * scaleFactor);
00224             newRect.height = static_cast<Type>(height * scaleFactor);
00225 
00226             return newRect;
00227         }
00228 
00233         BaseRect operator/(float scaleFactor) const noexcept {
00234             BaseRect newRect;
00235             newRect.x = static_cast<Type>(x / scaleFactor);
00236             newRect.y = static_cast<Type>(y / scaleFactor);
00237             newRect.width = static_cast<Type>(width / scaleFactor);
00238             newRect.height = static_cast<Type>(height / scaleFactor);
00239 
00240             return newRect;
00241         }
00242 
00243         BaseRect operator+(Vector2<typename BaseRect::ElementType> vec) {
00244             BaseRect newRect = *this;
00245             newRect.x += vec.x;
00246             newRect.y += vec.y;
00247 
00248             return newRect;
00249         }
00250 
00251         BaseRect operator-(Vector2<typename BaseRect::ElementType> vec) {
00252             BaseRect newRect = *this;
00253             newRect.x -= vec.x;
00254             newRect.y -= vec.y;
00255 
00256             return newRect;
00257         }
00258 
00262         Vector2<Type> size() const noexcept {
00263             return Vector2<Type>(width, height);
00264         }
00265 
00269         Vector2<Type> topLeft() const noexcept {
00270             return Vector2<Type>(x, y);
00271         }
00272 
00276         Vector2<Type> center() const noexcept {
00277             return Vector2<Type>(x + width / 2, y + height / 2);
00278         }
00279 
00283         Vector2<Type> bottomRight() const noexcept {
00284             return Vector2<Type>(x + width, y + height);
00285         }
00286 
00290         Type top() const noexcept {
00291             return y;
00292         }
00293 
00297         Type bottom() const noexcept {
00298             return y + height;
00299         }
00300 
00304         Type left() const noexcept {
00305             return x;
00306         }
00307 
00311         Type right() const noexcept {
00312             return x + width;
00313         }
00314 
00319         void set(const Vector2<Type>& topLeft, const Vector2<Type>& bottomRight) noexcept {
00320             x = topLeft.x;
00321             y = topLeft.y;
00322             width = bottomRight.x - x;
00323             height = bottomRight.y - y;
00324         }
00325 
00332         void adjust(Type dx, Type dy, Type dw, Type dh) noexcept {
00333             x += dx;
00334             y += dy;
00335             width += dw;
00336             height += dh;
00337         }
00338 
00346         BaseRect adjusted(Type dx, Type dy, Type dw, Type dh) const noexcept {
00347             BaseRect rect(*this);
00348             rect.adjust(dx, dy, dw, dh);
00349             return rect;
00350         }
00351 
00355         Type getArea() const noexcept {
00356             return width * height;
00357         }
00358 
00363         bool inside(const BaseRect& other) const noexcept {
00364             return topLeft() >= other.topLeft() && bottomRight() <= other.bottomRight();
00365         }
00366 
00372         bool isValid() const noexcept {
00373             return width > 0 && height > 0;
00374         }
00375     };
00376 
00382     template <typename Type>
00383     BaseRect<Type> centerScale(const BaseRect<Type>& in, float scaleFactor) noexcept {
00384         BaseRect<Type> out;
00385         out.x = in.x - 0.5 * (scaleFactor - 1) * in.width;
00386         out.y = in.y - 0.5 * (scaleFactor - 1) * in.height;
00387         out.width = in.width * scaleFactor;
00388         out.height = in.height * scaleFactor;
00389         return out;
00390     }
00391 
00392     using Rect = BaseRect<int>;
00393     using FloatRect = BaseRect<float>;
00394 } // namespace fsdk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines