Changeset 848


Ignore:
Timestamp:
01/31/19 03:45:08 (3 months ago)
Author:
Maciej Komosinski
Message:

2D operations with more granular types of arguments

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/common/2d.h

    r778 r848  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2019  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    99#include <math.h>
    1010
    11 //unifikacja starych GUIXY i Pt2D
     11//unification of old GUIXY and Pt2D
    1212template <typename T> class XY
    1313{
    1414public:
    15 T x,y;
    16 XY() {}
    17 XY(T _x,T _y):x(_x),y(_y) {}
    18 template <typename Q> XY(const Q& other):x(other.x),y(other.y) {}
    19 template <typename Q> const XY& operator=(const Q& other) {x=other.x; y=other.y; return *this;}
    20 template <typename Q> const XY operator()(const Q& other) {return XY(other.x,other.y);}
    21 XY operator+(const XY&p) const  {return XY(x+p.x,y+p.y);}
    22 XY operator-(const XY&p) const {return XY(x-p.x,y-p.y);}
    23 XY operator+=(const XY&p) {x+=p.x; y+=p.y; return *this;}
    24 XY operator-=(const XY&p) {x-=p.x; y-=p.y; return *this;}
    25 XY operator-() const {return XY(-x,-y);}
    26 XY operator*=(T q) {x*=q; y*=q; return *this;}
    27 XY operator/=(T q) {x/=q; y/=q; return *this;}
    28 XY operator/(T q) {return XY(x/q,y/q);}
    29 XY operator*(T q) const  {return XY(q*x,q*y);}
    30 void set(T _x,T _y) {x=_x; y=_y;}
    31 void add(T _x,T _y) {x+=_x; y+=_y;}
    32 void sub(T _x,T _y) {x-=_x; y-=_y;}
    33 bool operator==(const XY& p) const {return (fabs(double(x-p.x))<1e-20)&&(fabs(double(y-p.y))<1e-20);}
    34 T distanceTo(const XY& p) const {return sqrt(double((p.x-x)*(p.x-x)+(p.y-y)*(p.y-y)));}
    35 T magnitude() const {return sqrt(x*x+y*y);}
    36 T length() const {return sqrt(x*x+y*y);}
    37 T lengthSq() const { return x*x + y*y; }
    38 T dotProduct(const XY& v) const {return x*v.x + y*v.y;}
    39 T crossProduct(const XY& v) const {return x*v.y - y*v.x;}
    40 void normalize() { operator/=(length()); } // length becomes 1
    41 static XY average(const XY& v1,const XY& v2) { return XY((v1.x+v2.x)*0.5,(v1.y+v2.y)*0.5); }
    42 double getDirection() const {return atan2(y,x);}
    43 static XY interpolate(const XY& v1, const XY& v2,double t) {return v1+(v2-v1)*t;}
    44 XY toInt() const {return XY(int(x),int(y));}
    45 static const XY& zero() {static XY t(0,0); return t;}
    46 static const XY& one() {static XY t(1,1); return t;}
     15        T x, y;
     16        XY() {}
     17        XY(T _x, T _y) :x(_x), y(_y) {}
     18        template <typename Q> XY(const Q& other) : x(other.x), y(other.y) {}
     19        template <typename Q> const XY& operator=(const Q& other) { x = other.x; y = other.y; return *this; }
     20        template <typename Q> const XY operator()(const Q& other) { return XY(other.x, other.y); }
     21        XY operator+(const XY&p) const { return XY(x + p.x, y + p.y); }
     22        XY operator-(const XY&p) const { return XY(x - p.x, y - p.y); }
     23        XY operator+=(const XY&p) { x += p.x; y += p.y; return *this; }
     24        XY operator-=(const XY&p) { x -= p.x; y -= p.y; return *this; }
     25        XY operator-() const { return XY(-x, -y); }
     26        // allows float operations on ints
     27        template <typename Q> XY operator*=(Q q) { x *= q; y *= q; return *this; }
     28        template <typename Q> XY operator/=(Q q) { x /= q; y /= q; return *this; }
     29        template <typename Q> XY operator/(Q q) { return XY(x / q, y / q); }
     30        template <typename Q> XY operator*(Q q) const { return XY(q*x, q*y); }
     31        void set(T _x, T _y) { x = _x; y = _y; }
     32        void add(T _x, T _y) { x += _x; y += _y; }
     33        void sub(T _x, T _y) { x -= _x; y -= _y; }
     34        bool operator==(const XY& p) const { return (fabs(double(x - p.x)) < 1e-20) && (fabs(double(y - p.y)) < 1e-20); }
     35        bool operator!=(const XY& p) const { return !operator==(p); }
     36        T distanceTo(const XY& p) const { return sqrt(double((p.x - x)*(p.x - x) + (p.y - y)*(p.y - y))); }
     37        T magnitude() const { return sqrt(x*x + y * y); }
     38        T length() const { return sqrt(x*x + y * y); }
     39        T lengthSq() const { return x * x + y * y; }
     40        T dotProduct(const XY& v) const { return x * v.x + y * v.y; }
     41        T crossProduct(const XY& v) const { return x * v.y - y * v.x; }
     42        void normalize() { operator/=(length()); } // length becomes 1
     43        static XY average(const XY& v1, const XY& v2) { return XY((v1.x + v2.x)*0.5, (v1.y + v2.y)*0.5); }
     44        double getDirection() const { return atan2(y, x); }
     45        static XY interpolate(const XY& v1, const XY& v2, double t) { return v1 + (v2 - v1)*t; }
     46        XY toInt() const { return XY(int(x), int(y)); }
     47        XY transpose() const { return XY(y, x); }
     48        static const XY& zero() { static XY t(0, 0); return t; }
     49        static const XY& one() { static XY t(1, 1); return t; }
    4750};
    4851
    49 template <typename T> XY<T> xymin(const XY<T>& a, const XY<T>& b) {return XY<T>(min(a.x,b.x),min(a.y,b.y));}
    50 template <typename T> XY<T> xymax(const XY<T>& a, const XY<T>& b) {return XY<T>(max(a.x,b.x),max(a.y,b.y));}
     52//specialized: int equality not using fabs()
     53template<> inline bool XY<int>::operator==(const XY<int>& p) const { return (x == p.x) && (y == p.y); }
     54
     55template <typename T> XY<T> xymin(const XY<T>& a, const XY<T>& b) { return XY<T>(min(a.x, b.x), min(a.y, b.y)); }
     56template <typename T> XY<T> xymax(const XY<T>& a, const XY<T>& b) { return XY<T>(max(a.x, b.x), max(a.y, b.y)); }
    5157
    5258template <typename T>
    5359class XYMargin
    5460{
    55   public:
    56         XYMargin(T x=0):left(x),top(x),right(x),bottom(x) {}
    57         XYMargin(T l,T t,T r,T b):left(l),top(t),right(r),bottom(b) {}
    58         T left,top,right,bottom;
    59         void operator=(T x) {left=top=right=bottom=x;}
    60         XYMargin operator-() const {return XYMargin(-left,-top,-right,-bottom);}
    61         void operator=(const XYMargin<T> &other) {left=other.left; top=other.top; right=other.right; bottom=other.bottom;}
    62         T horizontal() const {return left+right;}
    63         T vertical() const {return top+bottom;}
    64         bool operator==(const XYMargin &other) const {return left==other.left && top==other.top && right==other.right && bottom==other.bottom;}
    65         XYMargin normalized() const {return XYMargin(max(left,T(0)),max(top,T(0)),max(right,T(0)),max(bottom,T(0)));}
     61public:
     62        XYMargin(T x = 0) :left(x), top(x), right(x), bottom(x) {}
     63        XYMargin(T l, T t, T r, T b) :left(l), top(t), right(r), bottom(b) {}
     64        T left, top, right, bottom;
     65        void operator=(T x) { left = top = right = bottom = x; }
     66        XYMargin operator-() const { return XYMargin(-left, -top, -right, -bottom); }
     67        void operator=(const XYMargin<T> &other) { left = other.left; top = other.top; right = other.right; bottom = other.bottom; }
     68        T horizontal() const { return left + right; }
     69        T vertical() const { return top + bottom; }
     70        bool operator==(const XYMargin &other) const { return left == other.left && top == other.top && right == other.right && bottom == other.bottom; }
     71        XYMargin normalized() const { return XYMargin(max(left, T(0)), max(top, T(0)), max(right, T(0)), max(bottom, T(0))); }
    6672};
    6773
     
    7076{
    7177public:
    72 XY<T> p,size;
    73 XYRect() {}
    74 XYRect(const XY<T>& p1,const XY<T>& s):p(p1),size(s) {}
    75 template <typename Q> XYRect(const Q& other):p(other.p),size(other.size) {}
    76 XYRect(T _x,T _y,T _w,T _h):p(_x,_y),size(_w,_h) {}
    77 static XYRect<T> centeredAt(const XY<T>& p,XY<T> s) {return XYRect<T>(p-s*0.5,s);}
     78        XY<T> p, size;
     79        XYRect() {}
     80        XYRect(const XY<T>& p1, const XY<T>& s) :p(p1), size(s) {}
     81        template <typename Q> XYRect(const Q& other) : p(other.p), size(other.size) {}
     82        XYRect(T _x, T _y, T _w, T _h) :p(_x, _y), size(_w, _h) {}
     83        static XYRect<T> centeredAt(const XY<T>& p, XY<T> s) { return XYRect<T>(p - s * 0.5, s); }
    7884
    79 bool isEmpty() const {return (size.x<0)||(size.y<0);}
    80 XYRect toInt() const {return XYRect(int(p.x),int(p.y),int(p.x+size.x)-int(p.x),int(p.y+size.y)-int(p.y));}
    81 bool operator==(const XYRect& r) const {return (p==r.p) && (size==r.size);}
    82 template <typename Q> const XYRect& operator=(const Q& other) {p=other.p; size=other.size; return *this;}
     85        bool isEmpty() const { return (size.x < 0) || (size.y < 0); }
     86        XYRect toInt() const { return XYRect(int(p.x), int(p.y), int(p.x + size.x) - int(p.x), int(p.y + size.y) - int(p.y)); }
     87        bool operator==(const XYRect& r) const { return (p == r.p) && (size == r.size); }
     88        template <typename Q> const XYRect& operator=(const Q& other) { p = other.p; size = other.size; return *this; }
    8389
    84 bool intersects(const XYRect& r) const
    85 {
    86 if (r.p.x >= (p.x+size.x)) return false;
    87 if (r.p.y >= (p.y+size.y)) return false;
    88 if ((r.p.x+r.size.x) <= p.x) return false;
    89 if ((r.p.y+r.size.y) <= p.y) return false;
    90 return true;
    91 }
     90        bool intersects(const XYRect& r) const
     91        {
     92                if (r.p.x >= (p.x + size.x)) return false;
     93                if (r.p.y >= (p.y + size.y)) return false;
     94                if ((r.p.x + r.size.x) <= p.x) return false;
     95                if ((r.p.y + r.size.y) <= p.y) return false;
     96                return true;
     97        }
    9298
    93 bool contains(const XY<T>& n) const
    94 {
    95 if (n.x<p.x) return false;
    96 if (n.x>(p.x+size.x)) return false;
    97 if (n.y<p.y) return false;
    98 if (n.y>(p.y+size.y)) return false;
    99 return true;
    100 }
     99        bool contains(const XY<T>& n) const
     100        {
     101                if (n.x < p.x) return false;
     102                if (n.x > (p.x + size.x)) return false;
     103                if (n.y < p.y) return false;
     104                if (n.y > (p.y + size.y)) return false;
     105                return true;
     106        }
    101107
    102 void add(const XY<T>& n)
    103 {
    104 if (n.x<p.x) {size.x+=p.x-n.x; p.x=n.x;}
    105 else if (n.x>(p.x+size.x)) size.x=n.x-p.x;
    106 if (n.y<p.y) {size.y+=p.y-n.y; p.y=n.y;}
    107 else if (n.y>(p.y+size.y)) size.y=n.y-p.y;
    108 }
     108        void add(const XY<T>& n)
     109        {
     110                if (n.x < p.x) { size.x += p.x - n.x; p.x = n.x; }
     111                else if (n.x > (p.x + size.x)) size.x = n.x - p.x;
     112                if (n.y < p.y) { size.y += p.y - n.y; p.y = n.y; }
     113                else if (n.y > (p.y + size.y)) size.y = n.y - p.y;
     114        }
    109115
    110 XYRect extendBy(const XY<T>& border_size) const
    111 {
    112 return XYRect(p-border_size,size+border_size*2);
    113 }
     116        XYRect extendBy(const XY<T>& border_size) const
     117        {
     118                return XYRect(p - border_size, size + border_size * 2);
     119        }
    114120
    115 XYRect shrinkBy(const XY<T>& border_size) const
    116 {
    117 return XYRect(p+border_size,size-border_size*2);
    118 }
     121        XYRect shrinkBy(const XY<T>& border_size) const
     122        {
     123                return XYRect(p + border_size, size - border_size * 2);
     124        }
    119125
    120 XYRect extendBy(const XYMargin<T>& m) const
    121 {
    122 return XYRect(p.x-m.left,p.y-m.top,size.x+m.horizontal(),size.y+m.vertical());
    123 }
     126        XYRect extendBy(const XYMargin<T>& m) const
     127        {
     128                return XYRect(p.x - m.left, p.y - m.top, size.x + m.horizontal(), size.y + m.vertical());
     129        }
    124130
    125 XYRect shrinkBy(const XYMargin<T>& m) const
    126 {
    127 return XYRect(p.x+m.left,p.y+m.top,size.x-m.horizontal(),size.y-m.vertical());
    128 }
     131        XYRect shrinkBy(const XYMargin<T>& m) const
     132        {
     133                return XYRect(p.x + m.left, p.y + m.top, size.x - m.horizontal(), size.y - m.vertical());
     134        }
    129135
    130 XYMargin<T> marginTowards(const XYRect &r) const
    131 {
    132 return XYMargin<T>(r.p.x-p.x, r.p.y-p.y,
    133                 (p.x+size.x)-(r.p.x+r.size.x), (p.y+size.y)-(r.p.y+r.size.y));
    134 }
     136        XYMargin<T> marginTowards(const XYRect &r) const
     137        {
     138                return XYMargin<T>(r.p.x - p.x, r.p.y - p.y,
     139                        (p.x + size.x) - (r.p.x + r.size.x), (p.y + size.y) - (r.p.y + r.size.y));
     140        }
    135141
    136 XYRect intersection(const XYRect& r) const
    137 {
    138 XYRect i;
    139 XY<T> p2=p+size;
    140 XY<T> rp2=r.p+r.size;
    141 i.p.x=max(p.x,r.p.x);
    142 i.p.y=max(p.y,r.p.y);
    143 i.size.x=min(p2.x,rp2.x)-i.p.x;
    144 i.size.y=min(p2.y,rp2.y)-i.p.y;
    145 return i;
    146 }
     142        XYRect intersection(const XYRect& r) const
     143        {
     144                XYRect i;
     145                XY<T> p2 = p + size;
     146                XY<T> rp2 = r.p + r.size;
     147                i.p.x = max(p.x, r.p.x);
     148                i.p.y = max(p.y, r.p.y);
     149                i.size.x = min(p2.x, rp2.x) - i.p.x;
     150                i.size.y = min(p2.y, rp2.y) - i.p.y;
     151                return i;
     152        }
    147153
    148 XYRect translation(const XY<T>& t) const
    149 {
    150 return XYRect(p+t,size);
    151 }
     154        XYRect translation(const XY<T>& t) const
     155        {
     156                return XYRect(p + t, size);
     157        }
    152158
    153 T distanceTo(const XY<T>& n) const
    154 {
    155 XY<T> tp=n;
    156 if (n.x<p.x) tp.x=p.x; else if (n.x>=(p.x+size.x)) tp.x=p.x+size.x;
    157 if (n.y<p.y) tp.y=p.y; else if (n.y>=(p.y+size.y)) tp.y=p.y+size.y;
    158  return tp.distanceTo(n);
    159 }
     159        T distanceTo(const XY<T>& n) const
     160        {
     161                XY<T> tp = n;
     162                if (n.x < p.x) tp.x = p.x; else if (n.x >= (p.x + size.x)) tp.x = p.x + size.x;
     163                if (n.y < p.y) tp.y = p.y; else if (n.y >= (p.y + size.y)) tp.y = p.y + size.y;
     164                return tp.distanceTo(n);
     165        }
    160166
    161 static const XYRect& zero() {static XYRect t(0,0,0,0); return t;}
    162 static const XYRect& one() {static XYRect t(0,0,1,1); return t;}
     167        static const XYRect& zero() { static XYRect t(0, 0, 0, 0); return t; }
     168        static const XYRect& one() { static XYRect t(0, 0, 1, 1); return t; }
    163169};
    164170
Note: See TracChangeset for help on using the changeset viewer.