Subversion Repositories gelsvn

Rev

Rev 10 | Rev 43 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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