Subversion Repositories gelsvn

Rev

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

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