Subversion Repositories gelsvn

Rev

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

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