You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

595 lines
14 KiB

  1. /*
  2. * This program source code file is part of KICAD, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2010 Virtenio GmbH, Torsten Hueter, torsten.hueter <at> virtenio.de
  5. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  6. * Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
  7. * Copyright (C) 2013 CERN
  8. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, you may find one here:
  22. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  23. * or you may search the http://www.gnu.org website for the version 2 license,
  24. * or you may write to the Free Software Foundation, Inc.,
  25. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  26. */
  27. #ifndef VECTOR2D_H_
  28. #define VECTOR2D_H_
  29. #include <limits>
  30. #include <iostream>
  31. #include <sstream>
  32. #include <math/math_util.h>
  33. #ifdef WX_COMPATIBILITY
  34. #include <wx/gdicmn.h>
  35. #endif
  36. /**
  37. * Class VECTOR2_TRAITS
  38. * traits class for VECTOR2.
  39. */
  40. template <class T>
  41. struct VECTOR2_TRAITS
  42. {
  43. ///> extended range/precision types used by operations involving multiple
  44. ///> multiplications to prevent overflow.
  45. typedef T extended_type;
  46. };
  47. template <>
  48. struct VECTOR2_TRAITS<int>
  49. {
  50. typedef int64_t extended_type;
  51. };
  52. // Forward declarations for template friends
  53. template <class T>
  54. class VECTOR2;
  55. template <class T>
  56. std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
  57. /**
  58. * Class VECTOR2
  59. * defines a general 2D-vector/point.
  60. *
  61. * This class uses templates to be universal. Several operators are provided to help
  62. * easy implementing of linear algebra equations.
  63. *
  64. */
  65. template <class T = int>
  66. class VECTOR2
  67. {
  68. public:
  69. typedef typename VECTOR2_TRAITS<T>::extended_type extended_type;
  70. typedef T coord_type;
  71. static constexpr extended_type ECOORD_MAX = std::numeric_limits<extended_type>::max();
  72. static constexpr extended_type ECOORD_MIN = std::numeric_limits<extended_type>::min();
  73. T x, y;
  74. // Constructors
  75. /// Construct a 2D-vector with x, y = 0
  76. VECTOR2();
  77. #ifdef WX_COMPATIBILITY
  78. /// Constructor with a wxPoint as argument
  79. VECTOR2( const wxPoint& aPoint );
  80. /// Constructor with a wxSize as argument
  81. VECTOR2( const wxSize& aSize );
  82. #endif
  83. /// Construct a vector with given components x, y
  84. VECTOR2( T x, T y );
  85. /// Initializes a vector from another specialization. Beware of rouding
  86. /// issues.
  87. template <typename CastingType>
  88. VECTOR2( const VECTOR2<CastingType>& aVec )
  89. {
  90. x = (T) aVec.x;
  91. y = (T) aVec.y;
  92. }
  93. /// Casts a vector to another specialized subclass. Beware of rouding
  94. /// issues.
  95. template <typename CastedType>
  96. VECTOR2<CastedType> operator()() const
  97. {
  98. return VECTOR2<CastedType>( (CastedType) x, (CastedType) y );
  99. }
  100. /**
  101. * (wxPoint)
  102. * implements the cast to wxPoint.
  103. * @return wxPoint - the vector cast to wxPoint.
  104. */
  105. explicit operator wxPoint() const
  106. {
  107. return wxPoint( x, y );
  108. }
  109. /// Destructor
  110. // virtual ~VECTOR2();
  111. /**
  112. * Function Euclidean Norm
  113. * computes the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
  114. * It is used to calculate the length of the vector.
  115. * @return Scalar, the euclidean norm
  116. */
  117. T EuclideanNorm() const;
  118. /**
  119. * Function Squared Euclidean Norm
  120. * computes the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
  121. * It is used to calculate the length of the vector.
  122. * @return Scalar, the euclidean norm
  123. */
  124. extended_type SquaredEuclideanNorm() const;
  125. /**
  126. * Function Perpendicular
  127. * computes the perpendicular vector
  128. * @return Perpendicular vector
  129. */
  130. VECTOR2<T> Perpendicular() const;
  131. /**
  132. * Function Resize
  133. * returns a vector of the same direction, but length specified in aNewLength
  134. * @param aNewLength: length of the rescaled vector
  135. * @return rescaled vector
  136. */
  137. VECTOR2<T> Resize( T aNewLength ) const;
  138. /**
  139. * Function Angle
  140. * computes the angle of the vector
  141. * @return vector angle, in radians
  142. */
  143. double Angle() const;
  144. /**
  145. * Function Rotate
  146. * rotates the vector by a given angle
  147. * @param aAngle rotation angle in radians
  148. * @return rotated vector
  149. */
  150. VECTOR2<T> Rotate( double aAngle ) const;
  151. /**
  152. * Function Format
  153. * returns the vector formatted as a string
  154. * @return the formatted string
  155. */
  156. const std::string Format() const;
  157. /**
  158. * Function Cross()
  159. * computes cross product of self with aVector
  160. */
  161. extended_type Cross( const VECTOR2<T>& aVector ) const;
  162. /**
  163. * Function Dot()
  164. * computes dot product of self with aVector
  165. */
  166. extended_type Dot( const VECTOR2<T>& aVector ) const;
  167. // Operators
  168. /// Assignment operator
  169. VECTOR2<T>& operator=( const VECTOR2<T>& aVector );
  170. /// Vector addition operator
  171. VECTOR2<T> operator+( const VECTOR2<T>& aVector ) const;
  172. /// Scalar addition operator
  173. VECTOR2<T> operator+( const T& aScalar ) const;
  174. /// Compound assignment operator
  175. VECTOR2<T>& operator+=( const VECTOR2<T>& aVector );
  176. /// Compound assignment operator
  177. VECTOR2<T>& operator+=( const T& aScalar );
  178. /// Vector subtraction operator
  179. VECTOR2<T> operator-( const VECTOR2<T>& aVector ) const;
  180. /// Scalar subtraction operator
  181. VECTOR2<T> operator-( const T& aScalar ) const;
  182. /// Compound assignment operator
  183. VECTOR2<T>& operator-=( const VECTOR2<T>& aVector );
  184. /// Compound assignment operator
  185. VECTOR2<T>& operator-=( const T& aScalar );
  186. /// Negate Vector operator
  187. VECTOR2<T> operator-();
  188. /// Scalar product operator
  189. extended_type operator*( const VECTOR2<T>& aVector ) const;
  190. /// Multiplication with a factor
  191. VECTOR2<T> operator*( const T& aFactor ) const;
  192. /// Division with a factor
  193. VECTOR2<T> operator/( const T& aFactor ) const;
  194. /// Equality operator
  195. bool operator==( const VECTOR2<T>& aVector ) const;
  196. /// Not equality operator
  197. bool operator!=( const VECTOR2<T>& aVector ) const;
  198. /// Smaller than operator
  199. bool operator<( const VECTOR2<T>& aVector ) const;
  200. bool operator<=( const VECTOR2<T>& aVector ) const;
  201. /// Greater than operator
  202. bool operator>( const VECTOR2<T>& aVector ) const;
  203. bool operator>=( const VECTOR2<T>& aVector ) const;
  204. };
  205. // ----------------------
  206. // --- Implementation ---
  207. // ----------------------
  208. template <class T>
  209. VECTOR2<T>::VECTOR2()
  210. {
  211. x = y = 0.0;
  212. }
  213. #ifdef WX_COMPATIBILITY
  214. template <class T>
  215. VECTOR2<T>::VECTOR2( wxPoint const& aPoint )
  216. {
  217. x = T( aPoint.x );
  218. y = T( aPoint.y );
  219. }
  220. template <class T>
  221. VECTOR2<T>::VECTOR2( wxSize const& aSize )
  222. {
  223. x = T( aSize.x );
  224. y = T( aSize.y );
  225. }
  226. #endif
  227. template <class T>
  228. VECTOR2<T>::VECTOR2( T aX, T aY )
  229. {
  230. x = aX;
  231. y = aY;
  232. }
  233. template <class T>
  234. T VECTOR2<T>::EuclideanNorm() const
  235. {
  236. return sqrt( (extended_type) x * x + (extended_type) y * y );
  237. }
  238. template <class T>
  239. typename VECTOR2<T>::extended_type VECTOR2<T>::SquaredEuclideanNorm() const
  240. {
  241. return (extended_type) x * x + (extended_type) y * y;
  242. }
  243. template <class T>
  244. double VECTOR2<T>::Angle() const
  245. {
  246. return atan2( (double) y, (double) x );
  247. }
  248. template <class T>
  249. VECTOR2<T> VECTOR2<T>::Perpendicular() const
  250. {
  251. VECTOR2<T> perpendicular( -y, x );
  252. return perpendicular;
  253. }
  254. template <class T>
  255. VECTOR2<T>& VECTOR2<T>::operator=( const VECTOR2<T>& aVector )
  256. {
  257. x = aVector.x;
  258. y = aVector.y;
  259. return *this;
  260. }
  261. template <class T>
  262. VECTOR2<T>& VECTOR2<T>::operator+=( const VECTOR2<T>& aVector )
  263. {
  264. x += aVector.x;
  265. y += aVector.y;
  266. return *this;
  267. }
  268. template <class T>
  269. VECTOR2<T>& VECTOR2<T>::operator+=( const T& aScalar )
  270. {
  271. x += aScalar;
  272. y += aScalar;
  273. return *this;
  274. }
  275. template <class T>
  276. VECTOR2<T>& VECTOR2<T>::operator-=( const VECTOR2<T>& aVector )
  277. {
  278. x -= aVector.x;
  279. y -= aVector.y;
  280. return *this;
  281. }
  282. template <class T>
  283. VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
  284. {
  285. x -= aScalar;
  286. y -= aScalar;
  287. return *this;
  288. }
  289. /**
  290. * Rotate a VECTOR2 by aAngle.
  291. * @param aAngle = rotation angle in radians
  292. */
  293. template <class T>
  294. VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
  295. {
  296. // Avoid 0 radian rotation, case very frequently found
  297. if( aAngle == 0.0 )
  298. return VECTOR2<T> ( T( x ), T( y ) );
  299. double sa = sin( aAngle );
  300. double ca = cos( aAngle );
  301. return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
  302. T( (double) x * sa + (double) y * ca ) );
  303. }
  304. template <class T>
  305. VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
  306. {
  307. if( x == 0 && y == 0 )
  308. return VECTOR2<T> ( 0, 0 );
  309. extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
  310. extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
  311. return VECTOR2<T> (
  312. ( x < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
  313. ( y < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) * sign( aNewLength );
  314. }
  315. template <class T>
  316. const std::string VECTOR2<T>::Format() const
  317. {
  318. std::stringstream ss;
  319. ss << "( xy " << x << " " << y << " )";
  320. return ss.str();
  321. }
  322. template <class T>
  323. VECTOR2<T> VECTOR2<T>::operator+( const VECTOR2<T>& aVector ) const
  324. {
  325. return VECTOR2<T> ( x + aVector.x, y + aVector.y );
  326. }
  327. template <class T>
  328. VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
  329. {
  330. return VECTOR2<T> ( x + aScalar, y + aScalar );
  331. }
  332. template <class T>
  333. VECTOR2<T> VECTOR2<T>::operator-( const VECTOR2<T>& aVector ) const
  334. {
  335. return VECTOR2<T> ( x - aVector.x, y - aVector.y );
  336. }
  337. template <class T>
  338. VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
  339. {
  340. return VECTOR2<T> ( x - aScalar, y - aScalar );
  341. }
  342. template <class T>
  343. VECTOR2<T> VECTOR2<T>::operator-()
  344. {
  345. return VECTOR2<T> ( -x, -y );
  346. }
  347. template <class T>
  348. typename VECTOR2<T>::extended_type VECTOR2<T>::operator*( const VECTOR2<T>& aVector ) const
  349. {
  350. return (extended_type)aVector.x * x + (extended_type)aVector.y * y;
  351. }
  352. template <class T>
  353. VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
  354. {
  355. VECTOR2<T> vector( x * aFactor, y * aFactor );
  356. return vector;
  357. }
  358. template <class T>
  359. VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
  360. {
  361. VECTOR2<T> vector( x / aFactor, y / aFactor );
  362. return vector;
  363. }
  364. template <class T>
  365. VECTOR2<T> operator*( const T& aFactor, const VECTOR2<T>& aVector )
  366. {
  367. VECTOR2<T> vector( aVector.x * aFactor, aVector.y * aFactor );
  368. return vector;
  369. }
  370. template <class T>
  371. typename VECTOR2<T>::extended_type VECTOR2<T>::Cross( const VECTOR2<T>& aVector ) const
  372. {
  373. return (extended_type) x * (extended_type) aVector.y -
  374. (extended_type) y * (extended_type) aVector.x;
  375. }
  376. template <class T>
  377. typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector ) const
  378. {
  379. return (extended_type) x * (extended_type) aVector.x +
  380. (extended_type) y * (extended_type) aVector.y;
  381. }
  382. template <class T>
  383. bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
  384. {
  385. return ( *this * *this ) < ( aVector * aVector );
  386. }
  387. template <class T>
  388. bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
  389. {
  390. return ( *this * *this ) <= ( aVector * aVector );
  391. }
  392. template <class T>
  393. bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
  394. {
  395. return ( *this * *this ) > ( aVector * aVector );
  396. }
  397. template <class T>
  398. bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
  399. {
  400. return ( *this * *this ) >= ( aVector * aVector );
  401. }
  402. template <class T>
  403. bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
  404. {
  405. return ( aVector.x == x ) && ( aVector.y == y );
  406. }
  407. template <class T>
  408. bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
  409. {
  410. return ( aVector.x != x ) || ( aVector.y != y );
  411. }
  412. template <class T>
  413. const VECTOR2<T> LexicographicalMax( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
  414. {
  415. if( aA.x > aB.x )
  416. return aA;
  417. else if( aA.x == aB.x && aA.y > aB.y )
  418. return aA;
  419. return aB;
  420. }
  421. template <class T>
  422. const VECTOR2<T> LexicographicalMin( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
  423. {
  424. if( aA.x < aB.x )
  425. return aA;
  426. else if( aA.x == aB.x && aA.y < aB.y )
  427. return aA;
  428. return aB;
  429. }
  430. template <class T>
  431. const int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
  432. {
  433. if( aA.x < aB.x )
  434. return -1;
  435. else if( aA.x > aB.x )
  436. return 1;
  437. else // aA.x == aB.x
  438. {
  439. if( aA.y < aB.y )
  440. return -1;
  441. else if( aA.y > aB.y )
  442. return 1;
  443. else
  444. return 0;
  445. }
  446. }
  447. template <class T>
  448. std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
  449. {
  450. aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
  451. return aStream;
  452. }
  453. /* Default specializations */
  454. typedef VECTOR2<double> VECTOR2D;
  455. typedef VECTOR2<int> VECTOR2I;
  456. typedef VECTOR2<unsigned int> VECTOR2U;
  457. /* Compatibility typedefs */
  458. // FIXME should be removed to avoid multiple typedefs for the same type
  459. typedef VECTOR2<double> DPOINT;
  460. typedef DPOINT DSIZE;
  461. #endif // VECTOR2D_H_