Subversion Repositories gelsvn

Rev

Rev 633 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 633 Rev 634
1
/* ----------------------------------------------------------------------- *
1
/* ----------------------------------------------------------------------- *
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
3
 * Copyright (C) the authors and DTU Informatics
3
 * Copyright (C) the authors and DTU Informatics
4
 * For license and list of authors, see ../../doc/intro.pdf
4
 * For license and list of authors, see ../../doc/intro.pdf
5
 * @brief Abstract vector class
5
 * @brief Abstract vector class
6
 * ----------------------------------------------------------------------- */
6
 * ----------------------------------------------------------------------- */
7
 
7
 
8
/** @file ArithVec.h
8
/** @file ArithVec.h
9
 * @brief Abstract vector class
9
 * @brief Abstract vector class
10
 */
10
 */
11
 
11
 
12
#ifndef __CGLA_ARITHVEC_H__
12
#ifndef __CGLA_ARITHVEC_H__
13
#define __CGLA_ARITHVEC_H__
13
#define __CGLA_ARITHVEC_H__
14
 
14
 
15
#include <array>
15
#include <array>
16
#include <algorithm>
16
#include <algorithm>
17
#include <iostream>
17
#include <iostream>
18
#include "CGLA.h"
18
#include "CGLA.h"
19
 
19
 
20
#include <numeric>
20
#include <numeric>
21
 
21
 
