Subversion Repositories gelsvn

Rev

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

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