summaryrefslogtreecommitdiffstats
path: root/kig/misc/coordinate.h
blob: a56edb761c0f40d008b2ce8970d0cc5a01f19669 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/**
 This file is part of Kig, a KDE program for Interactive Geometry...
 Copyright (C) 2002  Dominique Devriese <[email protected]>

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 USA
**/


#ifndef KIG_MISC_COORDINATE_H
#define KIG_MISC_COORDINATE_H

class QPoint;
class kdbgstream;

/**
 * The Coordinate class is the basic class representing a 2D location
 * by its x and y components.  It has all relevant arithmetic
 * operators properly defined, and should be straightforward to use..
 */
class Coordinate
{
public:
  static Coordinate fromQPoint( const QPoint& p );

  /** Constructor.  Construct a new Coordinate, with a given x and y
   * value.
   */
  Coordinate( double x, double y );
  /** Copy Constructor.  Construct a new Coordinate, and give it the
   *  same value as p.
   */
  Coordinate( const Coordinate& p );
  /**
   * \ifnot creating-python-scripting-doc
   * \brief Default Constructor
   *
   * Constructs a new Coordinate, with x and y initialized to 0.
   * \endif
   */
  Coordinate();
  ~Coordinate() {}

  /** Create an invalid Coordinate.  This is a special value of a
   * Coordinate that signals that something went wrong..
   *
   * \see Coordinate::valid
   *
   * \internal We represent an invalid coordinate by setting x or y to
   * positive or negative infinity.  This is handy, since it doesn't
   * require us to adapt most of the functions, it doesn't need extra
   * space, and most of the times that we should get an invalid coord,
   * we get one automatically..
   */
  static Coordinate invalidCoord();
  /** Return whether this is a valid Coordinate.
   * \see Coordinate::invalidCoord
   */
  bool valid() const;

  /** Distance to another Coordinate.
   */
  double distance ( const Coordinate& p ) const;
  /** Length.  Returns the length or norm of this coordinate.
   * I.e. return the distance from this Coordinate to the origin.
   * \see squareLength
   */
  double length () const;
  /** Square length.  Equivalent to the square of \ref length, but a
   * bit more efficient because no square root has to be calculated.
   * \see length
   */
  inline double squareLength() const;
  /** Inverse.  Returns the inverse of this Coordinate.
   */
  const Coordinate operator- () const;
  /** Orthogonal.  Returns a vector which is orthogonal on this vector.
   * This relation always holds:
   * <pre>
   * Coordinate a = ...;
   * assert( a*a.orthogonal() ) == 0;
   * </pre>
   */
  const Coordinate orthogonal() const;
  /** Round. Returns this coordinate, rounded to the nearest integral
   * values.
   */
  const Coordinate round() const;
  /** Normalize.  This sets the length to length, while keeping the
   * x/y ratio untouched...
   */
  const Coordinate normalize( double length = 1 ) const;
  QPoint toQPoint() const;

  Coordinate& operator= ( const Coordinate& c );
  /** Add.  Add c to this Coordinate
   */
  Coordinate& operator+= ( const Coordinate& c );
  /** Subtract.  Subtract c from this Coordinate
   */
  Coordinate& operator-= ( const Coordinate& c );
  /** Scale.  Scales this Coordinate by a factor r
   */
  Coordinate& operator*= ( double r );
  /** Scale.  Scales this Coordinate by a factor r
   */
  Coordinate& operator*= ( int r );
  /** Scale.  Scales this Coordinate by a factor 1/r
   */
  Coordinate& operator/= ( double r );
public:
  /** X Component.  The X Component of this Coordinate.
   */
  double x;
  /** Y Component.  The Y Component of this Coordinate.
   */
  double y;

  friend kdbgstream& operator<<( kdbgstream& s, const Coordinate& t );
  /** Add.  Returns the sum of a and b.
   */
  friend const Coordinate operator+ ( const Coordinate& a, const Coordinate& b );
  /** Subtract.  Returns the difference between a and b.
   */
  friend const Coordinate operator- ( const Coordinate& a, const Coordinate& b );
  /** Scale.  Returns this a, scaled by a factor of r.
   */
  friend const Coordinate operator* ( const Coordinate& a, double r );
  /** Scale.  Returns a, scaled by a factor of 1/r.
   */
  friend const Coordinate operator/ ( const Coordinate& a, double r );
  /** Scalar Product.  Returns the scalar product of a and b.
   */
  friend double operator*( const Coordinate& a, const Coordinate& b );
  /** Equal.  Tests two Coordinates for equality.
   */
  friend bool operator==( const Coordinate&, const Coordinate& );
  /** Not Equal.  Tests two Coordinates for inequality.
   */
  friend bool operator!=( const Coordinate&, const Coordinate& );
};

const Coordinate operator/ ( const Coordinate& a, double r );
kdbgstream& operator<<( kdbgstream& s, const Coordinate& t );
const Coordinate operator+ ( const Coordinate& a, const Coordinate& b );
const Coordinate operator- ( const Coordinate& a, const Coordinate& b );
const Coordinate operator* ( const Coordinate& a, double r );
const Coordinate operator* ( double r, const Coordinate& a );
double operator*( const Coordinate& a, const Coordinate& b );

double Coordinate::squareLength() const
{
  return x*x+y*y;
}

#endif