Subversion Repositories gelsvn

Rev

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

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