// This file is a part of Framsticks SDK. http://www.framsticks.com/ // Copyright (C) 1999-2015 Maciej Komosinski and Szymon Ulatowski. // See LICENSE.txt for details. #ifndef _2D_H_ #define _2D_H_ #include "nonstd_stl.h" #include //unifikacja starych GUIXY i Pt2D template class XY { public: T x,y; XY() {} XY(T _x,T _y):x(_x),y(_y) {} template XY(const Q& other):x(other.x),y(other.y) {} template const XY& operator=(const Q& other) {x=other.x; y=other.y; return *this;} template const XY operator()(const Q& other) {return XY(other.x,other.y);} XY operator+(const XY&p) const {return XY(x+p.x,y+p.y);} XY operator-(const XY&p) const {return XY(x-p.x,y-p.y);} XY operator+=(const XY&p) {x+=p.x; y+=p.y; return *this;} XY operator-=(const XY&p) {x-=p.x; y-=p.y; return *this;} XY operator-() const {return XY(-x,-y);} XY operator*=(T q) {x*=q; y*=q; return *this;} XY operator/=(T q) {x/=q; y/=q; return *this;} XY operator/(T q) {return XY(x/q,y/q);} XY operator*(T q) const {return XY(q*x,q*y);} void set(T _x,T _y) {x=_x; y=_y;} void add(T _x,T _y) {x+=_x; y+=_y;} void sub(T _x,T _y) {x-=_x; y-=_y;} bool operator==(const XY& p) const {return (fabs(double(x-p.x))<1e-20)&&(fabs(double(y-p.y))<1e-20);} T distanceTo(const XY& p) const {return sqrt(double((p.x-x)*(p.x-x)+(p.y-y)*(p.y-y)));} T magnitude() const {return sqrt(x*x+y*y);} T length() const {return sqrt(x*x+y*y);} T lengthSq() const { return x*x + y*y; } T dotProduct(const XY& v) const {return x*v.x + y*v.y;} T crossProduct(const XY& v) const {return x*v.y - y*v.x;} void normalize() { operator/=(length()); } // length becomes 1 static XY average(const XY& v1,const XY& v2) { return XY((v1.x+v2.x)*0.5,(v1.y+v2.y)*0.5); } double getDirection() const {return atan2(y,x);} static XY interpolate(const XY& v1, const XY& v2,double t) {return v1+(v2-v1)*t;} XY toInt() const {return XY(int(x),int(y));} static const XY& zero() {static XY t(0,0); return t;} static const XY& one() {static XY t(1,1); return t;} }; template XY xymin(const XY& a, const XY& b) {return XY(min(a.x,b.x),min(a.y,b.y));} template XY xymax(const XY& a, const XY& b) {return XY(max(a.x,b.x),max(a.y,b.y));} template class XYMargin { public: XYMargin(T x=0):left(x),top(x),right(x),bottom(x) {} XYMargin(T l,T t,T r,T b):left(l),top(t),right(r),bottom(b) {} T left,top,right,bottom; void operator=(T x) {left=top=right=bottom=x;} XYMargin operator-() const {return XYMargin(-left,-top,-right,-bottom);} void operator=(const XYMargin &other) {left=other.left; top=other.top; right=other.right; bottom=other.bottom;} T horizontal() const {return left+right;} T vertical() const {return top+bottom;} }; template class XYRect { public: XY p,size; XYRect() {} XYRect(const XY& p1,const XY& s):p(p1),size(s) {} template XYRect(const Q& other):p(other.p),size(other.size) {} XYRect(T _x,T _y,T _w,T _h):p(_x,_y),size(_w,_h) {} static XYRect centeredAt(const XY& p,XY s) {return XYRect(p-s*0.5,s);} bool isEmpty() const {return (size.x<0)||(size.y<0);} 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));} bool operator==(const XYRect& r) const {return (p==r.p) && (size==r.size);} template const XYRect& operator=(const Q& other) {p=other.p; size=other.size; return *this;} bool intersects(const XYRect& r) const { if (r.p.x >= (p.x+size.x)) return false; if (r.p.y >= (p.y+size.y)) return false; if ((r.p.x+r.size.x) <= p.x) return false; if ((r.p.y+r.size.y) <= p.y) return false; return true; } bool contains(const XY& n) const { if (n.x(p.x+size.x)) return false; if (n.y(p.y+size.y)) return false; return true; } void add(const XY& n) { if (n.x(p.x+size.x)) size.x=n.x-p.x; if (n.y(p.y+size.y)) size.y=n.y-p.y; } XYRect extendBy(const XY& border_size) const { return XYRect(p-border_size,size+border_size*2); } XYRect shrinkBy(const XY& border_size) const { return XYRect(p+border_size,size-border_size*2); } XYRect extendBy(const XYMargin& m) const { return XYRect(p.x-m.left,p.y-m.top,size.x+m.horizontal(),size.y+m.vertical()); } XYRect shrinkBy(const XYMargin& m) const { return XYRect(p.x+m.left,p.y+m.top,size.x-m.horizontal(),size.y-m.vertical()); } XYMargin marginTowards(const XYRect &r) const { return XYMargin(r.p.x, r.p.y, (p.x+size.x)-(r.p.x+r.size.x), (p.y+size.y)-(r.p.y+r.size.y)); } XYRect intersection(const XYRect& r) const { XYRect i; XY p2=p+size; XY rp2=r.p+r.size; i.p.x=max(p.x,r.p.x); i.p.y=max(p.y,r.p.y); i.size.x=min(p2.x,rp2.x)-i.p.x; i.size.y=min(p2.y,rp2.y)-i.p.y; return i; } XYRect translation(const XY& t) const { return XYRect(p+t,size); } T distanceTo(const XY& n) const { XY tp=n; if (n.x=(p.x+size.x)) tp.x=p.x+size.x; if (n.y=(p.y+size.y)) tp.y=p.y+size.y; return tp.distanceTo(n); } static const XYRect& zero() {static XYRect t(0,0,0,0); return t;} static const XYRect& one() {static XYRect t(0,0,1,1); return t;} }; typedef XY IntXY; typedef XYRect IntRect; #endif