Empirical
Point2D.h
Go to the documentation of this file.
1 // This file is part of Empirical, https://github.com/devosoft/Empirical
2 // Copyright (C) Michigan State University, 2016-2017.
3 // Released under the MIT Software license; see doc/LICENSE
4 //
5 //
6 // A simple class to track value pairs of any kind, optimized for points in 2D Space
7 //
8 // Note: For maximal efficiency, prefer SquareMagnitude() and SquareDistance()
9 // over Magnitude() and Distance() as the latter require a square-root.
10 
11 
12 #ifndef EMP_POINT_2D_H
13 #define EMP_POINT_2D_H
14 
15 #include <cmath>
16 #include <iostream>
17 
18 namespace emp {
19 
20  template <typename TYPE=double> class Point2D {
21  private:
22  TYPE x;
23  TYPE y;
24 
25  public:
26  constexpr Point2D() : x(0.0), y(0.0) { ; } // Default = 0,0
27  constexpr Point2D(const Point2D & _in) : x(_in.x), y(_in.y) { ; } // Copy constructor
28  constexpr Point2D(TYPE _x, TYPE _y) : x(_x), y(_y) { ; } // Two ints -> x and y
29  constexpr Point2D(const Point2D & _in, TYPE new_magnitude)
30  : x(_in.x * ((double) new_magnitude) / ((double) _in.Magnitude()))
31  , y(_in.y * ((double) new_magnitude) / ((double) _in.Magnitude()))
32  { ; }
33  // ~Point2D() { ; }
34 
35  const Point2D & operator=(const Point2D & _in) { x = _in.x; y = _in.y; return *this; }
36  constexpr bool operator==(const Point2D & _in) const { return (x == _in.x) && (y == _in.y); }
37  constexpr bool operator!=(const Point2D & _in) const { return (x != _in.x) || (y != _in.y); }
38 
39  constexpr inline TYPE GetX() const { return x; }
40  constexpr inline TYPE GetY() const { return y; }
41  inline Point2D & SetX(TYPE in_x) { x = in_x; return *this; }
42  inline Point2D & SetY(TYPE in_y) { y = in_y; return *this; }
43  Point2D & Set(TYPE _x, TYPE _y) { x=_x; y=_y; return *this; }
44 
45  constexpr double SquareMagnitude() const { return x*x + y*y; }
46  constexpr double Magnitude() const { return sqrt( x*x + y*y ); }
47  constexpr bool AtOrigin() const { return x == 0 && y == 0; }
48  constexpr bool NonZero() const { return x != 0 || y != 0; }
49 
50  // Determine a new point, but don't change this one
51  constexpr Point2D GetMidpoint(const Point2D & p2) const { return Point2D((x+p2.x)/2, (y+p2.y)/2); }
52  constexpr Point2D GetRot90() const { return Point2D(y, -x); }
53  constexpr Point2D GetRot180() const { return Point2D(-x, -y); }
54  constexpr Point2D GetRot270() const { return Point2D(-y, x); }
55  constexpr Point2D GetOffset(TYPE off_x, TYPE off_y) const { return Point2D(x+off_x, y+off_y); }
56 
57  constexpr Point2D operator+(const Point2D & _in) const { return Point2D(x + _in.x , y + _in.y); }
58  constexpr Point2D operator-(const Point2D & _in) const { return Point2D(x - _in.x , y - _in.y); }
59  constexpr Point2D operator*(double mult) const { return Point2D(((double) x) * mult, ((double) y) * mult); }
60  constexpr Point2D operator/(double div) const { return Point2D(((double) x) / div, ((double) y) / div); }
61  constexpr Point2D operator*(int mult) const { return Point2D(x * mult, y * mult); }
62  constexpr Point2D operator/(int div) const { return Point2D(x / div, y / div); }
63  constexpr Point2D operator-() const { return Point2D(-x, -y); } // Unary minus
64 
65  constexpr Point2D Abs() const { return Point2D(std::abs(x), std::abs(y)); } // Absolute value
66 
67  // Modify this point.
68  Point2D & Translate(TYPE shift_x, TYPE shift_y) { x += shift_x; y += shift_y; return *this; }
69  Point2D & TranslateX(TYPE shift) { x += shift; return *this; }
70  Point2D & TranslateY(TYPE shift) { y += shift; return *this; }
71  Point2D & Scale(double scale) { x *= scale; y *= scale; return *this; }
72  Point2D & Scale(double scale_x, double scale_y) { x *= scale_x; y *= scale_y; return *this; }
73  Point2D & ToOrigin() { x = 0; y = 0; return *this; }
74  Point2D & NegateX() { x = -x; return *this; }
75  Point2D & NegateY() { y = -y; return *this; }
76 
77  Point2D & operator+=(const Point2D & _in) { x += _in.x; y += _in.y; return *this; }
78  Point2D & operator-=(const Point2D & _in) { x -= _in.x; y -= _in.y; return *this; }
79  Point2D & operator*=(double mult) { x *= mult; y *= mult; return *this; }
80  Point2D & operator/=(double val) { if (val != 0.0) { x /= val; y /= val; }; return *this; }
81  Point2D & operator*=(int mult) { x *= mult; y *= mult; return *this; }
82  Point2D & operator/=(int val) { if (val != 0.0) { x /= val; y /= val; }; return *this; }
83 
84  Point2D & Rot90() { return Set(y, -x); }
85  Point2D & Rot180() { return Set(-x, -y); }
86  Point2D & Rot270() { return Set(-y, x); }
87 
88  // Square-roots are slow to calculate; if we're just doing comparisons, square-distance
89  // is usualy going to be sufficient.
90  TYPE SquareDistance(const Point2D & _in) const {
91  const TYPE x_dist = x - _in.x;
92  const TYPE y_dist = y - _in.y;
93  return x_dist*x_dist + y_dist*y_dist;
94  }
95 
96  TYPE Distance(const Point2D & _in) const { return sqrt( SquareDistance(_in) ); }
97  };
98 
99  using Point = Point2D<>;
100 
101 }
102 
103 // Overload ostream to work with points.
104 template <typename TYPE> std::ostream & operator<<(std::ostream & os,
105  const emp::Point2D<TYPE> & point) {
106  return os << "(" << point.GetX() << "," << point.GetY() << ")";
107 }
108 
109 
110 #endif
constexpr Point2D operator-(const Point2D &_in) const
Definition: Point2D.h:58
constexpr bool NonZero() const
Definition: Point2D.h:48
constexpr Point2D GetRot90() const
Definition: Point2D.h:52
Point2D & operator+=(const Point2D &_in)
Definition: Point2D.h:77
constexpr TYPE GetX() const
Definition: Point2D.h:39
Point2D & operator-=(const Point2D &_in)
Definition: Point2D.h:78
constexpr Point2D GetOffset(TYPE off_x, TYPE off_y) const
Definition: Point2D.h:55
Point2D & NegateX()
Definition: Point2D.h:74
constexpr Point2D(const Point2D &_in)
Definition: Point2D.h:27
constexpr Point2D operator*(double mult) const
Definition: Point2D.h:59
constexpr double SquareMagnitude() const
Definition: Point2D.h:45
constexpr bool AtOrigin() const
Definition: Point2D.h:47
constexpr Point2D GetRot270() const
Definition: Point2D.h:54
Point2D & TranslateX(TYPE shift)
Definition: Point2D.h:69
Point2D & operator*=(double mult)
Definition: Point2D.h:79
constexpr Point2D(const Point2D &_in, TYPE new_magnitude)
Definition: Point2D.h:29
TYPE Distance(const Point2D &_in) const
Definition: Point2D.h:96
constexpr bool operator==(const Point2D &_in) const
Definition: Point2D.h:36
constexpr Point2D()
Definition: Point2D.h:26
Point2D & Scale(double scale)
Definition: Point2D.h:71
Point2D & Set(TYPE _x, TYPE _y)
Definition: Point2D.h:43
TYPE SquareDistance(const Point2D &_in) const
Definition: Point2D.h:90
constexpr Point2D GetMidpoint(const Point2D &p2) const
Definition: Point2D.h:51
std::ostream & operator<<(std::ostream &out, const emp::Ptr< T > &ptr)
Definition: Ptr.h:800
constexpr Point2D operator/(int div) const
Definition: Point2D.h:62
const Point2D & operator=(const Point2D &_in)
Definition: Point2D.h:35
Point2D & operator*=(int mult)
Definition: Point2D.h:81
Point2D & ToOrigin()
Definition: Point2D.h:73
constexpr Point2D Abs() const
Definition: Point2D.h:65
constexpr Point2D operator/(double div) const
Definition: Point2D.h:60
constexpr Point2D GetRot180() const
Definition: Point2D.h:53
Definition: Point2D.h:20
constexpr bool operator!=(const Point2D &_in) const
Definition: Point2D.h:37
Point2D & Rot180()
Definition: Point2D.h:85
If we are in emscripten, make sure to include the header.
Definition: array.h:37
constexpr Point2D operator+(const Point2D &_in) const
Definition: Point2D.h:57
constexpr Point2D operator-() const
Definition: Point2D.h:63
Point2D & Rot270()
Definition: Point2D.h:86
Point2D & TranslateY(TYPE shift)
Definition: Point2D.h:70
Point2D & SetY(TYPE in_y)
Definition: Point2D.h:42
Point2D & operator/=(int val)
Definition: Point2D.h:82
constexpr Point2D(TYPE _x, TYPE _y)
Definition: Point2D.h:28
constexpr Point2D operator*(int mult) const
Definition: Point2D.h:61
Point2D & NegateY()
Definition: Point2D.h:75
constexpr TYPE GetY() const
Definition: Point2D.h:40
Point2D & Scale(double scale_x, double scale_y)
Definition: Point2D.h:72
Point2D & Translate(TYPE shift_x, TYPE shift_y)
Definition: Point2D.h:68
Point2D & operator/=(double val)
Definition: Point2D.h:80
Point2D & Rot90()
Definition: Point2D.h:84
constexpr double Magnitude() const
Definition: Point2D.h:46
Point2D & SetX(TYPE in_x)
Definition: Point2D.h:41