Subversion Repositories gelsvn

Rev

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

Rev 595 Rev 630
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 <iostream>
15
#include <iostream>
16
#include "CGLA.h"
16
#include "CGLA.h"
17
 
17
 
18
#include <numeric>
18
#include <numeric>
19
 
19
 
20
namespace CGLA 
20
namespace CGLA 
21
{
21
{
22
 
22
 
23
  /** \brief Template representing generic arithmetic vectors.  
23
  /** \brief Template representing generic arithmetic vectors.  
24
 
24
 
25
			The three parameters to the template are
25
			The three parameters to the template are
26
 
26
 
27
      T - the scalar type (i.e. float, int, double etc.)
27
      T - the scalar type (i.e. float, int, double etc.)
28
 
28
 
29
      V - the name of the vector type. This template is always (and
29
      V - the name of the vector type. This template is always (and
30
      only) used as ancestor of concrete types, and the name of the
30
      only) used as ancestor of concrete types, and the name of the
31
      class _inheriting_ _from_ this class is used as the V argument.
31
      class _inheriting_ _from_ this class is used as the V argument.
32
 
32
 
33
      N - The final argument is the dimension N. For instance, N=3 for a
33
      N - The final argument is the dimension N. For instance, N=3 for a
34
      3D vector.
34
      3D vector.
35
 
35
 
36
      This class template contains all functions that are assumed to be
36
      This class template contains all functions that are assumed to be
37
      the same for any arithmetic vector - regardless of dimension or
37
      the same for any arithmetic vector - regardless of dimension or
38
      the type of scalars used for coordinates.
38
      the type of scalars used for coordinates.
39
 
39
 
40
      The template contains no virtual functions which is important
40
      The template contains no virtual functions which is important
41
      since they add overhead.
41
      since they add overhead.
42
  */
42
  */
43
 
43
 
44
  template <class T, class V, unsigned int N> 
44
  template <class T, class V, unsigned int N> 
45
    class ArithVec
45
    class ArithVec
46
    {
46
    {
47
 
47
 
48
    protected:
48
    protected:
49
 
49
 
50
      /// The actual contents of the vector.
50
      /// The actual contents of the vector.
51
      T data[N];
51
      T data[N];
52
 
52
 
53
    protected:
53
    protected:
54
 
54
 
55
      //----------------------------------------------------------------------
55
      //----------------------------------------------------------------------
56
      // Constructors
56
      // Constructors
57
      //----------------------------------------------------------------------
57
      //----------------------------------------------------------------------
58
 
58
 
59
      /// Construct uninitialized vector
59
      /// Construct uninitialized vector
60
      ArithVec() 
60
      ArithVec() 
61
	{
61
	{
62
	}
62
	}
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
 
96
 
97
 
97
 
98
    public:
98
    public:
99
 
99
 
100
      /// For convenience we define a more meaningful name for the scalar type
100
      /// For convenience we define a more meaningful name for the scalar type
101
      typedef T ScalarType;
101
      typedef T ScalarType;
102
	
102
	
103
      /// A more meaningful name for vector type
103
      /// A more meaningful name for vector type
104
      typedef V VectorType;
104
      typedef V VectorType;
105
 
105
 
106
      /// Return dimension of vector
106
      /// Return dimension of vector
107
      static unsigned int get_dim() {return N;}
107
      static unsigned int get_dim() {return N;}
108
	
108
	
109
      /// Set all coordinates of a 2D vector.
109
      /// Set all coordinates of a 2D vector.
110
      void set(T _a, T _b)
110
      void set(T _a, T _b)
111
	{
111
	{
112
	  assert(N==2);
112
	  assert(N==2);
113
	  data[0] = _a;
113
	  data[0] = _a;
114
	  data[1] = _b;
114
	  data[1] = _b;
115
	}
115
	}
116
 
116
 
117
      /// Set all coordinates of a 3D vector.
117
      /// Set all coordinates of a 3D vector.
118
      void set(T _a, T _b, T _c)
118
      void set(T _a, T _b, T _c)
119
	{
119
	{
120
	  assert(N==3);
120
	  assert(N==3);
121
	  data[0] = _a;
121
	  data[0] = _a;
122
	  data[1] = _b;
122
	  data[1] = _b;
123
	  data[2] = _c;
123
	  data[2] = _c;
124
	}
124
	}
125
 
125
 
126
      /// Set all coordinates of a 4D vector.
126
      /// Set all coordinates of a 4D vector.
127
      void set(T _a, T _b, T _c, T _d)
127
      void set(T _a, T _b, T _c, T _d)
128
	{
128
	{
129
	  assert(N==4);
129
	  assert(N==4);
130
	  data[0] = _a;
130
	  data[0] = _a;
131
	  data[1] = _b;
131
	  data[1] = _b;
132
	  data[2] = _c;
132
	  data[2] = _c;
133
	  data[3] = _d;
133
	  data[3] = _d;
134
	}
134
	}
135
 
135
 
136
  /// Const index operator
136
  /// Const index operator
137
  const T& operator [] ( unsigned int i ) const
137
  const T& operator [] ( unsigned int i ) const
138
	{
138
	{
139
	  assert(i<N);
139
	  assert(i<N);
140
	  return data[i];
140
	  return data[i];
141
	}
141
	}
142
 
142
 
143
  /// Non-const index operator
143
  /// Non-const index operator
144
  T& operator [] ( unsigned int i ) 
144
  T& operator [] ( unsigned int i ) 
145
	{
145
	{
146
	  assert(i<N);
146
	  assert(i<N);
147
	  return data[i];
147
	  return data[i];
148
	}
148
	}
149
 
149
 
150
	/// Const index operator
150
	/// Const index operator
151
  const T& operator () ( unsigned int i ) const
151
  const T& operator () ( unsigned int i ) const
152
	{
152
	{
153
	  assert(i<N);
153
	  assert(i<N);
154
	  return data[i];
154
	  return data[i];
155
	}
155
	}
156
 
156
 
157
  /// Non-const index operator
157
  /// Non-const index operator
158
  T& operator () ( unsigned int i ) 
158
  T& operator () ( unsigned int i ) 
159
	{
159
	{
160
	  assert(i<N);
160
	  assert(i<N);
161
	  return data[i];
161
	  return data[i];
162
	}
162
	}
163
 
163
 
164
 
164
 
165
      /** Get a pointer to first element in data array.
165
      /** Get a pointer to first element in data array.
166
	  This function may be useful when interfacing with some other API 
166
	  This function may be useful when interfacing with some other API 
167
	  such as OpenGL (TM) */
167
	  such as OpenGL (TM) */
168
      T* get() {return &data[0];}
168
      T* get() {return &data[0];}
169
 
169
 
170
      /** Get a const pointer to first element in data array.
170
      /** Get a const pointer to first element in data array.
171
	  This function may be useful when interfacing with some other API 
171
	  This function may be useful when interfacing with some other API 
172
	  such as OpenGL (TM). */
172
	  such as OpenGL (TM). */
173
      const T* get() const {return &data[0];}
173
      const T* get() const {return &data[0];}
174
 
174
 
175
      //----------------------------------------------------------------------
175
      //----------------------------------------------------------------------
176
      // Comparison operators
176
      // Comparison operators
177
      //----------------------------------------------------------------------
177
      //----------------------------------------------------------------------
178
 
178
 
179
      /// Equality operator
179
      /// Equality operator
180
      bool operator==(const V& v) const 
180
      bool operator==(const V& v) const 
181
	{
181
	{
182
	  return std::inner_product(data, &data[N], v.get(), true,
182
	  return std::inner_product(data, &data[N], v.get(), true,
183
				    std::logical_and<bool>(), std::equal_to<T>());
183
				    std::logical_and<bool>(), std::equal_to<T>());
184
	}
184
	}
185
 
185
 
186
#define for_all_i(expr) for(unsigned int i=0;i<N;i++) {expr;}
186
#define for_all_i(expr) for(unsigned int i=0;i<N;i++) {expr;}
187
      /// Equality wrt scalar. True if all coords are equal to scalar
187
      /// Equality wrt scalar. True if all coords are equal to scalar
188
      bool operator==(T k) const 
188
      bool operator==(T k) const 
189
	{ 
189
	{ 
190
	  for_all_i(if (data[i] != k) return false)
190
	  for_all_i(if (data[i] != k) return false)
191
	    return true;
191
	    return true;
192
	}
192
	}
193
#undef for_all_i  
193
#undef for_all_i  
194
 
194
 
195
      /// Inequality operator
195
      /// Inequality operator
196
      bool operator!=(const V& v) const 
196
      bool operator!=(const V& v) const 
197
	{
197
	{
198
	  return std::inner_product(data, &data[N], v.get(), false,
198
	  return std::inner_product(data, &data[N], v.get(), false,
199
				    std::logical_or<bool>(), std::not_equal_to<T>());
199
				    std::logical_or<bool>(), std::not_equal_to<T>());
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(data, &data[N], v.get(), true, 
217
	  return std::inner_product(data, &data[N], v.get(), 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(data, &data[N], v.get(), true, 
225
	  return std::inner_product(data, &data[N], v.get(), 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(data, &data[N], v.get(), true, 
233
	  return std::inner_product(data, &data[N], v.get(), 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(data, &data[N], v.get(), true, 
241
	  return std::inner_product(data, &data[N], v.get(), 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
	  std::transform(data, &data[N], data, std::bind2nd(std::multiplies<T>(), k));
253
	  std::transform(data, &data[N], data, std::bind2nd(std::multiplies<T>(), 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
	  std::transform(data, &data[N], data, std::bind2nd(std::divides<T>(), k));
260
	  std::transform(data, &data[N], data, std::bind2nd(std::divides<T>(), 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
	  std::transform(data, &data[N], data, std::bind2nd(std::plus<T>(), k));
267
	  std::transform(data, &data[N], data, std::bind2nd(std::plus<T>(), 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
	  std::transform(data, &data[N], data, std::bind2nd(std::minus<T>(), k));
274
	  std::transform(data, &data[N], data, std::bind2nd(std::minus<T>(), 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(data, &data[N], v.get(), data, std::multiplies<T>());
282
	  std::transform(data, &data[N], v.get(), data, 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(data, &data[N], v.get(), data, std::divides<T>());
289
	  std::transform(data, &data[N], v.get(), data, 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(data, &data[N], v.get(), data, std::plus<T>());
296
	  std::transform(data, &data[N], v.get(), data, 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(data, &data[N], v.get(), data, std::minus<T>());
303
	  std::transform(data, &data[N], v.get(), data, 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(data, &data[N], v_new.get(), std::negate<T>());
316
	  std::transform(data, &data[N], v_new.get(), 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(data, &data[N], v1.get(), v_new.get(), std::multiplies<T>());
329
	  std::transform(data, &data[N], v1.get(), v_new.get(), 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(data, &data[N], v1.get(), v_new.get(), std::plus<T>());
337
	  std::transform(data, &data[N], v1.get(), v_new.get(), 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(data, &data[N], v1.get(), v_new.get(), std::minus<T>());
345
	  std::transform(data, &data[N], v1.get(), v_new.get(), 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(data, &data[N], v1.get(), v_new.get(), std::divides<T>());
353
	  std::transform(data, &data[N], v1.get(), v_new.get(), 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(data, &data[N], v_new.get(), std::bind2nd(std::multiplies<T>(), k));
365
	  std::transform(data, &data[N], v_new.get(), std::bind2nd(std::multiplies<T>(), 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(data, &data[N], v_new.get(), std::bind2nd(std::divides<T>(), k));
374
	  std::transform(data, &data[N], v_new.get(), std::bind2nd(std::divides<T>(), 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(data, &data[N]);
382
	  return *std::min_element(data, &data[N]);
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(data, &data[N]);
388
	  return *std::max_element(data, &data[N]);
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(unsigned int i=0;i<N;i++) os << v[i] << " ";
397
      for(unsigned int i=0;i<N;i++) os << v[i] << " ";
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.get(), v0.get() + N, v1.get(), T(0));
425
      return std::inner_product(v0.get(), v0.get() + N, v1.get(), 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.get(), v0.get() + N, v1.get(), v.get(), std::ptr_fun(s_min<T>));
479
      std::transform(v0.get(), v0.get() + N, v1.get(), v.get(), std::ptr_fun(s_min<T>));
480
      return v;
480
      return v;
481
    }
481
    }
482
 
482
 
483
  /** Returns the vector containing for each coordinate the largest 
483
  /** Returns the vector containing for each coordinate the largest 
484
      value from two vectors. */
484
      value from two vectors. */
485
  template <class T,class V, unsigned int N>
485
  template <class T,class V, unsigned int N>
486
    inline V v_max(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
486
    inline V v_max(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
487
    {
487
    {
488
      V v;
488
      V v;
489
      std::transform(v0.get(), v0.get() + N, v1.get(), v.get(), std::ptr_fun(s_max<T>));
489
      std::transform(v0.get(), v0.get() + N, v1.get(), v.get(), std::ptr_fun(s_max<T>));
490
      return v;
490
      return v;
491
    }
491
    }
492
 
492
 
493
 
493
 
494
}
494
}
495
 
495
 
496
#endif
496
#endif
497
 
497