1 // Created by: Kirill GAVRILOV 2 // Copyright (c) 2013-2014 OPEN CASCADE SAS 3 // 4 // This file is part of Open CASCADE Technology software library. 5 // 6 // This library is free software; you can redistribute it and/or modify it under 7 // the terms of the GNU Lesser General Public License version 2.1 as published 8 // by the Free Software Foundation, with special exception defined in the file 9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 10 // distribution for complete text of the license and disclaimer of any warranty. 11 // 12 // Alternatively, this file may be used under the terms of Open CASCADE 13 // commercial license or contractual agreement. 14 15 #ifndef _NCollection_Vec2_H__ 16 #define _NCollection_Vec2_H__ 17 18 #include <cmath> // std::sqrt() 19 20 //! Auxiliary macros to define couple of similar access components as vector methods. 21 //! @return 2 components by their names in specified order 22 #define NCOLLECTION_VEC_COMPONENTS_2D(theX, theY) \ 23 const NCollection_Vec2<Element_t> theX##theY() const { return NCollection_Vec2<Element_t>(theX(), theY()); } \ 24 const NCollection_Vec2<Element_t> theY##theX() const { return NCollection_Vec2<Element_t>(theY(), theX()); } 25 26 //! Defines the 2D-vector template. 27 //! The main target for this class - to handle raw low-level arrays (from/to graphic driver etc.). 28 template<typename Element_t> 29 class NCollection_Vec2 30 { 31 32 public: 33 34 //! Returns the number of components. Length()35 static int Length() 36 { 37 return 2; 38 } 39 40 //! Empty constructor. Construct the zero vector. NCollection_Vec2()41 NCollection_Vec2() 42 { 43 v[0] = v[1] = Element_t(0); 44 } 45 46 //! Initialize ALL components of vector within specified value. NCollection_Vec2(const Element_t theXY)47 explicit NCollection_Vec2 (const Element_t theXY) 48 { 49 v[0] = v[1] = theXY; 50 } 51 52 //! Per-component constructor. NCollection_Vec2(const Element_t theX,const Element_t theY)53 explicit NCollection_Vec2 (const Element_t theX, 54 const Element_t theY) 55 { 56 v[0] = theX; 57 v[1] = theY; 58 } 59 60 //! Conversion constructor (explicitly converts some 2-component vector with other element type 61 //! to a new 2-component vector with the element type Element_t, 62 //! whose elements are static_cast'ed corresponding elements of theOtherVec2 vector) 63 //! @tparam OtherElement_t the element type of the other 2-component vector theOtherVec2 64 //! @param theOtherVec2 the 2-component vector that needs to be converted 65 template <typename OtherElement_t> NCollection_Vec2(const NCollection_Vec2<OtherElement_t> & theOtherVec2)66 explicit NCollection_Vec2 (const NCollection_Vec2<OtherElement_t>& theOtherVec2) 67 { 68 v[0] = static_cast<Element_t> (theOtherVec2[0]); 69 v[1] = static_cast<Element_t> (theOtherVec2[1]); 70 } 71 72 //! Assign new values to the vector. SetValues(const Element_t theX,const Element_t theY)73 void SetValues (const Element_t theX, 74 const Element_t theY) 75 { 76 v[0] = theX; 77 v[1] = theY; 78 } 79 80 //! Alias to 1st component as X coordinate in XY. x() const81 Element_t x() const { return v[0]; } 82 83 //! Alias to 2nd component as Y coordinate in XY. y() const84 Element_t y() const { return v[1]; } 85 86 //! @return 2 components by their names in specified order (in GLSL-style) NCOLLECTION_VEC_COMPONENTS_2D(x,y)87 NCOLLECTION_VEC_COMPONENTS_2D(x, y) 88 89 //! Alias to 1st component as X coordinate in XY. 90 Element_t& x() { return v[0]; } 91 92 //! Alias to 2nd component as Y coordinate in XY. y()93 Element_t& y() { return v[1]; } 94 95 //! Check this vector with another vector for equality (without tolerance!). IsEqual(const NCollection_Vec2 & theOther) const96 bool IsEqual (const NCollection_Vec2& theOther) const 97 { 98 return v[0] == theOther.v[0] 99 && v[1] == theOther.v[1]; 100 } 101 102 //! Check this vector with another vector for equality (without tolerance!). operator ==(const NCollection_Vec2 & theOther)103 bool operator== (const NCollection_Vec2& theOther) { return IsEqual (theOther); } operator ==(const NCollection_Vec2 & theOther) const104 bool operator== (const NCollection_Vec2& theOther) const { return IsEqual (theOther); } 105 106 //! Check this vector with another vector for non-equality (without tolerance!). operator !=(const NCollection_Vec2 & theOther)107 bool operator!= (const NCollection_Vec2& theOther) { return !IsEqual (theOther); } operator !=(const NCollection_Vec2 & theOther) const108 bool operator!= (const NCollection_Vec2& theOther) const { return !IsEqual (theOther); } 109 110 //! Raw access to the data (for OpenGL exchange). GetData() const111 const Element_t* GetData() const { return v; } ChangeData()112 Element_t* ChangeData() { return v; } operator const Element_t*() const113 operator const Element_t*() const { return v; } operator Element_t*()114 operator Element_t*() { return v; } 115 116 //! Compute per-component summary. operator +=(const NCollection_Vec2 & theAdd)117 NCollection_Vec2& operator+= (const NCollection_Vec2& theAdd) 118 { 119 v[0] += theAdd.v[0]; 120 v[1] += theAdd.v[1]; 121 return *this; 122 } 123 124 //! Compute per-component summary. operator +(const NCollection_Vec2 & theLeft,const NCollection_Vec2 & theRight)125 friend NCollection_Vec2 operator+ (const NCollection_Vec2& theLeft, 126 const NCollection_Vec2& theRight) 127 { 128 return NCollection_Vec2 (theLeft.v[0] + theRight.v[0], 129 theLeft.v[1] + theRight.v[1]); 130 } 131 132 //! Compute per-component subtraction. operator -=(const NCollection_Vec2 & theDec)133 NCollection_Vec2& operator-= (const NCollection_Vec2& theDec) 134 { 135 v[0] -= theDec.v[0]; 136 v[1] -= theDec.v[1]; 137 return *this; 138 } 139 140 //! Compute per-component subtraction. operator -(const NCollection_Vec2 & theLeft,const NCollection_Vec2 & theRight)141 friend NCollection_Vec2 operator- (const NCollection_Vec2& theLeft, 142 const NCollection_Vec2& theRight) 143 { 144 return NCollection_Vec2 (theLeft.v[0] - theRight.v[0], 145 theLeft.v[1] - theRight.v[1]); 146 } 147 148 //! Unary -. operator -() const149 NCollection_Vec2 operator-() const 150 { 151 return NCollection_Vec2 (-x(), -y()); 152 } 153 154 //! Compute per-component multiplication. operator *=(const NCollection_Vec2 & theRight)155 NCollection_Vec2& operator*= (const NCollection_Vec2& theRight) 156 { 157 v[0] *= theRight.v[0]; 158 v[1] *= theRight.v[1]; 159 return *this; 160 } 161 162 //! Compute per-component multiplication. operator *(const NCollection_Vec2 & theLeft,const NCollection_Vec2 & theRight)163 friend NCollection_Vec2 operator* (const NCollection_Vec2& theLeft, 164 const NCollection_Vec2& theRight) 165 { 166 return NCollection_Vec2 (theLeft.v[0] * theRight.v[0], 167 theLeft.v[1] * theRight.v[1]); 168 } 169 170 //! Compute per-component multiplication by scale factor. Multiply(const Element_t theFactor)171 void Multiply (const Element_t theFactor) 172 { 173 v[0] *= theFactor; 174 v[1] *= theFactor; 175 } 176 177 //! Compute per-component multiplication by scale factor. Multiplied(const Element_t theFactor) const178 NCollection_Vec2 Multiplied (const Element_t theFactor) const 179 { 180 return NCollection_Vec2 (v[0] * theFactor, 181 v[1] * theFactor); 182 } 183 184 //! Compute component-wise minimum of two vectors. cwiseMin(const NCollection_Vec2 & theVec) const185 NCollection_Vec2 cwiseMin (const NCollection_Vec2& theVec) const 186 { 187 return NCollection_Vec2 (v[0] < theVec.v[0] ? v[0] : theVec.v[0], 188 v[1] < theVec.v[1] ? v[1] : theVec.v[1]); 189 } 190 191 //! Compute component-wise maximum of two vectors. cwiseMax(const NCollection_Vec2 & theVec) const192 NCollection_Vec2 cwiseMax (const NCollection_Vec2& theVec) const 193 { 194 return NCollection_Vec2 (v[0] > theVec.v[0] ? v[0] : theVec.v[0], 195 v[1] > theVec.v[1] ? v[1] : theVec.v[1]); 196 } 197 198 //! Compute component-wise modulus of the vector. cwiseAbs() const199 NCollection_Vec2 cwiseAbs() const 200 { 201 return NCollection_Vec2 (std::abs (v[0]), 202 std::abs (v[1])); 203 } 204 205 //! Compute maximum component of the vector. maxComp() const206 Element_t maxComp() const 207 { 208 return v[0] > v[1] ? v[0] : v[1]; 209 } 210 211 //! Compute minimum component of the vector. minComp() const212 Element_t minComp() const 213 { 214 return v[0] < v[1] ? v[0] : v[1]; 215 } 216 217 //! Compute per-component multiplication by scale factor. operator *=(const Element_t theFactor)218 NCollection_Vec2& operator*= (const Element_t theFactor) 219 { 220 Multiply (theFactor); 221 return *this; 222 } 223 224 //! Compute per-component division by scale factor. operator /=(const Element_t theInvFactor)225 NCollection_Vec2& operator/= (const Element_t theInvFactor) 226 { 227 v[0] /= theInvFactor; 228 v[1] /= theInvFactor; 229 return *this; 230 } 231 232 //! Compute per-component division. operator /=(const NCollection_Vec2 & theRight)233 NCollection_Vec2& operator/= (const NCollection_Vec2& theRight) 234 { 235 v[0] /= theRight.v[0]; 236 v[1] /= theRight.v[1]; 237 return *this; 238 } 239 240 //! Compute per-component multiplication by scale factor. operator *(const Element_t theFactor) const241 NCollection_Vec2 operator* (const Element_t theFactor) const 242 { 243 return Multiplied (theFactor); 244 } 245 246 //! Compute per-component division by scale factor. operator /(const Element_t theInvFactor) const247 NCollection_Vec2 operator/ (const Element_t theInvFactor) const 248 { 249 return NCollection_Vec2(v[0] / theInvFactor, 250 v[1] / theInvFactor); 251 } 252 253 //! Compute per-component division. operator /(const NCollection_Vec2 & theLeft,const NCollection_Vec2 & theRight)254 friend NCollection_Vec2 operator/ (const NCollection_Vec2& theLeft, 255 const NCollection_Vec2& theRight) 256 { 257 return NCollection_Vec2 (theLeft.v[0] / theRight.v[0], 258 theLeft.v[1] / theRight.v[1]); 259 } 260 261 //! Computes the dot product. Dot(const NCollection_Vec2 & theOther) const262 Element_t Dot (const NCollection_Vec2& theOther) const 263 { 264 return x() * theOther.x() + y() * theOther.y(); 265 } 266 267 //! Computes the vector modulus (magnitude, length). Modulus() const268 Element_t Modulus() const 269 { 270 return std::sqrt (x() * x() + y() * y()); 271 } 272 273 //! Computes the square of vector modulus (magnitude, length). 274 //! This method may be used for performance tricks. SquareModulus() const275 Element_t SquareModulus() const 276 { 277 return x() * x() + y() * y(); 278 } 279 280 //! Constuct DX unit vector. DX()281 static NCollection_Vec2 DX() 282 { 283 return NCollection_Vec2 (Element_t(1), Element_t(0)); 284 } 285 286 //! Constuct DY unit vector. DY()287 static NCollection_Vec2 DY() 288 { 289 return NCollection_Vec2 (Element_t(0), Element_t(1)); 290 } 291 292 private: 293 294 Element_t v[2]; 295 296 }; 297 298 #endif // _NCollection_Vec2_H__ 299