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.

615 lines
15 KiB

6 years ago
  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-2021 KiCad Developers, see AUTHORS.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 <type_traits>
  33. #include <math/util.h>
  34. /**
  35. * Traits class for VECTOR2.
  36. */
  37. template <class T>
  38. struct VECTOR2_TRAITS
  39. {
  40. /// extended range/precision types used by operations involving multiple
  41. /// multiplications to prevent overflow.
  42. typedef T extended_type;
  43. };
  44. template <>
  45. struct VECTOR2_TRAITS<int>
  46. {
  47. typedef int64_t extended_type;
  48. };
  49. // Forward declarations for template friends
  50. template <class T>
  51. class VECTOR2;
  52. template <class T>
  53. std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
  54. /**
  55. * Define a general 2D-vector/point.
  56. *
  57. * This class uses templates to be universal. Several operators are provided to help
  58. * easy implementing of linear algebra equations.
  59. *
  60. */
  61. template <class T = int>
  62. class VECTOR2
  63. {
  64. public:
  65. typedef typename VECTOR2_TRAITS<T>::extended_type extended_type;
  66. typedef T coord_type;
  67. static constexpr extended_type ECOORD_MAX = std::numeric_limits<extended_type>::max();
  68. static constexpr extended_type ECOORD_MIN = std::numeric_limits<extended_type>::min();
  69. T x, y;
  70. /// Construct a 2D-vector with x, y = 0
  71. VECTOR2();
  72. /// Construct a vector with given components x, y
  73. VECTOR2( T x, T y );
  74. /// Initializes a vector from another specialization. Beware of rounding issues.
  75. template <typename CastingType>
  76. VECTOR2( const VECTOR2<CastingType>& aVec )
  77. {
  78. if( std::is_same<T, int>::value )
  79. {
  80. CastingType minI = static_cast<CastingType>( std::numeric_limits<int>::min() );
  81. CastingType maxI = static_cast<CastingType>( std::numeric_limits<int>::max() );
  82. x = static_cast<int>( Clamp( minI, aVec.x, maxI ) );
  83. y = static_cast<int>( Clamp( minI, aVec.y, maxI ) );
  84. }
  85. else
  86. {
  87. x = static_cast<T>( aVec.x );
  88. y = static_cast<T>( aVec.y );
  89. }
  90. }
  91. /// Copy a vector
  92. VECTOR2( const VECTOR2<T>& aVec )
  93. {
  94. x = aVec.x;
  95. y = aVec.y;
  96. }
  97. /// Cast a vector to another specialized subclass. Beware of rounding issues.
  98. template <typename CastedType>
  99. VECTOR2<CastedType> operator()() const
  100. {
  101. if( std::is_same<CastedType, int>::value )
  102. {
  103. T minI = static_cast<T>( std::numeric_limits<int>::min() );
  104. T maxI = static_cast<T>( std::numeric_limits<int>::max() );
  105. return VECTOR2<int>( static_cast<int>( Clamp( minI, x, maxI ) ),
  106. static_cast<int>( Clamp( minI, y, maxI ) ) );
  107. }
  108. else
  109. {
  110. return VECTOR2<CastedType>( static_cast<CastedType>( x ), static_cast<CastedType>( y ) );
  111. }
  112. }
  113. // virtual ~VECTOR2();
  114. /**
  115. * Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
  116. *
  117. * It is used to calculate the length of the vector.
  118. *
  119. * @return Scalar, the euclidean norm
  120. */
  121. T EuclideanNorm() const;
  122. /**
  123. * Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
  124. *
  125. * It is used to calculate the length of the vector.
  126. *
  127. * @return Scalar, the euclidean norm
  128. */
  129. extended_type SquaredEuclideanNorm() const;
  130. /**
  131. * Compute the perpendicular vector.
  132. *
  133. * @return Perpendicular vector
  134. */
  135. VECTOR2<T> Perpendicular() const;
  136. /**
  137. * Return a vector of the same direction, but length specified in \a aNewLength.
  138. *
  139. * @param aNewLength is the length of the rescaled vector.
  140. * @return the rescaled vector.
  141. */
  142. VECTOR2<T> Resize( T aNewLength ) const;
  143. /**
  144. * Return the vector formatted as a string.
  145. *
  146. * @return the formatted string
  147. */
  148. const std::string Format() const;
  149. /**
  150. * Compute cross product of self with \a aVector.
  151. */
  152. extended_type Cross( const VECTOR2<T>& aVector ) const;
  153. /**
  154. * Compute dot product of self with \a aVector.
  155. */
  156. extended_type Dot( const VECTOR2<T>& aVector ) const;
  157. // Operators
  158. /// Assignment operator
  159. VECTOR2<T>& operator=( const VECTOR2<T>& aVector );
  160. /// Vector addition operator
  161. VECTOR2<T> operator+( const VECTOR2<T>& aVector ) const;
  162. /// Scalar addition operator
  163. VECTOR2<T> operator+( const T& aScalar ) const;
  164. /// Compound assignment operator
  165. VECTOR2<T>& operator+=( const VECTOR2<T>& aVector );
  166. /// Compound assignment operator
  167. VECTOR2<T>& operator*=( const VECTOR2<T>& aVector );
  168. VECTOR2<T>& operator*=( const T& aScalar );
  169. /// Compound assignment operator
  170. VECTOR2<T>& operator+=( const T& aScalar );
  171. /// Vector subtraction operator
  172. VECTOR2<T> operator-( const VECTOR2<T>& aVector ) const;
  173. /// Scalar subtraction operator
  174. VECTOR2<T> operator-( const T& aScalar ) const;
  175. /// Compound assignment operator
  176. VECTOR2<T>& operator-=( const VECTOR2<T>& aVector );
  177. /// Compound assignment operator
  178. VECTOR2<T>& operator-=( const T& aScalar );
  179. /// Negate Vector operator
  180. VECTOR2<T> operator-();
  181. /// Scalar product operator
  182. extended_type operator*( const VECTOR2<T>& aVector ) const;
  183. /// Multiplication with a factor
  184. VECTOR2<T> operator*( const T& aFactor ) const;
  185. /// Division with a factor
  186. VECTOR2<T> operator/( double aFactor ) const;
  187. /// Equality operator
  188. bool operator==( const VECTOR2<T>& aVector ) const;
  189. /// Not equality operator
  190. bool operator!=( const VECTOR2<T>& aVector ) const;
  191. /// Smaller than operator
  192. bool operator<( const VECTOR2<T>& aVector ) const;
  193. bool operator<=( const VECTOR2<T>& aVector ) const;
  194. /// Greater than operator
  195. bool operator>( const VECTOR2<T>& aVector ) const;
  196. bool operator>=( const VECTOR2<T>& aVector ) const;
  197. };
  198. // ----------------------
  199. // --- Implementation ---
  200. // ----------------------
  201. template <class T>
  202. VECTOR2<T>::VECTOR2() : x{}, y{}
  203. {
  204. }
  205. template <class T>
  206. VECTOR2<T>::VECTOR2( T aX, T aY )
  207. {
  208. x = aX;
  209. y = aY;
  210. }
  211. template <class T>
  212. T VECTOR2<T>::EuclideanNorm() const
  213. {
  214. return static_cast<T>( sqrt( (extended_type) x * x + (extended_type) y * y ) );
  215. }
  216. template <class T>
  217. typename VECTOR2<T>::extended_type VECTOR2<T>::SquaredEuclideanNorm() const
  218. {
  219. return (extended_type) x * x + (extended_type) y * y;
  220. }
  221. template <class T>
  222. VECTOR2<T> VECTOR2<T>::Perpendicular() const
  223. {
  224. VECTOR2<T> perpendicular( -y, x );
  225. return perpendicular;
  226. }
  227. template <class T>
  228. VECTOR2<T>& VECTOR2<T>::operator=( const VECTOR2<T>& aVector )
  229. {
  230. x = aVector.x;
  231. y = aVector.y;
  232. return *this;
  233. }
  234. template <class T>
  235. VECTOR2<T>& VECTOR2<T>::operator+=( const VECTOR2<T>& aVector )
  236. {
  237. x += aVector.x;
  238. y += aVector.y;
  239. return *this;
  240. }
  241. template <class T>
  242. VECTOR2<T>& VECTOR2<T>::operator*=( const VECTOR2<T>& aVector )
  243. {
  244. x *= aVector.x;
  245. y *= aVector.y;
  246. return *this;
  247. }
  248. template <class T>
  249. VECTOR2<T>& VECTOR2<T>::operator*=( const T& aScalar )
  250. {
  251. x *= aScalar;
  252. y *= aScalar;
  253. return *this;
  254. }
  255. template <class T>
  256. VECTOR2<T>& VECTOR2<T>::operator+=( const T& aScalar )
  257. {
  258. x += aScalar;
  259. y += aScalar;
  260. return *this;
  261. }
  262. template <class T>
  263. VECTOR2<T>& VECTOR2<T>::operator-=( const VECTOR2<T>& aVector )
  264. {
  265. x -= aVector.x;
  266. y -= aVector.y;
  267. return *this;
  268. }
  269. template <class T>
  270. VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
  271. {
  272. x -= aScalar;
  273. y -= aScalar;
  274. return *this;
  275. }
  276. template <class T>
  277. VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
  278. {
  279. if( x == 0 && y == 0 )
  280. return VECTOR2<T> ( 0, 0 );
  281. extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
  282. extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
  283. if( std::is_integral<T>::value )
  284. {
  285. return VECTOR2<T> (
  286. ( x < 0 ? -1 : 1 ) *
  287. KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ) ),
  288. ( y < 0 ? -1 : 1 ) *
  289. KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) )
  290. * sign( aNewLength );
  291. }
  292. else
  293. {
  294. return VECTOR2<T> (
  295. ( x < 0 ? -1 : 1 ) *
  296. std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
  297. ( y < 0 ? -1 : 1 ) *
  298. std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) )
  299. * sign( aNewLength );
  300. }
  301. }
  302. template <class T>
  303. const std::string VECTOR2<T>::Format() const
  304. {
  305. std::stringstream ss;
  306. ss << "( xy " << x << " " << y << " )";
  307. return ss.str();
  308. }
  309. template <class T>
  310. VECTOR2<T> VECTOR2<T>::operator+( const VECTOR2<T>& aVector ) const
  311. {
  312. return VECTOR2<T> ( x + aVector.x, y + aVector.y );
  313. }
  314. template <class T>
  315. VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
  316. {
  317. return VECTOR2<T> ( x + aScalar, y + aScalar );
  318. }
  319. template <class T>
  320. VECTOR2<T> VECTOR2<T>::operator-( const VECTOR2<T>& aVector ) const
  321. {
  322. return VECTOR2<T> ( x - aVector.x, y - aVector.y );
  323. }
  324. template <class T>
  325. VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
  326. {
  327. return VECTOR2<T> ( x - aScalar, y - aScalar );
  328. }
  329. template <class T>
  330. VECTOR2<T> VECTOR2<T>::operator-()
  331. {
  332. return VECTOR2<T> ( -x, -y );
  333. }
  334. template <class T>
  335. typename VECTOR2<T>::extended_type VECTOR2<T>::operator*( const VECTOR2<T>& aVector ) const
  336. {
  337. return (extended_type)aVector.x * x + (extended_type)aVector.y * y;
  338. }
  339. template <class T>
  340. VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
  341. {
  342. VECTOR2<T> vector( x * aFactor, y * aFactor );
  343. return vector;
  344. }
  345. template <class T>
  346. VECTOR2<T> VECTOR2<T>::operator/( double aFactor ) const
  347. {
  348. if( std::is_integral<T>::value )
  349. return VECTOR2<T>( KiROUND( x / aFactor ), KiROUND( y / aFactor ) );
  350. else
  351. return VECTOR2<T>( static_cast<T>( x / aFactor ), static_cast<T>( y / aFactor ) );
  352. }
  353. template <class T>
  354. VECTOR2<T> operator*( const T& aFactor, const VECTOR2<T>& aVector )
  355. {
  356. VECTOR2<T> vector( aVector.x * aFactor, aVector.y * aFactor );
  357. return vector;
  358. }
  359. template <class T>
  360. typename VECTOR2<T>::extended_type VECTOR2<T>::Cross( const VECTOR2<T>& aVector ) const
  361. {
  362. return (extended_type) x * (extended_type) aVector.y -
  363. (extended_type) y * (extended_type) aVector.x;
  364. }
  365. template <class T>
  366. typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector ) const
  367. {
  368. return (extended_type) x * (extended_type) aVector.x +
  369. (extended_type) y * (extended_type) aVector.y;
  370. }
  371. template <class T>
  372. bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
  373. {
  374. return ( *this * *this ) < ( aVector * aVector );
  375. }
  376. template <class T>
  377. bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
  378. {
  379. return ( *this * *this ) <= ( aVector * aVector );
  380. }
  381. template <class T>
  382. bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
  383. {
  384. return ( *this * *this ) > ( aVector * aVector );
  385. }
  386. template <class T>
  387. bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
  388. {
  389. return ( *this * *this ) >= ( aVector * aVector );
  390. }
  391. template <class T>
  392. bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
  393. {
  394. return ( aVector.x == x ) && ( aVector.y == y );
  395. }
  396. template <class T>
  397. bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
  398. {
  399. return ( aVector.x != x ) || ( aVector.y != y );
  400. }
  401. template <class T>
  402. const VECTOR2<T> LexicographicalMax( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
  403. {
  404. if( aA.x > aB.x )
  405. return aA;
  406. else if( aA.x == aB.x && aA.y > aB.y )
  407. return aA;
  408. return aB;
  409. }
  410. template <class T>
  411. const VECTOR2<T> LexicographicalMin( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
  412. {
  413. if( aA.x < aB.x )
  414. return aA;
  415. else if( aA.x == aB.x && aA.y < aB.y )
  416. return aA;
  417. return aB;
  418. }
  419. template <class T>
  420. int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
  421. {
  422. if( aA.x < aB.x )
  423. return -1;
  424. else if( aA.x > aB.x )
  425. return 1;
  426. else // aA.x == aB.x
  427. {
  428. if( aA.y < aB.y )
  429. return -1;
  430. else if( aA.y > aB.y )
  431. return 1;
  432. else
  433. return 0;
  434. }
  435. }
  436. /**
  437. * Template to compare two VECTOR2<T> values for equality within a required epsilon.
  438. *
  439. * @param aFirst value to compare.
  440. * @param aSecond value to compare.
  441. * @param aEpsilon allowed error.
  442. * @return true if the values considered equal within the specified epsilon, otherwise false.
  443. */
  444. template <class T>
  445. typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
  446. equals( VECTOR2<T> const& aFirst, VECTOR2<T> const& aSecond,
  447. T aEpsilon = std::numeric_limits<T>::epsilon() )
  448. {
  449. if( !equals( aFirst.x, aSecond.x, aEpsilon ) )
  450. {
  451. return false;
  452. }
  453. return equals( aFirst.y, aSecond.y, aEpsilon );
  454. }
  455. template <class T>
  456. std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
  457. {
  458. aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
  459. return aStream;
  460. }
  461. /* Default specializations */
  462. typedef VECTOR2<double> VECTOR2D;
  463. typedef VECTOR2<int> VECTOR2I;
  464. typedef VECTOR2<unsigned int> VECTOR2U;
  465. /* STL specializations */
  466. namespace std
  467. {
  468. // Required to enable correct use in std::map/unordered_map
  469. // DO NOT USE hash tables with VECTOR2 elements. It is inefficient
  470. // and degenerates to a linear search. Use the std::map/std::set
  471. // trees instead that utilize the less operator below
  472. // This function is purposely deleted after substantial testing
  473. template <>
  474. struct hash<VECTOR2I>
  475. {
  476. size_t operator()( const VECTOR2I& k ) const = delete;
  477. };
  478. // Required to enable use of std::hash with maps.
  479. template <>
  480. struct less<VECTOR2I>
  481. {
  482. bool operator()( const VECTOR2I& aA, const VECTOR2I& aB ) const;
  483. };
  484. }
  485. #endif // VECTOR2D_H_