22
namespace CGLA
22
namespace CGLA
23
{
23
{
24
    
24
    
25
    /** \brief Template representing generic arithmetic vectors.
25
    /** \brief Template representing generic arithmetic vectors.
26
     
26
     
27
     The three parameters to the template are
27
     The three parameters to the template are
28
     
28
     
29
     T - the scalar type (i.e. float, int, double etc.)
29
     T - the scalar type (i.e. float, int, double etc.)
30
     
30
     
31
     V - the name of the vector type. This template is always (and
31
     V - the name of the vector type. This template is always (and
32
     only) used as ancestor of concrete types, and the name of the
32
     only) used as ancestor of concrete types, and the name of the
33
     class _inheriting_ _from_ this class is used as the V argument.
33
     class _inheriting_ _from_ this class is used as the V argument.
34
     
34
     
35
     N - The final argument is the dimension N. For instance, N=3 for a
35
     N - The final argument is the dimension N. For instance, N=3 for a
36
     3D vector.
36
     3D vector.
37
     
37
     
38
     This class template contains all functions that are assumed to be
38
     This class template contains all functions that are assumed to be
39
     the same for any arithmetic vector - regardless of dimension or
39
     the same for any arithmetic vector - regardless of dimension or
40
     the type of scalars used for coordinates.
40
     the type of scalars used for coordinates.
41
     
41
     
42
     The template contains no virtual functions which is important
42
     The template contains no virtual functions which is important
43
     since they add overhead.
43
     since they add overhead.
44
     */
44
     */
45
    
45
    
46
    template <class T, class V, unsigned int N>
46
    template <class T, class V, unsigned int N>
47
    class ArithVec
47
    class ArithVec
48
    {
48
    {
49
        
49
        
50
    protected:
50
    protected:
51
        
51
        
52
        /// The actual contents of the vector.
52
        /// The actual contents of the vector.
53
        std::array<T,N> data;
53
        std::array<T,N> data;
54
        
54
        
55
    protected:
55
    protected:
56
        
56
        
57
        //----------------------------------------------------------------------
57
        //----------------------------------------------------------------------
58
        // Constructors
58
        // Constructors
59
        //----------------------------------------------------------------------
59
        //----------------------------------------------------------------------
60
        
60
        
61
        /// Construct uninitialized vector
61
        /// Construct uninitialized vector
62
        ArithVec() {}
62
        ArithVec() {}
63
        
63
        
64
        /// Construct a vector where all coordinates are identical
64
        /// Construct a vector where all coordinates are identical
65
        explicit ArithVec(T _a)
65
        explicit ArithVec(T _a)
66
        {
66
        {
67
            std::fill_n(data, N, _a);
67
            std::fill_n(data, N, _a);
68
        }
68
        }
69
        
69
        
70
        /// Construct a 2D vector
70
        /// Construct a 2D vector
71
        ArithVec(T _a, T _b): data({_a,_b}) {assert(N==2);}
71
        ArithVec(T _a, T _b)
72
        
72
        {
73
        /// Construct a 2D vector
73
            assert(N==2);
-
 
74
            data[0] = _a;
74
        ArithVec(T _a, T _b, T _c): data({_a,_b,_c}) {assert(N==3);}
75
            data[1] = _b;
-
 
76
        }
75
        
77
        
76
        /// Construct a 2D vector
78
        /// Construct a 3D vector
77
        ArithVec(T _a, T _b, T _c, T _d): data({_a,_b,_c,_d}) {assert(N==4);}
79
        ArithVec(T _a, T _b, T _c)
-
 
80
        {
-
 
81
            assert(N==3);
-
 
82
            data[0] = _a;
-
 
83
            data[1] = _b;
-
 
84
            data[2] = _c;
-
 
85
        }
78
        
86
        
-
 
87
        /// Construct a 4D vector
-
 
88
        ArithVec(T _a, T _b, T _c, T _d)
-
 
89
        {
-
 
90
            assert(N==4);
-
 
91
            data[0] = _a;
-
 
92
            data[1] = _b;
-
 
93
            data[2] = _c;
-
 
94
            data[3] = _d;
-
 
95
        }
79
    public:
96
    public:
80
        
97
        
81
        /// For convenience we define a more meaningful name for the scalar type
98
        /// For convenience we define a more meaningful name for the scalar type
82
        typedef T ScalarType;
99
        typedef T ScalarType;
83
        
100
        
84
        /// A more meaningful name for vector type
101
        /// A more meaningful name for vector type
85
        typedef V VectorType;
102
        typedef V VectorType;
86
        
103
        
87
        /// Return dimension of vector
104
        /// Return dimension of vector
88
        static unsigned int get_dim() {return N;}
105
        static unsigned int get_dim() {return N;}
89
        
106
        
90
        /// Set all coordinates of a 2D vector.
107
        /// Set all coordinates of a 2D vector.
91
        void set(T _a, T _b)
108
        void set(T _a, T _b)
92
        {
109
        {
93
            assert(N==2);
110
            assert(N==2);
-
 
111
            data[0] = _a;
94
            data = {_a,_b};
112
            data[1] = _b;
95
        }
113
        }
96
        
114
        
97
        /// Set all coordinates of a 3D vector.
115
        /// Set all coordinates of a 3D vector.
98
        void set(T _a, T _b, T _c)
116
        void set(T _a, T _b, T _c)
99
        {
117
        {
100
            assert(N==3);
118
            assert(N==3);
-
 
119
            data[0] = _a;
-
 
120
            data[1] = _b;
101
            data = {_a,_b,_c};
121
            data[2] = _c;
102
        }
122
        }
103
        
123
        
104
        /// Set all coordinates of a 4D vector.
124
        /// Set all coordinates of a 4D vector.
105
        void set(T _a, T _b, T _c, T _d)
125
        void set(T _a, T _b, T _c, T _d)
106
        {
126
        {
107
            assert(N==4);
127
            assert(N==4);
-
 
128
            data[0] = _a;
-
 
129
            data[1] = _b;
-
 
130
            data[2] = _c;
108
            data = {_a,_b,_c,_d};
131
            data[3] = _d;
109
        }
132
        }
110
        
133
        
111
        /// Const index operator
134
        /// Const index operator
112
        const T& operator [] ( unsigned int i ) const
135
        const T& operator [] ( unsigned int i ) const
113
        {
136
        {
114
            assert(i<N);
137
            assert(i<N);
115
            return data[i];
138
            return data[i];
116
        }
139
        }
117
        
140
        
118
        /// Non-const index operator
141
        /// Non-const index operator
119
        T& operator [] ( unsigned int i )
142
        T& operator [] ( unsigned int i )
120
        {
143
        {
121
            assert(i<N);
144
            assert(i<N);
122
            return data[i];
145
            return data[i];
123
        }
146
        }
124
        
147
        
125
        /// Const index operator
148
        /// Const index operator
126
        const T& operator () ( unsigned int i ) const
149
        const T& operator () ( unsigned int i ) const
127
        {
150
        {
128
            assert(i<N);
151
            assert(i<N);
129
            return data[i];
152
            return data[i];
130
        }
153
        }
131
        
154
        
132
        /// Non-const index operator
155
        /// Non-const index operator
133
        T& operator () ( unsigned int i )
156
        T& operator () ( unsigned int i )
134
        {
157
        {
135
            assert(i<N);
158
            assert(i<N);
136
            return data[i];
159
            return data[i];
137
        }
160
        }
138
        
161
        
139
        typedef typename std::array<T,N>::iterator iterator;
162
        typedef typename std::array<T,N>::iterator iterator;
140
        typedef typename std::array<T,N>::const_iterator const_iterator;
163
        typedef typename std::array<T,N>::const_iterator const_iterator;
141
        
164
        
142
        
165
        
143
        /** Get a pointer to first element in data array.
166
        /** Get a pointer to first element in data array.
144
         This function may be useful when interfacing with some other API
167
         This function may be useful when interfacing with some other API
145
         such as OpenGL (TM) */
168
         such as OpenGL (TM) */
146
        iterator begin() {return data.begin();}
169
        iterator begin() {return data.begin();}
147
        iterator end() {return data.end();}
170
        iterator end() {return data.end();}
148
        T* get() {return data.data();}
171
        T* get() {return data.data();}
149
        
172
        
150
        /** Get a const pointer to first element in data array.
173
        /** Get a const pointer to first element in data array.
151
         This function may be useful when interfacing with some other API
174
         This function may be useful when interfacing with some other API
152
         such as OpenGL (TM). */
175
         such as OpenGL (TM). */
153
        const_iterator begin() const {return data.begin();}
176
        const_iterator begin() const {return data.begin();}
154
        const_iterator end() const {return data.end();}
177
        const_iterator end() const {return data.end();}
155
        const T* get() const {return data.data();}
178
        const T* get() const {return data.data();}
156
        
179
        
157
        //----------------------------------------------------------------------
180
        //----------------------------------------------------------------------
158
        // Comparison operators
181
        // Comparison operators
159
        //----------------------------------------------------------------------
182
        //----------------------------------------------------------------------
160
        
183
        
161
        /// Equality operator
184
        /// Equality operator
162
        bool operator==(const V& v) const
185
        bool operator==(const V& v) const
163
        {
186
        {
164
            return std::equal(begin(),end(), v.begin());
187
            return std::equal(begin(),end(), v.begin());
165
        }
188
        }
166
        
189
        
167
        /// Equality wrt scalar. True if all coords are equal to scalar
190
        /// Equality wrt scalar. True if all coords are equal to scalar
168
        bool operator==(T k) const
191
        bool operator==(T k) const
169
        {
192
        {
170
            return std::count(begin(),end(), k)==N;
193
            return std::count(begin(),end(), k)==N;
171
        }
194
        }
172
        
195
        
173
        /// Inequality operator
196
        /// Inequality operator
174
        bool operator!=(const V& v) const
197
        bool operator!=(const V& v) const
175
        {
198
        {
176
            return !(*this==v);
199
            return !(*this==v);
177
        }
200
        }
178
        
201
        
179
        /// Inequality wrt scalar. True if any coord not equal to scalar
202
        /// Inequality wrt scalar. True if any coord not equal to scalar
180
        bool operator!=(T k) const
203
        bool operator!=(T k) const
181
        {
204
        {
182
            return !(*this==k);
205
            return !(*this==k);
183
        }
206
        }
184
        
207
        
185
        
208
        
186
        //----------------------------------------------------------------------
209
        //----------------------------------------------------------------------
187
        // Comparison functions ... of geometric significance
210
        // Comparison functions ... of geometric significance
188
        //----------------------------------------------------------------------
211
        //----------------------------------------------------------------------
189
        
212
        
190
        /** Compare all coordinates against other vector. ( < )
213
        /** Compare all coordinates against other vector. ( < )
191
         Similar to testing whether we are on one side of three planes. */
214
         Similar to testing whether we are on one side of three planes. */
192
        bool  all_l  (const V& v) const
215
        bool  all_l  (const V& v) const
193
        {
216
        {
194
            return std::inner_product(begin(), end(), v.begin(), true,
217
            return std::inner_product(begin(), end(), v.begin(), true,
195
                                      std::logical_and<bool>(), std::less<T>());
218
                                      std::logical_and<bool>(), std::less<T>());
196
        }
219
        }
197
        
220
        
198
        /** Compare all coordinates against other vector. ( <= )
221
        /** Compare all coordinates against other vector. ( <= )
199
         Similar to testing whether we are on one side of three planes. */
222
         Similar to testing whether we are on one side of three planes. */
200
        bool  all_le (const V& v) const
223
        bool  all_le (const V& v) const
201
        {
224
        {
202
            return std::inner_product(begin(), end(), v.begin(), true,
225
            return std::inner_product(begin(), end(), v.begin(), true,
203
                                      std::logical_and<bool>(), std::less_equal<T>());
226
                                      std::logical_and<bool>(), std::less_equal<T>());
204
        }
227
        }
205
        
228
        
206
        /** Compare all coordinates against other vector. ( > )
229
        /** Compare all coordinates against other vector. ( > )
207
         Similar to testing whether we are on one side of three planes. */
230
         Similar to testing whether we are on one side of three planes. */
208
        bool  all_g  (const V& v) const
231
        bool  all_g  (const V& v) const
209
        {
232
        {
210
            return std::inner_product(begin(), end(), v.begin(), true,
233
            return std::inner_product(begin(), end(), v.begin(), true,
211
                                      std::logical_and<bool>(), std::greater<T>());
234
                                      std::logical_and<bool>(), std::greater<T>());
212
        }
235
        }
213
        
236
        
214
        /** Compare all coordinates against other vector. ( >= )
237
        /** Compare all coordinates against other vector. ( >= )
215
         Similar to testing whether we are on one side of three planes. */
238
         Similar to testing whether we are on one side of three planes. */
216
        bool  all_ge (const V& v) const
239
        bool  all_ge (const V& v) const
217
        {
240
        {
218
            return std::inner_product(begin(), end(), v.begin(), true,
241
            return std::inner_product(begin(), end(), v.begin(), true,
219
                                      std::logical_and<bool>(), std::greater_equal<T>());
242
                                      std::logical_and<bool>(), std::greater_equal<T>());
220
        }
243
        }
221
        
244
        
222
        
245
        
223
        //----------------------------------------------------------------------
246
        //----------------------------------------------------------------------
224
        // Assignment operators
247
        // Assignment operators
225
        //----------------------------------------------------------------------
248
        //----------------------------------------------------------------------
226
        
249
        
227
        /// Assignment multiplication with scalar.
250
        /// Assignment multiplication with scalar.
228
        const V& operator *=(T k)
251
        const V& operator *=(T k)
229
        {
252
        {
230
            for(auto& x : data) {x*=k;}
253
            for(auto& x : data) {x*=k;}
231
            return static_cast<const V&>(*this);
254
            return static_cast<const V&>(*this);
232
        }
255
        }
233
        
256
        
234
        /// Assignment division with scalar.
257
        /// Assignment division with scalar.
235
        const V& operator /=(T k)
258
        const V& operator /=(T k)
236
        {
259
        {
237
            for(auto& x : data) {x/=k;}
260
            for(auto& x : data) {x/=k;}
238
            return static_cast<const V&>(*this);
261
            return static_cast<const V&>(*this);
239
        }
262
        }
240
        
263
        
241
        /// Assignment addition with scalar. Adds scalar to each coordinate.
264
        /// Assignment addition with scalar. Adds scalar to each coordinate.
242
        const V& operator +=(T k)
265
        const V& operator +=(T k)
243
        {
266
        {
244
            for(auto& x : data) {x+=k;}
267
            for(auto& x : data) {x+=k;}
245
            return  static_cast<const V&>(*this);
268
            return  static_cast<const V&>(*this);
246
        }
269
        }
247
        
270
        
248
        /// Assignment subtraction with scalar. Subtracts scalar from each coord.
271
        /// Assignment subtraction with scalar. Subtracts scalar from each coord.
249
        const V& operator -=(T k)
272
        const V& operator -=(T k)
250
        {
273
        {
251
            for(auto& x : data) {x-=k;}
274
            for(auto& x : data) {x-=k;}
252
            return  static_cast<const V&>(*this);
275
            return  static_cast<const V&>(*this);
253
        }
276
        }
254
        
277
        
255
        /** Assignment multiplication with vector.
278
        /** Assignment multiplication with vector.
256
         Multiply each coord independently. */
279
         Multiply each coord independently. */
257
        const V& operator *=(const V& v)
280
        const V& operator *=(const V& v)
258
        {
281
        {
259
            std::transform(begin(), end(), v.begin(), begin(), std::multiplies<T>());
282
            std::transform(begin(), end(), v.begin(), begin(), std::multiplies<T>());
260
            return  static_cast<const V&>(*this);
283
            return  static_cast<const V&>(*this);
261
        }
284
        }
262
        
285
        
263
        /// Assigment division with vector. Each coord divided independently.
286
        /// Assigment division with vector. Each coord divided independently.
264
        const V& operator /=(const V& v)
287
        const V& operator /=(const V& v)
265
        {
288
        {
266
            std::transform(begin(), end(),  v.begin(), begin(), std::divides<T>());
289
            std::transform(begin(), end(),  v.begin(), begin(), std::divides<T>());
267
            return  static_cast<const V&>(*this);
290
            return  static_cast<const V&>(*this);
268
        }
291
        }
269
        
292
        
270
        /// Assignmment addition with vector.
293
        /// Assignmment addition with vector.
271
        const V& operator +=(const V& v)
294
        const V& operator +=(const V& v)
272
        {
295
        {
273
            std::transform(begin(), end(), v.begin(), begin(), std::plus<T>());
296
            std::transform(begin(), end(), v.begin(), begin(), std::plus<T>());
274
            return  static_cast<const V&>(*this);
297
            return  static_cast<const V&>(*this);
275
        }
298
        }
276
		
299
		
277
        /// Assignment subtraction with vector.
300
        /// Assignment subtraction with vector.
278
        const V& operator -=(const V& v)
301
        const V& operator -=(const V& v)
279
        {
302
        {
280
            std::transform(begin(), end(), v.begin(), begin(), std::minus<T>());
303
            std::transform(begin(), end(), v.begin(), begin(), std::minus<T>());
281
            return  static_cast<const V&>(*this);
304
            return  static_cast<const V&>(*this);
282
        }
305
        }
283
        
306
        
284
        
307
        
285
        //----------------------------------------------------------------------
308
        //----------------------------------------------------------------------
286
        // Unary operators on vectors
309
        // Unary operators on vectors
287
        //----------------------------------------------------------------------
310
        //----------------------------------------------------------------------
288
        
311
        
289
        /// Negate vector.
312
        /// Negate vector.
290
        const V operator - () const
313
        const V operator - () const
291
        {
314
        {
292
            V v_new;
315
            V v_new;
293
            std::transform(begin(), end(), v_new.begin(), std::negate<T>());
316
            std::transform(begin(), end(), v_new.begin(), std::negate<T>());
294
            return v_new;
317
            return v_new;
295
        }
318
        }
296
        
319
        
297
        //----------------------------------------------------------------------
320
        //----------------------------------------------------------------------
298
        // Binary operators on vectors
321
        // Binary operators on vectors
299
        //----------------------------------------------------------------------
322
        //----------------------------------------------------------------------
300
        
323
        
301
        /** Multiply vector with vector. Each coord multiplied independently
324
        /** Multiply vector with vector. Each coord multiplied independently
302
         Do not confuse this operation with dot product. */
325
         Do not confuse this operation with dot product. */
303
        const V operator * (const V& v1) const
326
        const V operator * (const V& v1) const
304
        {
327
        {
305
            V v_new;
328
            V v_new;
306
            std::transform(begin(), end(), v1.begin(), v_new.begin(), std::multiplies<T>());
329
            std::transform(begin(), end(), v1.begin(), v_new.begin(), std::multiplies<T>());
307
            return v_new;
330
            return v_new;
308
        }
331
        }
309
        
332
        
310
        /// Add two vectors
333
        /// Add two vectors
311
        const V operator + (const V& v1) const
334
        const V operator + (const V& v1) const
312
        {
335
        {
313
            V v_new;
336
            V v_new;
314
            std::transform(begin(), end(), v1.begin(), v_new.begin(), std::plus<T>());
337
            std::transform(begin(), end(), v1.begin(), v_new.begin(), std::plus<T>());
315
            return v_new;
338
            return v_new;
316
        }
339
        }
317
        
340
        
318
        /// Subtract two vectors.
341
        /// Subtract two vectors.
319
        const V operator - (const V& v1) const
342
        const V operator - (const V& v1) const
320
        {
343
        {
321
            V v_new;
344
            V v_new;
322
            std::transform(begin(), end(), v1.begin(), v_new.begin(), std::minus<T>());
345
            std::transform(begin(), end(), v1.begin(), v_new.begin(), std::minus<T>());
323
            return v_new;
346
            return v_new;
324
        }
347
        }
325
        
348
        
326
        /// Divide two vectors. Each coord separately
349
        /// Divide two vectors. Each coord separately
327
        const V operator / (const V& v1) const
350
        const V operator / (const V& v1) const
328
        {
351
        {
329
            V v_new;
352
            V v_new;
330
            std::transform(begin(), end(), v1.begin(), v_new.begin(), std::divides<T>());
353
            std::transform(begin(), end(), v1.begin(), v_new.begin(), std::divides<T>());
331
            return v_new;
354
            return v_new;
332
        }
355
        }
333
        
356
        
334
        //----------------------------------------------------------------------
357
        //----------------------------------------------------------------------
335
        // Binary operators on vector and scalar
358
        // Binary operators on vector and scalar
336
        //----------------------------------------------------------------------
359
        //----------------------------------------------------------------------
337
        
360
        
338
        /// Multiply scalar onto vector.
361
        /// Multiply scalar onto vector.
339
        const V operator * (T k) const
362
        const V operator * (T k) const
340
        {
363
        {
341
            V v_new;
364
            V v_new;
342
            std::transform(begin(), end(), v_new.begin(), [k](T x){return x*k;});
365
            std::transform(begin(), end(), v_new.begin(), [k](T x){return x*k;});
343
            return v_new;
366
            return v_new;
344
        }
367
        }
345
        
368
        
346
        
369
        
347
        /// Divide vector by scalar.
370
        /// Divide vector by scalar.
348
        const V operator / (T k) const
371
        const V operator / (T k) const
349
        {
372
        {
350
            V v_new;
373
            V v_new;
351
            std::transform(begin(), end(), v_new.begin(), [k](T x){return x/k;});
374
            std::transform(begin(), end(), v_new.begin(), [k](T x){return x/k;});
352
            return v_new;
375
            return v_new;
353
        }
376
        }
354
        
377
        
355
        
378
        
356
        /// Return the smallest coordinate of the vector
379
        /// Return the smallest coordinate of the vector
357
        const T min_coord() const
380
        const T min_coord() const
358
        {
381
        {
359
            return *std::min_element(begin(), end());
382
            return *std::min_element(begin(), end());
360
        }
383
        }
361
        
384
        
362
        /// Return the largest coordinate of the vector
385
        /// Return the largest coordinate of the vector
363
        const T max_coord() const
386
        const T max_coord() const
364
        {
387
        {
365
            return *std::max_element(begin(), end());
388
            return *std::max_element(begin(), end());
366
        }
389
        }
367
        
390
        
368
    };
391
    };
369
    
392
    
370
    template <class T, class V, unsigned int N>
393
    template <class T, class V, unsigned int N>
371
    inline std::ostream& operator<<(std::ostream&os, const ArithVec<T,V,N>& v)
394
    inline std::ostream& operator<<(std::ostream&os, const ArithVec<T,V,N>& v)
372
    {
395
    {
373
        os << "[ ";
396
        os << "[ ";
374
        for(const T& x : v) os << x << " ";
397
        for(const T& x : v) os << x << " ";
375
        os << "]";
398
        os << "]";
376
        return os;
399
        return os;
377
        }
400
        }
378
        
401
        
379
        /// Get from operator for ArithVec descendants.
402
        /// Get from operator for ArithVec descendants.
380
        template <class T,class V, unsigned int N>
403
        template <class T,class V, unsigned int N>
381
        inline std::istream& operator>>(std::istream&is, ArithVec<T,V,N>& v)
404
        inline std::istream& operator>>(std::istream&is, ArithVec<T,V,N>& v)
382
        {
405
        {
383
            is >> std::ws;
406
            is >> std::ws;
384
            if (is.peek() == '[')
407
            if (is.peek() == '[')
385
                is.ignore();
408
                is.ignore();
386
            is >> std::ws;
409
            is >> std::ws;
387
            for (int c=0; c<N; ++c)
410
            for (int c=0; c<N; ++c)
388
            {
411
            {
389
                is >> v(c) >> std::ws;
412
                is >> v(c) >> std::ws;
390
            }
413
            }
391
            if (is.peek() == ']')
414
            if (is.peek() == ']')
392
                is.ignore();
415
                is.ignore();
393
            return is;
416
            return is;
394
        }
417
        }
395
        
418
        
396
        
419
        
397
        /** Dot product for two vectors. The `*' operator is
420
        /** Dot product for two vectors. The `*' operator is
398
         reserved for coordinatewise	multiplication of vectors. */
421
         reserved for coordinatewise	multiplication of vectors. */
399
        template <class T,class V, unsigned int N>
422
        template <class T,class V, unsigned int N>
400
        inline T dot(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
423
        inline T dot(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
401
        {
424
        {
402
            return std::inner_product(v0.begin(), v0.end(), v1.begin(), T(0));
425
            return std::inner_product(v0.begin(), v0.end(), v1.begin(), T(0));
403
        }
426
        }
404
        
427
        
405
        /** Compute the sqr length by taking dot product of vector with itself. */
428
        /** Compute the sqr length by taking dot product of vector with itself. */
406
        template <class T,class V, unsigned int N>
429
        template <class T,class V, unsigned int N>
407
        inline T sqr_length(const ArithVec<T,V,N>& v)
430
        inline T sqr_length(const ArithVec<T,V,N>& v)
408
        {
431
        {
409
            return dot(v,v);
432
            return dot(v,v);
410
        }
433
        }
411
        
434
        
412
        /** Multiply double onto vector. This operator handles the case
435
        /** Multiply double onto vector. This operator handles the case
413
         where the vector is on the righ side of the `*'.
436
         where the vector is on the righ side of the `*'.
414
         
437
         
415
         \note It seems to be optimal to put the binary operators inside the
438
         \note It seems to be optimal to put the binary operators inside the
416
         ArithVec class template, but the operator functions whose
439
         ArithVec class template, but the operator functions whose
417
         left operand is _not_ a vector cannot be inside, hence they
440
         left operand is _not_ a vector cannot be inside, hence they
418
         are here.
441
         are here.
419
         We need three operators for scalar * vector although they are
442
         We need three operators for scalar * vector although they are
420
         identical, because, if we use a separate template argument for
443
         identical, because, if we use a separate template argument for
421
         the left operand, it will match any type. If we use just T as
444
         the left operand, it will match any type. If we use just T as
422
         type for the left operand hoping that other built-in types will
445
         type for the left operand hoping that other built-in types will
423
         be automatically converted, we will be disappointed. It seems that
446
         be automatically converted, we will be disappointed. It seems that
424
         a float * ArithVec<float,Vec3f,3> function is not found if the
447
         a float * ArithVec<float,Vec3f,3> function is not found if the
425
         left operand is really a double.
448
         left operand is really a double.
426
         */
449
         */
427
        
450
        
428
        template<class T, class V, unsigned int N>
451
        template<class T, class V, unsigned int N>
429
        inline const V operator * (double k, const ArithVec<T,V,N>& v)
452
        inline const V operator * (double k, const ArithVec<T,V,N>& v)
430
        {
453
        {
431
            return v * k;
454
            return v * k;
432
        }
455
        }
433
        
456
        
434
        /** Multiply float onto vector. See the note in the documentation
457
        /** Multiply float onto vector. See the note in the documentation
435
         regarding multiplication of a double onto a vector. */
458
         regarding multiplication of a double onto a vector. */
436
        template<class T, class V, unsigned int N>
459
        template<class T, class V, unsigned int N>
437
        inline const V operator * (float k, const ArithVec<T,V,N>& v)
460
        inline const V operator * (float k, const ArithVec<T,V,N>& v)
438
        {
461
        {
439
            return v * k;
462
            return v * k;
440
        }
463
        }
441
        
464
        
442
        /** Multiply unsigned int onto vector. See the note in the documentation
465
        /** Multiply unsigned int onto vector. See the note in the documentation
443
         regarding multiplication of a double onto a vector. */
466
         regarding multiplication of a double onto a vector. */
444
        template<class T, class V, unsigned int N>
467
        template<class T, class V, unsigned int N>
445
        inline const V operator * (int k, const ArithVec<T,V,N>& v)
468
        inline const V operator * (int k, const ArithVec<T,V,N>& v)
446
        {
469
        {
447
            return v * k;
470
            return v * k;
448
        }
471
        }
449
        
472
        
450
        /** Returns the vector containing for each coordinate the smallest
473
        /** Returns the vector containing for each coordinate the smallest
451
         value from two vectors. */
474
         value from two vectors. */
452
        template <class T,class V, unsigned int N>
475
        template <class T,class V, unsigned int N>
453
        inline V v_min(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
476
        inline V v_min(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
454
        {
477
        {
455
            V v;
478
            V v;
456
            std::transform(v0.begin(), v0.end(), v1.begin(), v.begin(),
479
            std::transform(v0.begin(), v0.end(), v1.begin(), v.begin(),
457
                           [](T a, T b){return std::min(a,b);});
480
                           [](T a, T b){return std::min(a,b);});
458
            return v;
481
            return v;
459
        }
482
        }
460
        
483
        
461
        /** Returns the vector containing for each coordinate the largest
484
        /** Returns the vector containing for each coordinate the largest
462
         value from two vectors. */
485
         value from two vectors. */
463
        template <class T,class V, unsigned int N>
486
        template <class T,class V, unsigned int N>
464
        inline V v_max(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
487
        inline V v_max(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
465
        {
488
        {
466
            V v;
489
            V v;
467
            std::transform(v0.begin(), v0.end(), v1.begin(), v.begin(),
490
            std::transform(v0.begin(), v0.end(), v1.begin(), v.begin(),
468
                           [](T a, T b){return std::max(a,b);});
491
                           [](T a, T b){return std::max(a,b);});
469
            return v;
492
            return v;
470
        }
493
        }
471
        
494
        
472
        
495
        
473
}
496
}
474
        
497
        
475
#endif
498
#endif
476
 
499