source: cpp/common/2d.h @ 794

Last change on this file since 794 was 778, checked in by Maciej Komosinski, 6 years ago

A few useful functions added for 2D operations

  • Property svn:eol-style set to native
File size: 5.5 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#ifndef _2D_H_
6#define _2D_H_
7
8#include "nonstd_stl.h"
9#include <math.h>
10
11//unifikacja starych GUIXY i Pt2D
12template <typename T> class XY
13{
14public:
15T x,y;
16XY() {}
17XY(T _x,T _y):x(_x),y(_y) {}
18template <typename Q> XY(const Q& other):x(other.x),y(other.y) {}
19template <typename Q> const XY& operator=(const Q& other) {x=other.x; y=other.y; return *this;}
20template <typename Q> const XY operator()(const Q& other) {return XY(other.x,other.y);}
21XY operator+(const XY&p) const  {return XY(x+p.x,y+p.y);}
22XY operator-(const XY&p) const {return XY(x-p.x,y-p.y);}
23XY operator+=(const XY&p) {x+=p.x; y+=p.y; return *this;}
24XY operator-=(const XY&p) {x-=p.x; y-=p.y; return *this;}
25XY operator-() const {return XY(-x,-y);}
26XY operator*=(T q) {x*=q; y*=q; return *this;}
27XY operator/=(T q) {x/=q; y/=q; return *this;}
28XY operator/(T q) {return XY(x/q,y/q);}
29XY operator*(T q) const  {return XY(q*x,q*y);}
30void set(T _x,T _y) {x=_x; y=_y;}
31void add(T _x,T _y) {x+=_x; y+=_y;}
32void sub(T _x,T _y) {x-=_x; y-=_y;}
33bool operator==(const XY& p) const {return (fabs(double(x-p.x))<1e-20)&&(fabs(double(y-p.y))<1e-20);}
34T distanceTo(const XY& p) const {return sqrt(double((p.x-x)*(p.x-x)+(p.y-y)*(p.y-y)));}
35T magnitude() const {return sqrt(x*x+y*y);}
36T length() const {return sqrt(x*x+y*y);}
37T lengthSq() const { return x*x + y*y; }
38T dotProduct(const XY& v) const {return x*v.x + y*v.y;}
39T crossProduct(const XY& v) const {return x*v.y - y*v.x;}
40void normalize() { operator/=(length()); } // length becomes 1
41static XY average(const XY& v1,const XY& v2) { return XY((v1.x+v2.x)*0.5,(v1.y+v2.y)*0.5); }
42double getDirection() const {return atan2(y,x);}
43static XY interpolate(const XY& v1, const XY& v2,double t) {return v1+(v2-v1)*t;}
44XY toInt() const {return XY(int(x),int(y));}
45static const XY& zero() {static XY t(0,0); return t;}
46static const XY& one() {static XY t(1,1); return t;}
47};
48
49template <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));}
50template <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));}
51
52template <typename T>
53class XYMargin
54{
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)));}
66};
67
68template <typename T>
69class XYRect
70{
71public:
72XY<T> p,size;
73XYRect() {}
74XYRect(const XY<T>& p1,const XY<T>& s):p(p1),size(s) {}
75template <typename Q> XYRect(const Q& other):p(other.p),size(other.size) {}
76XYRect(T _x,T _y,T _w,T _h):p(_x,_y),size(_w,_h) {}
77static XYRect<T> centeredAt(const XY<T>& p,XY<T> s) {return XYRect<T>(p-s*0.5,s);}
78
79bool isEmpty() const {return (size.x<0)||(size.y<0);}
80XYRect 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));}
81bool operator==(const XYRect& r) const {return (p==r.p) && (size==r.size);}
82template <typename Q> const XYRect& operator=(const Q& other) {p=other.p; size=other.size; return *this;}
83
84bool intersects(const XYRect& r) const
85{
86if (r.p.x >= (p.x+size.x)) return false;
87if (r.p.y >= (p.y+size.y)) return false;
88if ((r.p.x+r.size.x) <= p.x) return false;
89if ((r.p.y+r.size.y) <= p.y) return false;
90return true;
91}
92
93bool contains(const XY<T>& n) const
94{
95if (n.x<p.x) return false;
96if (n.x>(p.x+size.x)) return false;
97if (n.y<p.y) return false;
98if (n.y>(p.y+size.y)) return false;
99return true;
100}
101
102void add(const XY<T>& n)
103{
104if (n.x<p.x) {size.x+=p.x-n.x; p.x=n.x;}
105else if (n.x>(p.x+size.x)) size.x=n.x-p.x;
106if (n.y<p.y) {size.y+=p.y-n.y; p.y=n.y;}
107else if (n.y>(p.y+size.y)) size.y=n.y-p.y;
108}
109
110XYRect extendBy(const XY<T>& border_size) const
111{
112return XYRect(p-border_size,size+border_size*2);
113}
114
115XYRect shrinkBy(const XY<T>& border_size) const
116{
117return XYRect(p+border_size,size-border_size*2);
118}
119
120XYRect extendBy(const XYMargin<T>& m) const
121{
122return XYRect(p.x-m.left,p.y-m.top,size.x+m.horizontal(),size.y+m.vertical());
123}
124
125XYRect shrinkBy(const XYMargin<T>& m) const
126{
127return XYRect(p.x+m.left,p.y+m.top,size.x-m.horizontal(),size.y-m.vertical());
128}
129
130XYMargin<T> marginTowards(const XYRect &r) const
131{
132return 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}
135
136XYRect intersection(const XYRect& r) const
137{
138XYRect i;
139XY<T> p2=p+size;
140XY<T> rp2=r.p+r.size;
141i.p.x=max(p.x,r.p.x);
142i.p.y=max(p.y,r.p.y);
143i.size.x=min(p2.x,rp2.x)-i.p.x;
144i.size.y=min(p2.y,rp2.y)-i.p.y;
145return i;
146}
147
148XYRect translation(const XY<T>& t) const
149{
150return XYRect(p+t,size);
151}
152
153T distanceTo(const XY<T>& n) const
154{
155XY<T> tp=n;
156if (n.x<p.x) tp.x=p.x; else if (n.x>=(p.x+size.x)) tp.x=p.x+size.x;
157if (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}
160
161static const XYRect& zero() {static XYRect t(0,0,0,0); return t;}
162static const XYRect& one() {static XYRect t(0,0,1,1); return t;}
163};
164
165typedef XY<int> IntXY;
166typedef XYRect<int> IntRect;
167
168#endif
Note: See TracBrowser for help on using the repository browser.