Advertisement
chrondog

Untitled

Jan 1st, 2013
633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.77 KB | None | 0 0
  1. //========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8.  
  9. #ifndef VECTOR2D_H
  10. #define VECTOR2D_H
  11.  
  12. #ifdef _WIN32
  13. #pragma once
  14. #endif
  15.  
  16. #include <math.h>
  17. #include <float.h>
  18.  
  19. // For vec_t, put this somewhere else?
  20. #include "tier0/basetypes.h"
  21.  
  22. // For rand(). We really need a library!
  23. #include <stdlib.h>
  24.  
  25. #include "tier0/dbg.h"
  26. #include "mathlib/math_pfns.h"
  27.  
  28. //=========================================================
  29. // 2D Vector2D
  30. //=========================================================
  31.  
  32. class Vector2D                 
  33. {
  34. public:
  35.     // Members
  36.     vec_t x, y;
  37.  
  38.     // Construction/destruction
  39.     Vector2D(void);
  40.     Vector2D(vec_t X, vec_t Y);
  41.     Vector2D(const float *pFloat);
  42.  
  43.     // Initialization
  44.     void Init(vec_t ix=0.0f, vec_t iy=0.0f);
  45.  
  46.     // Got any nasty NAN's?
  47.     bool IsValid() const;
  48.  
  49.     // array access...
  50.     vec_t operator[](int i) const;
  51.     vec_t& operator[](int i);
  52.  
  53.     // Base address...
  54.     vec_t* Base();
  55.     vec_t const* Base() const;
  56.  
  57.     // Initialization methods
  58.     void Random( float minVal, float maxVal );
  59.  
  60.     // equality
  61.     bool operator==(const Vector2D& v) const;
  62.     bool operator!=(const Vector2D& v) const;  
  63.  
  64.     // arithmetic operations
  65.     Vector2D&   operator+=(const Vector2D &v);         
  66.     Vector2D&   operator-=(const Vector2D &v);     
  67.     Vector2D&   operator*=(const Vector2D &v);         
  68.     Vector2D&   operator*=(float s);
  69.     Vector2D&   operator/=(const Vector2D &v);     
  70.     Vector2D&   operator/=(float s);                   
  71.  
  72.     // negate the Vector2D components
  73.     void    Negate();
  74.  
  75.     // Get the Vector2D's magnitude.
  76.     vec_t   Length() const;
  77.  
  78.     // Get the Vector2D's magnitude squared.
  79.     vec_t   LengthSqr(void) const;
  80.  
  81.     // return true if this vector is (0,0) within tolerance
  82.     bool IsZero( float tolerance = 0.01f ) const
  83.     {
  84.         return (x > -tolerance && x < tolerance &&
  85.                 y > -tolerance && y < tolerance);
  86.     }
  87.  
  88.     // Normalize in place and return the old length.
  89.     vec_t   NormalizeInPlace();
  90.  
  91.     // Compare length.
  92.     bool    IsLengthGreaterThan( float val ) const;
  93.     bool    IsLengthLessThan( float val ) const;
  94.  
  95.     // Get the distance from this Vector2D to the other one.
  96.     vec_t   DistTo(const Vector2D &vOther) const;
  97.  
  98.     // Get the distance from this Vector2D to the other one squared.
  99.     vec_t   DistToSqr(const Vector2D &vOther) const;       
  100.  
  101.     // Copy
  102.     void    CopyToArray(float* rgfl) const;
  103.  
  104.     // Multiply, add, and assign to this (ie: *this = a + b * scalar). This
  105.     // is about 12% faster than the actual Vector2D equation (because it's done per-component
  106.     // rather than per-Vector2D).
  107.     void    MulAdd(const Vector2D& a, const Vector2D& b, float scalar);
  108.  
  109.     // Dot product.
  110.     vec_t   Dot(const Vector2D& vOther) const;         
  111.  
  112.     // assignment
  113.     Vector2D& operator=(const Vector2D &vOther);
  114.  
  115. #ifndef VECTOR_NO_SLOW_OPERATIONS
  116.     // copy constructors
  117.     Vector2D(const Vector2D &vOther);
  118.  
  119.     // arithmetic operations
  120.     Vector2D    operator-(void) const;
  121.                
  122.     Vector2D    operator+(const Vector2D& v) const;
  123.     Vector2D    operator-(const Vector2D& v) const;
  124.     Vector2D    operator*(const Vector2D& v) const;
  125.     Vector2D    operator/(const Vector2D& v) const;
  126.     Vector2D    operator*(float fl) const;
  127.     Vector2D    operator/(float fl) const;         
  128.    
  129.     // Cross product between two vectors.
  130.     Vector2D    Cross(const Vector2D &vOther) const;       
  131.  
  132.     // Returns a Vector2D with the min or max in X, Y, and Z.
  133.     Vector2D    Min(const Vector2D &vOther) const;
  134.     Vector2D    Max(const Vector2D &vOther) const;
  135.  
  136. #else
  137.  
  138. private:
  139.     // No copy constructors allowed if we're in optimal mode
  140.     Vector2D(const Vector2D& vOther);
  141. #endif
  142. };
  143.  
  144. //-----------------------------------------------------------------------------
  145.  
  146. const Vector2D vec2_origin(0,0);
  147. const Vector2D vec2_invalid( FLT_MAX, FLT_MAX );
  148.  
  149. //-----------------------------------------------------------------------------
  150. // Vector2D related operations
  151. //-----------------------------------------------------------------------------
  152.  
  153. // Vector2D clear
  154. void Vector2DClear( Vector2D& a );
  155.  
  156. // Copy
  157. void Vector2DCopy( const Vector2D& src, Vector2D& dst );
  158.  
  159. // Vector2D arithmetic
  160. void Vector2DAdd( const Vector2D& a, const Vector2D& b, Vector2D& result );
  161. void Vector2DSubtract( const Vector2D& a, const Vector2D& b, Vector2D& result );
  162. void Vector2DMultiply( const Vector2D& a, vec_t b, Vector2D& result );
  163. void Vector2DMultiply( const Vector2D& a, const Vector2D& b, Vector2D& result );
  164. void Vector2DDivide( const Vector2D& a, vec_t b, Vector2D& result );
  165. void Vector2DDivide( const Vector2D& a, const Vector2D& b, Vector2D& result );
  166. void Vector2DMA( const Vector2D& start, float s, const Vector2D& dir, Vector2D& result );
  167.  
  168. // Store the min or max of each of x, y, and z into the result.
  169. void Vector2DMin( const Vector2D &a, const Vector2D &b, Vector2D &result );
  170. void Vector2DMax( const Vector2D &a, const Vector2D &b, Vector2D &result );
  171.  
  172. #define Vector2DExpand( v ) (v).x, (v).y
  173.  
  174. // Normalization
  175. vec_t Vector2DNormalize( Vector2D& v );
  176.  
  177. // Length
  178. vec_t Vector2DLength( const Vector2D& v );
  179.  
  180. // Dot Product
  181. vec_t DotProduct2D(const Vector2D& a, const Vector2D& b);
  182.  
  183. // Linearly interpolate between two vectors
  184. void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest );
  185.  
  186.  
  187. //-----------------------------------------------------------------------------
  188. //
  189. // Inlined Vector2D methods
  190. //
  191. //-----------------------------------------------------------------------------
  192.  
  193.  
  194. //-----------------------------------------------------------------------------
  195. // constructors
  196. //-----------------------------------------------------------------------------
  197.  
  198. inline Vector2D::Vector2D(void)                                
  199. {
  200. #ifdef _DEBUG
  201.     // Initialize to NAN to catch errors
  202.     x = y = VEC_T_NAN;
  203. #endif
  204. }
  205.  
  206. inline Vector2D::Vector2D(vec_t X, vec_t Y)                    
  207. {
  208.     x = X; y = Y;
  209.     Assert( IsValid() );
  210. }
  211.  
  212. inline Vector2D::Vector2D(const float *pFloat)                 
  213. {
  214.     Assert( pFloat );
  215.     x = pFloat[0]; y = pFloat[1];  
  216.     Assert( IsValid() );
  217. }
  218.  
  219.  
  220. //-----------------------------------------------------------------------------
  221. // copy constructor
  222. //-----------------------------------------------------------------------------
  223.  
  224. inline Vector2D::Vector2D(const Vector2D &vOther)                  
  225. {
  226.     Assert( vOther.IsValid() );
  227.     x = vOther.x; y = vOther.y;
  228. }
  229.  
  230. //-----------------------------------------------------------------------------
  231. // initialization
  232. //-----------------------------------------------------------------------------
  233.  
  234. inline void Vector2D::Init( vec_t ix, vec_t iy )    
  235. {
  236.     x = ix; y = iy;
  237.     Assert( IsValid() );
  238. }
  239.  
  240. inline void Vector2D::Random( float minVal, float maxVal )
  241. {
  242.     x = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal);
  243.     y = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal);
  244. }
  245.  
  246. inline void Vector2DClear( Vector2D& a )
  247. {
  248.     a.x = a.y = 0.0f;
  249. }
  250.  
  251. //-----------------------------------------------------------------------------
  252. // assignment
  253. //-----------------------------------------------------------------------------
  254.  
  255. inline Vector2D& Vector2D::operator=(const Vector2D &vOther)   
  256. {
  257.     Assert( vOther.IsValid() );
  258.     x=vOther.x; y=vOther.y;
  259.     return *this;
  260. }
  261.  
  262. //-----------------------------------------------------------------------------
  263. // Array access
  264. //-----------------------------------------------------------------------------
  265.  
  266. inline vec_t& Vector2D::operator[](int i)
  267. {
  268.     Assert( (i >= 0) && (i < 2) );
  269.     return ((vec_t*)this)[i];
  270. }
  271.  
  272. inline vec_t Vector2D::operator[](int i) const
  273. {
  274.     Assert( (i >= 0) && (i < 2) );
  275.     return ((vec_t*)this)[i];
  276. }
  277.  
  278. //-----------------------------------------------------------------------------
  279. // Base address...
  280. //-----------------------------------------------------------------------------
  281.  
  282. inline vec_t* Vector2D::Base()
  283. {
  284.     return (vec_t*)this;
  285. }
  286.  
  287. inline vec_t const* Vector2D::Base() const
  288. {
  289.     return (vec_t const*)this;
  290. }
  291.  
  292. //-----------------------------------------------------------------------------
  293. // IsValid?
  294. //-----------------------------------------------------------------------------
  295.  
  296. inline bool Vector2D::IsValid() const
  297. {
  298.     return IsFinite(x) && IsFinite(y);
  299. }
  300.  
  301. //-----------------------------------------------------------------------------
  302. // comparison
  303. //-----------------------------------------------------------------------------
  304.  
  305. inline bool Vector2D::operator==( const Vector2D& src ) const
  306. {
  307.     Assert( src.IsValid() && IsValid() );
  308.     return (src.x == x) && (src.y == y);
  309. }
  310.  
  311. inline bool Vector2D::operator!=( const Vector2D& src ) const
  312. {
  313.     Assert( src.IsValid() && IsValid() );
  314.     return (src.x != x) || (src.y != y);
  315. }
  316.  
  317.  
  318. //-----------------------------------------------------------------------------
  319. // Copy
  320. //-----------------------------------------------------------------------------
  321.  
  322. inline void Vector2DCopy( const Vector2D& src, Vector2D& dst )
  323. {
  324.     Assert( src.IsValid() );
  325.     dst.x = src.x;
  326.     dst.y = src.y;
  327. }
  328.  
  329. inline void Vector2D::CopyToArray(float* rgfl) const       
  330. {
  331.     Assert( IsValid() );
  332.     Assert( rgfl );
  333.     rgfl[0] = x; rgfl[1] = y;
  334. }
  335.  
  336. //-----------------------------------------------------------------------------
  337. // standard math operations
  338. //-----------------------------------------------------------------------------
  339.  
  340. inline void Vector2D::Negate()
  341. {
  342.     Assert( IsValid() );
  343.     x = -x; y = -y;
  344. }
  345.  
  346. inline Vector2D& Vector2D::operator+=(const Vector2D& v)   
  347. {
  348.     Assert( IsValid() && v.IsValid() );
  349.     x+=v.x; y+=v.y;
  350.     return *this;
  351. }
  352.  
  353. inline Vector2D& Vector2D::operator-=(const Vector2D& v)   
  354. {
  355.     Assert( IsValid() && v.IsValid() );
  356.     x-=v.x; y-=v.y;
  357.     return *this;
  358. }
  359.  
  360. inline Vector2D& Vector2D::operator*=(float fl)
  361. {
  362.     x *= fl;
  363.     y *= fl;
  364.     Assert( IsValid() );
  365.     return *this;
  366. }
  367.  
  368. inline Vector2D& Vector2D::operator*=(const Vector2D& v)   
  369. {
  370.     x *= v.x;
  371.     y *= v.y;
  372.     Assert( IsValid() );
  373.     return *this;
  374. }
  375.  
  376. inline Vector2D& Vector2D::operator/=(float fl)
  377. {
  378.     Assert( fl != 0.0f );
  379.     float oofl = 1.0f / fl;
  380.     x *= oofl;
  381.     y *= oofl;
  382.     Assert( IsValid() );
  383.     return *this;
  384. }
  385.  
  386. inline Vector2D& Vector2D::operator/=(const Vector2D& v)   
  387. {
  388.     Assert( v.x != 0.0f && v.y != 0.0f );
  389.     x /= v.x;
  390.     y /= v.y;
  391.     Assert( IsValid() );
  392.     return *this;
  393. }
  394.  
  395. inline void Vector2DAdd( const Vector2D& a, const Vector2D& b, Vector2D& c )
  396. {
  397.     Assert( a.IsValid() && b.IsValid() );
  398.     c.x = a.x + b.x;
  399.     c.y = a.y + b.y;
  400. }
  401.  
  402. inline void Vector2DSubtract( const Vector2D& a, const Vector2D& b, Vector2D& c )
  403. {
  404.     Assert( a.IsValid() && b.IsValid() );
  405.     c.x = a.x - b.x;
  406.     c.y = a.y - b.y;
  407. }
  408.  
  409. inline void Vector2DMultiply( const Vector2D& a, vec_t b, Vector2D& c )
  410. {
  411.     Assert( a.IsValid() && IsFinite(b) );
  412.     c.x = a.x * b;
  413.     c.y = a.y * b;
  414. }
  415.  
  416. inline void Vector2DMultiply( const Vector2D& a, const Vector2D& b, Vector2D& c )
  417. {                
  418.     Assert( a.IsValid() && b.IsValid() );
  419.     c.x = a.x * b.x;
  420.     c.y = a.y * b.y;
  421. }
  422.  
  423.  
  424. inline void Vector2DDivide( const Vector2D& a, vec_t b, Vector2D& c )
  425. {
  426.     Assert( a.IsValid() );
  427.     Assert( b != 0.0f );
  428.     vec_t oob = 1.0f / b;
  429.     c.x = a.x * oob;
  430.     c.y = a.y * oob;
  431. }
  432.  
  433. inline void Vector2DDivide( const Vector2D& a, const Vector2D& b, Vector2D& c )
  434. {
  435.     Assert( a.IsValid() );
  436.     Assert( (b.x != 0.0f) && (b.y != 0.0f) );
  437.     c.x = a.x / b.x;
  438.     c.y = a.y / b.y;
  439. }
  440.  
  441. inline void Vector2DMA( const Vector2D& start, float s, const Vector2D& dir, Vector2D& result )
  442. {
  443.     Assert( start.IsValid() && IsFinite(s) && dir.IsValid() );
  444.     result.x = start.x + s*dir.x;
  445.     result.y = start.y + s*dir.y;
  446. }
  447.  
  448. // FIXME: Remove
  449. // For backwards compatability
  450. inline void Vector2D::MulAdd(const Vector2D& a, const Vector2D& b, float scalar)
  451. {
  452.     x = a.x + b.x * scalar;
  453.     y = a.y + b.y * scalar;
  454. }
  455.  
  456. inline void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest )
  457. {
  458.     dest[0] = src1[0] + (src2[0] - src1[0]) * t;
  459.     dest[1] = src1[1] + (src2[1] - src1[1]) * t;
  460. }
  461.  
  462. //-----------------------------------------------------------------------------
  463. // dot, cross
  464. //-----------------------------------------------------------------------------
  465. inline vec_t DotProduct2D(const Vector2D& a, const Vector2D& b)
  466. {
  467.     Assert( a.IsValid() && b.IsValid() );
  468.     return( a.x*b.x + a.y*b.y );
  469. }
  470.  
  471. // for backwards compatability
  472. inline vec_t Vector2D::Dot( const Vector2D& vOther ) const
  473. {
  474.     return DotProduct2D( *this, vOther );
  475. }
  476.  
  477.  
  478. //-----------------------------------------------------------------------------
  479. // length
  480. //-----------------------------------------------------------------------------
  481. inline vec_t Vector2DLength( const Vector2D& v )
  482. {
  483.     Assert( v.IsValid() );
  484.     return (vec_t)FastSqrt(v.x*v.x + v.y*v.y);     
  485. }
  486.  
  487. inline vec_t Vector2D::LengthSqr(void) const   
  488. {
  489.     Assert( IsValid() );
  490.     return (x*x + y*y);    
  491. }
  492.  
  493. inline vec_t Vector2D::NormalizeInPlace()
  494. {
  495.     return Vector2DNormalize( *this );
  496. }
  497.  
  498. inline bool Vector2D::IsLengthGreaterThan( float val ) const
  499. {
  500.     return LengthSqr() > val*val;
  501. }
  502.  
  503. inline bool Vector2D::IsLengthLessThan( float val ) const
  504. {
  505.     return LengthSqr() < val*val;
  506. }
  507.  
  508. inline vec_t Vector2D::Length(void) const  
  509. {
  510.     return Vector2DLength( *this );
  511. }
  512.  
  513.  
  514. inline void Vector2DMin( const Vector2D &a, const Vector2D &b, Vector2D &result )
  515. {
  516.     result.x = (a.x < b.x) ? a.x : b.x;
  517.     result.y = (a.y < b.y) ? a.y : b.y;
  518. }
  519.  
  520.  
  521. inline void Vector2DMax( const Vector2D &a, const Vector2D &b, Vector2D &result )
  522. {
  523.     result.x = (a.x > b.x) ? a.x : b.x;
  524.     result.y = (a.y > b.y) ? a.y : b.y;
  525. }
  526.  
  527.  
  528. //-----------------------------------------------------------------------------
  529. // Normalization
  530. //-----------------------------------------------------------------------------
  531. inline vec_t Vector2DNormalize( Vector2D& v )
  532. {
  533.     Assert( v.IsValid() );
  534.     vec_t l = v.Length();
  535.     if (l != 0.0f)
  536.     {
  537.         v /= l;
  538.     }
  539.     else
  540.     {
  541.         v.x = v.y = 0.0f;
  542.     }
  543.     return l;
  544. }
  545.  
  546.  
  547. //-----------------------------------------------------------------------------
  548. // Get the distance from this Vector2D to the other one
  549. //-----------------------------------------------------------------------------
  550. inline vec_t Vector2D::DistTo(const Vector2D &vOther) const
  551. {
  552.     Vector2D delta;
  553.     Vector2DSubtract( *this, vOther, delta );
  554.     return delta.Length();
  555. }
  556.  
  557. inline vec_t Vector2D::DistToSqr(const Vector2D &vOther) const
  558. {
  559.     Vector2D delta;
  560.     Vector2DSubtract( *this, vOther, delta );
  561.     return delta.LengthSqr();
  562. }
  563.  
  564.  
  565. //-----------------------------------------------------------------------------
  566. // Computes the closest point to vecTarget no farther than flMaxDist from vecStart
  567. //-----------------------------------------------------------------------------
  568. inline void ComputeClosestPoint2D( const Vector2D& vecStart, float flMaxDist, const Vector2D& vecTarget, Vector2D *pResult )
  569. {
  570.     Vector2D vecDelta;
  571.     Vector2DSubtract( vecTarget, vecStart, vecDelta );
  572.     float flDistSqr = vecDelta.LengthSqr();
  573.     if ( flDistSqr <= flMaxDist * flMaxDist )
  574.     {
  575.         *pResult = vecTarget;
  576.     }
  577.     else
  578.     {
  579.         vecDelta /= FastSqrt( flDistSqr );
  580.         Vector2DMA( vecStart, flMaxDist, vecDelta, *pResult );
  581.     }
  582. }
  583.  
  584.  
  585.  
  586. //-----------------------------------------------------------------------------
  587. //
  588. // Slow methods
  589. //
  590. //-----------------------------------------------------------------------------
  591.  
  592. #ifndef VECTOR_NO_SLOW_OPERATIONS
  593.  
  594. //-----------------------------------------------------------------------------
  595. // Returns a Vector2D with the min or max in X, Y, and Z.
  596. //-----------------------------------------------------------------------------
  597.  
  598. inline Vector2D Vector2D::Min(const Vector2D &vOther) const
  599. {
  600.     return Vector2D(x < vOther.x ? x : vOther.x,
  601.         y < vOther.y ? y : vOther.y);
  602. }
  603.  
  604. inline Vector2D Vector2D::Max(const Vector2D &vOther) const
  605. {
  606.     return Vector2D(x > vOther.x ? x : vOther.x,
  607.         y > vOther.y ? y : vOther.y);
  608. }
  609.  
  610.  
  611. //-----------------------------------------------------------------------------
  612. // arithmetic operations
  613. //-----------------------------------------------------------------------------
  614.  
  615. inline Vector2D Vector2D::operator-(void) const
  616. {
  617.     return Vector2D(-x,-y);            
  618. }
  619.  
  620. inline Vector2D Vector2D::operator+(const Vector2D& v) const   
  621. {
  622.     Vector2D res;
  623.     Vector2DAdd( *this, v, res );
  624.     return res;
  625. }
  626.  
  627. inline Vector2D Vector2D::operator-(const Vector2D& v) const   
  628. {
  629.     Vector2D res;
  630.     Vector2DSubtract( *this, v, res );
  631.     return res;
  632. }
  633.  
  634. inline Vector2D Vector2D::operator*(float fl) const
  635. {
  636.     Vector2D res;
  637.     Vector2DMultiply( *this, fl, res );
  638.     return res;
  639. }
  640.  
  641. inline Vector2D Vector2D::operator*(const Vector2D& v) const   
  642. {
  643.     Vector2D res;
  644.     Vector2DMultiply( *this, v, res );
  645.     return res;
  646. }
  647.  
  648. inline Vector2D Vector2D::operator/(float fl) const
  649. {
  650.     Vector2D res;
  651.     Vector2DDivide( *this, fl, res );
  652.     return res;
  653. }
  654.  
  655. inline Vector2D Vector2D::operator/(const Vector2D& v) const   
  656. {
  657.     Vector2D res;
  658.     Vector2DDivide( *this, v, res );
  659.     return res;
  660. }
  661.  
  662. inline Vector2D operator*(float fl, const Vector2D& v) 
  663. {
  664.     return v * fl;
  665. }
  666.  
  667. #endif //slow
  668.  
  669. #endif // VECTOR2D_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement