Subversion Repositories gelsvn

Rev

Rev 634 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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