3 * Copyright (c) 2007-2010 SlimDX Group
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
\r
6 * of this software and associated documentation files (the "Software"), to deal
\r
7 * in the Software without restriction, including without limitation the rights
\r
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
9 * copies of the Software, and to permit persons to whom the Software is
\r
10 * furnished to do so, subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in
\r
13 * all copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
27 #include "Quaternion.h"
\r
28 #include "Vector2.h"
\r
30 using namespace System;
\r
31 using namespace System::Globalization;
\r
35 Vector2::Vector2( float value )
\r
41 Vector2::Vector2( float x, float y )
\r
47 float Vector2::default::get( int index )
\r
58 throw gcnew ArgumentOutOfRangeException( "index", "Indices for Vector2 run from 0 to 1, inclusive." );
\r
62 void Vector2::default::set( int index, float value )
\r
75 throw gcnew ArgumentOutOfRangeException( "index", "Indices for Vector2 run from 0 to 1, inclusive." );
\r
79 float Vector2::Length()
\r
81 return static_cast<float>( Math::Sqrt( (X * X) + (Y * Y) ) );
\r
84 float Vector2::LengthSquared()
\r
86 return (X * X) + (Y * Y);
\r
89 void Vector2::Normalize()
\r
91 float length = Length();
\r
94 float num = 1 / length;
\r
99 Vector2 Vector2::Add( Vector2 left, Vector2 right )
\r
101 return Vector2( left.X + right.X, left.Y + right.Y );
\r
104 void Vector2::Add( Vector2% left, Vector2% right, [Out] Vector2% result )
\r
106 result = Vector2( left.X + right.X, left.Y + right.Y );
\r
109 Vector2 Vector2::Subtract( Vector2 left, Vector2 right )
\r
111 return Vector2( left.X - right.X, left.Y - right.Y );
\r
114 void Vector2::Subtract( Vector2% left, Vector2% right, [Out] Vector2% result )
\r
116 result = Vector2( left.X - right.X, left.Y - right.Y );
\r
119 Vector2 Vector2::Modulate( Vector2 left, Vector2 right )
\r
121 return Vector2( left.X * right.X, left.Y * right.Y );
\r
124 void Vector2::Modulate( Vector2% left, Vector2% right, [Out] Vector2% result )
\r
126 result = Vector2( left.X * right.X, left.Y * right.Y );
\r
129 Vector2 Vector2::Multiply( Vector2 value, float scale )
\r
131 return Vector2( value.X * scale, value.Y * scale );
\r
134 void Vector2::Multiply( Vector2% value, float scale, [Out] Vector2% result )
\r
136 result = Vector2( value.X * scale, value.Y * scale );
\r
139 Vector2 Vector2::Divide( Vector2 value, float scale )
\r
141 return Vector2( value.X / scale, value.Y / scale );
\r
144 void Vector2::Divide( Vector2% value, float scale, [Out] Vector2% result )
\r
146 result = Vector2( value.X / scale, value.Y / scale );
\r
149 Vector2 Vector2::Negate( Vector2 value )
\r
151 return Vector2( -value.X, -value.Y );
\r
154 void Vector2::Negate( Vector2% value, [Out] Vector2% result )
\r
156 result = Vector2( -value.X, -value.Y );
\r
159 Vector2 Vector2::Barycentric( Vector2 value1, Vector2 value2, Vector2 value3, float amount1, float amount2 )
\r
162 vector.X = (value1.X + (amount1 * (value2.X - value1.X))) + (amount2 * (value3.X - value1.X));
\r
163 vector.Y = (value1.Y + (amount1 * (value2.Y - value1.Y))) + (amount2 * (value3.Y - value1.Y));
\r
167 void Vector2::Barycentric( Vector2% value1, Vector2% value2, Vector2% value3, float amount1, float amount2, [Out] Vector2% result )
\r
169 result = Vector2((value1.X + (amount1 * (value2.X - value1.X))) + (amount2 * (value3.X - value1.X)),
\r
170 (value1.Y + (amount1 * (value2.Y - value1.Y))) + (amount2 * (value3.Y - value1.Y)) );
\r
173 Vector2 Vector2::CatmullRom( Vector2 value1, Vector2 value2, Vector2 value3, Vector2 value4, float amount )
\r
176 float squared = amount * amount;
\r
177 float cubed = amount * squared;
\r
179 vector.X = 0.5f * ((((2.0f * value2.X) + ((-value1.X + value3.X) * amount)) +
\r
180 (((((2.0f * value1.X) - (5.0f * value2.X)) + (4.0f * value3.X)) - value4.X) * squared)) +
\r
181 ((((-value1.X + (3.0f * value2.X)) - (3.0f * value3.X)) + value4.X) * cubed));
\r
183 vector.Y = 0.5f * ((((2.0f * value2.Y) + ((-value1.Y + value3.Y) * amount)) +
\r
184 (((((2.0f * value1.Y) - (5.0f * value2.Y)) + (4.0f * value3.Y)) - value4.Y) * squared)) +
\r
185 ((((-value1.Y + (3.0f * value2.Y)) - (3.0f * value3.Y)) + value4.Y) * cubed));
\r
190 void Vector2::CatmullRom( Vector2% value1, Vector2% value2, Vector2% value3, Vector2% value4, float amount, [Out] Vector2% result )
\r
192 float squared = amount * amount;
\r
193 float cubed = amount * squared;
\r
196 r.X = 0.5f * ((((2.0f * value2.X) + ((-value1.X + value3.X) * amount)) +
\r
197 (((((2.0f * value1.X) - (5.0f * value2.X)) + (4.0f * value3.X)) - value4.X) * squared)) +
\r
198 ((((-value1.X + (3.0f * value2.X)) - (3.0f * value3.X)) + value4.X) * cubed));
\r
200 r.Y = 0.5f * ((((2.0f * value2.Y) + ((-value1.Y + value3.Y) * amount)) +
\r
201 (((((2.0f * value1.Y) - (5.0f * value2.Y)) + (4.0f * value3.Y)) - value4.Y) * squared)) +
\r
202 ((((-value1.Y + (3.0f * value2.Y)) - (3.0f * value3.Y)) + value4.Y) * cubed));
\r
207 Vector2 Vector2::Clamp( Vector2 value, Vector2 min, Vector2 max )
\r
210 x = (x > max.X) ? max.X : x;
\r
211 x = (x < min.X) ? min.X : x;
\r
214 y = (y > max.Y) ? max.Y : y;
\r
215 y = (y < min.Y) ? min.Y : y;
\r
217 return Vector2( x, y );
\r
220 void Vector2::Clamp( Vector2% value, Vector2% min, Vector2% max, [Out] Vector2% result )
\r
223 x = (x > max.X) ? max.X : x;
\r
224 x = (x < min.X) ? min.X : x;
\r
227 y = (y > max.Y) ? max.Y : y;
\r
228 y = (y < min.Y) ? min.Y : y;
\r
230 result = Vector2( x, y );
\r
233 Vector2 Vector2::Hermite( Vector2 value1, Vector2 tangent1, Vector2 value2, Vector2 tangent2, float amount )
\r
236 float squared = amount * amount;
\r
237 float cubed = amount * squared;
\r
238 float part1 = ((2.0f * cubed) - (3.0f * squared)) + 1.0f;
\r
239 float part2 = (-2.0f * cubed) + (3.0f * squared);
\r
240 float part3 = (cubed - (2.0f * squared)) + amount;
\r
241 float part4 = cubed - squared;
\r
243 vector.X = (((value1.X * part1) + (value2.X * part2)) + (tangent1.X * part3)) + (tangent2.X * part4);
\r
244 vector.Y = (((value1.Y * part1) + (value2.Y * part2)) + (tangent1.Y * part3)) + (tangent2.Y * part4);
\r
249 void Vector2::Hermite( Vector2% value1, Vector2% tangent1, Vector2% value2, Vector2% tangent2, float amount, [Out] Vector2% result )
\r
251 float squared = amount * amount;
\r
252 float cubed = amount * squared;
\r
253 float part1 = ((2.0f * cubed) - (3.0f * squared)) + 1.0f;
\r
254 float part2 = (-2.0f * cubed) + (3.0f * squared);
\r
255 float part3 = (cubed - (2.0f * squared)) + amount;
\r
256 float part4 = cubed - squared;
\r
259 r.X = (((value1.X * part1) + (value2.X * part2)) + (tangent1.X * part3)) + (tangent2.X * part4);
\r
260 r.Y = (((value1.Y * part1) + (value2.Y * part2)) + (tangent1.Y * part3)) + (tangent2.Y * part4);
\r
265 Vector2 Vector2::Lerp( Vector2 start, Vector2 end, float factor )
\r
269 vector.X = start.X + ((end.X - start.X) * factor);
\r
270 vector.Y = start.Y + ((end.Y - start.Y) * factor);
\r
275 void Vector2::Lerp( Vector2% start, Vector2% end, float factor, [Out] Vector2% result )
\r
278 r.X = start.X + ((end.X - start.X) * factor);
\r
279 r.Y = start.Y + ((end.Y - start.Y) * factor);
\r
284 Vector2 Vector2::SmoothStep( Vector2 start, Vector2 end, float amount )
\r
288 amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount);
\r
289 amount = (amount * amount) * (3.0f - (2.0f * amount));
\r
291 vector.X = start.X + ((end.X - start.X) * amount);
\r
292 vector.Y = start.Y + ((end.Y - start.Y) * amount);
\r
297 void Vector2::SmoothStep( Vector2% start, Vector2% end, float amount, [Out] Vector2% result )
\r
299 amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount);
\r
300 amount = (amount * amount) * (3.0f - (2.0f * amount));
\r
303 r.X = start.X + ((end.X - start.X) * amount);
\r
304 r.Y = start.Y + ((end.Y - start.Y) * amount);
\r
309 float Vector2::Distance( Vector2 value1, Vector2 value2 )
\r
311 float x = value1.X - value2.X;
\r
312 float y = value1.Y - value2.Y;
\r
314 return static_cast<float>( Math::Sqrt( (x * x) + (y * y) ) );
\r
317 float Vector2::DistanceSquared( Vector2 value1, Vector2 value2 )
\r
319 float x = value1.X - value2.X;
\r
320 float y = value1.Y - value2.Y;
\r
322 return (x * x) + (y * y);
\r
325 float Vector2::Dot( Vector2 left, Vector2 right )
\r
327 return (left.X * right.X + left.Y * right.Y);
\r
330 Vector2 Vector2::Normalize( Vector2 vector )
\r
332 vector.Normalize();
\r
336 void Vector2::Normalize( Vector2% vector, [Out] Vector2% result )
\r
338 result = Vector2::Normalize(vector);
\r
341 Vector4 Vector2::Transform( Vector2 vector, Matrix transform )
\r
345 result.X = (vector.X * transform.M11) + (vector.Y * transform.M21) + transform.M41;
\r
346 result.Y = (vector.X * transform.M12) + (vector.Y * transform.M22) + transform.M42;
\r
347 result.Z = (vector.X * transform.M13) + (vector.Y * transform.M23) + transform.M43;
\r
348 result.W = (vector.X * transform.M14) + (vector.Y * transform.M24) + transform.M44;
\r
353 void Vector2::Transform( Vector2% vector, Matrix% transform, [Out] Vector4% result )
\r
356 r.X = (vector.X * transform.M11) + (vector.Y * transform.M21) + transform.M41;
\r
357 r.Y = (vector.X * transform.M12) + (vector.Y * transform.M22) + transform.M42;
\r
358 r.Z = (vector.X * transform.M13) + (vector.Y * transform.M23) + transform.M43;
\r
359 r.W = (vector.X * transform.M14) + (vector.Y * transform.M24) + transform.M44;
\r
364 array<Vector4>^ Vector2::Transform( array<Vector2>^ vectors, Matrix% transform )
\r
366 if( vectors == nullptr )
\r
367 throw gcnew ArgumentNullException( "vectors" );
\r
369 int count = vectors->Length;
\r
370 array<Vector4>^ results = gcnew array<Vector4>( count );
\r
372 for( int i = 0; i < count; i++ )
\r
375 r.X = (vectors[i].X * transform.M11) + (vectors[i].Y * transform.M21) + transform.M41;
\r
376 r.Y = (vectors[i].X * transform.M12) + (vectors[i].Y * transform.M22) + transform.M42;
\r
377 r.Z = (vectors[i].X * transform.M13) + (vectors[i].Y * transform.M23) + transform.M43;
\r
378 r.W = (vectors[i].X * transform.M14) + (vectors[i].Y * transform.M24) + transform.M44;
\r
386 Vector4 Vector2::Transform( Vector2 value, Quaternion rotation )
\r
389 float x = rotation.X + rotation.X;
\r
390 float y = rotation.Y + rotation.Y;
\r
391 float z = rotation.Z + rotation.Z;
\r
392 float wx = rotation.W * x;
\r
393 float wy = rotation.W * y;
\r
394 float wz = rotation.W * z;
\r
395 float xx = rotation.X * x;
\r
396 float xy = rotation.X * y;
\r
397 float xz = rotation.X * z;
\r
398 float yy = rotation.Y * y;
\r
399 float yz = rotation.Y * z;
\r
400 float zz = rotation.Z * z;
\r
402 vector.X = ((value.X * ((1.0f - yy) - zz)) + (value.Y * (xy - wz)));
\r
403 vector.Y = ((value.X * (xy + wz)) + (value.Y * ((1.0f - xx) - zz)));
\r
404 vector.Z = ((value.X * (xz - wy)) + (value.Y * (yz + wx)));
\r
410 void Vector2::Transform( Vector2% value, Quaternion% rotation, [Out] Vector4% result )
\r
412 float x = rotation.X + rotation.X;
\r
413 float y = rotation.Y + rotation.Y;
\r
414 float z = rotation.Z + rotation.Z;
\r
415 float wx = rotation.W * x;
\r
416 float wy = rotation.W * y;
\r
417 float wz = rotation.W * z;
\r
418 float xx = rotation.X * x;
\r
419 float xy = rotation.X * y;
\r
420 float xz = rotation.X * z;
\r
421 float yy = rotation.Y * y;
\r
422 float yz = rotation.Y * z;
\r
423 float zz = rotation.Z * z;
\r
426 r.X = ((value.X * ((1.0f - yy) - zz)) + (value.Y * (xy - wz)));
\r
427 r.Y = ((value.X * (xy + wz)) + (value.Y * ((1.0f - xx) - zz)));
\r
428 r.Z = ((value.X * (xz - wy)) + (value.Y * (yz + wx)));
\r
434 array<Vector4>^ Vector2::Transform( array<Vector2>^ vectors, Quaternion% rotation )
\r
436 if( vectors == nullptr )
\r
437 throw gcnew ArgumentNullException( "vectors" );
\r
439 int count = vectors->Length;
\r
440 array<Vector4>^ results = gcnew array<Vector4>( count );
\r
442 float x = rotation.X + rotation.X;
\r
443 float y = rotation.Y + rotation.Y;
\r
444 float z = rotation.Z + rotation.Z;
\r
445 float wx = rotation.W * x;
\r
446 float wy = rotation.W * y;
\r
447 float wz = rotation.W * z;
\r
448 float xx = rotation.X * x;
\r
449 float xy = rotation.X * y;
\r
450 float xz = rotation.X * z;
\r
451 float yy = rotation.Y * y;
\r
452 float yz = rotation.Y * z;
\r
453 float zz = rotation.Z * z;
\r
455 for( int i = 0; i < count; i++ )
\r
458 r.X = ((vectors[i].X * ((1.0f - yy) - zz)) + (vectors[i].Y * (xy - wz)));
\r
459 r.Y = ((vectors[i].X * (xy + wz)) + (vectors[i].Y * ((1.0f - xx) - zz)));
\r
460 r.Z = ((vectors[i].X * (xz - wy)) + (vectors[i].Y * (yz + wx)));
\r
469 Vector2 Vector2::TransformCoordinate( Vector2 coord, Matrix transform )
\r
473 vector.X = (coord.X * transform.M11) + (coord.Y * transform.M21) + transform.M41;
\r
474 vector.Y = (coord.X * transform.M12) + (coord.Y * transform.M22) + transform.M42;
\r
475 vector.Z = (coord.X * transform.M13) + (coord.Y * transform.M23) + transform.M43;
\r
476 vector.W = 1 / ((coord.X * transform.M14) + (coord.Y * transform.M24) + transform.M44);
\r
478 return Vector2( vector.X * vector.W, vector.Y * vector.W );
\r
481 void Vector2::TransformCoordinate( Vector2% coord, Matrix% transform, [Out] Vector2% result )
\r
485 vector.X = (coord.X * transform.M11) + (coord.Y * transform.M21) + transform.M41;
\r
486 vector.Y = (coord.X * transform.M12) + (coord.Y * transform.M22) + transform.M42;
\r
487 vector.Z = (coord.X * transform.M13) + (coord.Y * transform.M23) + transform.M43;
\r
488 vector.W = 1 / ((coord.X * transform.M14) + (coord.Y * transform.M24) + transform.M44);
\r
490 result = Vector2( vector.X * vector.W, vector.Y * vector.W );
\r
493 array<Vector2>^ Vector2::TransformCoordinate( array<Vector2>^ coords, Matrix% transform )
\r
495 if( coords == nullptr )
\r
496 throw gcnew ArgumentNullException( "coordinates" );
\r
499 int count = coords->Length;
\r
500 array<Vector2>^ results = gcnew array<Vector2>( count );
\r
502 for( int i = 0; i < count; i++ )
\r
504 vector.X = (coords[i].X * transform.M11) + (coords[i].Y * transform.M21) + transform.M41;
\r
505 vector.Y = (coords[i].X * transform.M12) + (coords[i].Y * transform.M22) + transform.M42;
\r
506 vector.Z = (coords[i].X * transform.M13) + (coords[i].Y * transform.M23) + transform.M43;
\r
507 vector.W = 1 / ((coords[i].X * transform.M14) + (coords[i].Y * transform.M24) + transform.M44);
\r
508 results[i] = Vector2( vector.X * vector.W, vector.Y * vector.W );
\r
514 Vector2 Vector2::TransformNormal( Vector2 normal, Matrix transform )
\r
518 vector.X = (normal.X * transform.M11) + (normal.Y * transform.M21);
\r
519 vector.Y = (normal.X * transform.M12) + (normal.Y * transform.M22);
\r
524 void Vector2::TransformNormal( Vector2% normal, Matrix% transform, [Out] Vector2% result )
\r
527 r.X = (normal.X * transform.M11) + (normal.Y * transform.M21);
\r
528 r.Y = (normal.X * transform.M12) + (normal.Y * transform.M22);
\r
533 array<Vector2>^ Vector2::TransformNormal( array<Vector2>^ normals, Matrix% transform )
\r
535 if( normals == nullptr )
\r
536 throw gcnew ArgumentNullException( "normals" );
\r
538 int count = normals->Length;
\r
539 array<Vector2>^ results = gcnew array<Vector2>( count );
\r
541 for( int i = 0; i < count; i++ )
\r
544 r.X = (normals[i].X * transform.M11) + (normals[i].Y * transform.M21);
\r
545 r.Y = (normals[i].X * transform.M12) + (normals[i].Y * transform.M22);
\r
553 Vector2 Vector2::Minimize( Vector2 left, Vector2 right )
\r
556 vector.X = (left.X < right.X) ? left.X : right.X;
\r
557 vector.Y = (left.Y < right.Y) ? left.Y : right.Y;
\r
561 void Vector2::Minimize( Vector2% left, Vector2% right, [Out] Vector2% result )
\r
564 r.X = (left.X < right.X) ? left.X : right.X;
\r
565 r.Y = (left.Y < right.Y) ? left.Y : right.Y;
\r
570 Vector2 Vector2::Maximize( Vector2 left, Vector2 right )
\r
573 vector.X = (left.X > right.X) ? left.X : right.X;
\r
574 vector.Y = (left.Y > right.Y) ? left.Y : right.Y;
\r
578 void Vector2::Maximize( Vector2% left, Vector2% right, [Out] Vector2% result )
\r
581 r.X = (left.X > right.X) ? left.X : right.X;
\r
582 r.Y = (left.Y > right.Y) ? left.Y : right.Y;
\r
587 Vector2 Vector2::operator + ( Vector2 left, Vector2 right )
\r
589 return Vector2( left.X + right.X, left.Y + right.Y );
\r
592 Vector2 Vector2::operator - ( Vector2 left, Vector2 right )
\r
594 return Vector2( left.X - right.X, left.Y - right.Y );
\r
597 Vector2 Vector2::operator - ( Vector2 value )
\r
599 return Vector2( -value.X, -value.Y );
\r
602 Vector2 Vector2::operator * ( Vector2 value, float scale )
\r
604 return Vector2( value.X * scale, value.Y * scale );
\r
607 Vector2 Vector2::operator * ( float scale, Vector2 vec )
\r
609 return vec * scale;
\r
612 Vector2 Vector2::operator / ( Vector2 value, float scale )
\r
614 return Vector2( value.X / scale, value.Y / scale );
\r
617 bool Vector2::operator == ( Vector2 left, Vector2 right )
\r
619 return Vector2::Equals( left, right );
\r
622 bool Vector2::operator != ( Vector2 left, Vector2 right )
\r
624 return !Vector2::Equals( left, right );
\r
627 String^ Vector2::ToString()
\r
629 return String::Format( CultureInfo::CurrentCulture, "X:{0} Y:{1}", X.ToString(CultureInfo::CurrentCulture), Y.ToString(CultureInfo::CurrentCulture) );
\r
632 int Vector2::GetHashCode()
\r
634 return X.GetHashCode() + Y.GetHashCode();
\r
637 bool Vector2::Equals( Object^ value )
\r
639 if( value == nullptr )
\r
642 if( value->GetType() != GetType() )
\r
645 return Equals( safe_cast<Vector2>( value ) );
\r
648 bool Vector2::Equals( Vector2 value )
\r
650 return ( X == value.X && Y == value.Y );
\r
653 bool Vector2::Equals( Vector2% value1, Vector2% value2 )
\r
655 return ( value1.X == value2.X && value1.Y == value2.Y );
\r