1: /*
2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
3:
4: Permission is hereby granted, free of charge, to any person obtaining a copy
5: of this software and associated documentation files (the "Software"), to deal
6: in the Software without restriction, including without limitation the rights
7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: copies of the Software, and to permit persons to whom the Software is
9: furnished to do so, subject to the following conditions:
10:
11: The above copyright notice and this permission notice shall be included in
12: all copies or substantial portions of the Software.
13:
14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: THE SOFTWARE.*/
21: #region Usings
22: using System;
23: using System.Xml.Serialization;
24: #endregion
25:
26: namespace Utilities.Math
27: {
28: /// <summary>
29: /// Vector class (holds three items)
30: /// </summary>
31: [Serializable()]
32: public class Vector3
33: {
34: #region Constructor
35:
36: /// <summary>
37: /// Constructor
38: /// </summary>
39: /// <param name="X">X direction</param>
40: /// <param name="Y">Y direction</param>
41: /// <param name="Z">Z direction</param>
42: public Vector3(double X, double Y, double Z)
43: {
44: this.X = X;
45: this.Y = Y;
46: this.Z = Z;
47: }
48:
49: #endregion
50:
51: #region Public Functions
52:
53: /// <summary>
54: /// Normalizes the vector
55: /// </summary>
56: public void Normalize()
57: {
58: double Normal = Magnitude;
59: if (Normal > 0)
60: {
61: Normal = 1 / Normal;
62: X *= Normal;
63: Y *= Normal;
64: Z *= Normal;
65: }
66: }
67:
68: #endregion
69:
70: #region Public Overridden Functions
71:
72: /// <summary>
73: /// To string function
74: /// </summary>
75: /// <returns>String representation of the vector</returns>
76: public override string ToString()
77: {
78: return "(" + X + "," + Y + "," + Z + ")";
79: }
80:
81: /// <summary>
82: /// Gets the hash code
83: /// </summary>
84: /// <returns>The hash code</returns>
85: public override int GetHashCode()
86: {
87: return (int)(X + Y + Z) % Int32.MaxValue;
88: }
89:
90: /// <summary>
91: /// Determines if the items are equal
92: /// </summary>
93: /// <param name="obj">Object to compare</param>
94: /// <returns>true if they are, false otherwise</returns>
95: public override bool Equals(object obj)
96: {
97: if (obj is Vector3)
98: {
99: return this == (Vector3)obj;
100: }
101: return false;
102: }
103:
104: #endregion
105:
106: #region Public Properties
107:
108: /// <summary>
109: /// Used for converting this to an array and back
110: /// </summary>
111: public double[] Array
112: {
113: get { return new double[] { X, Y, Z }; }
114: set
115: {
116: if (value.Length == 3)
117: {
118: X = value[0];
119: Y = value[1];
120: Z = value[2];
121: }
122: }
123: }
124:
125: /// <summary>
126: /// Returns the magnitude of the vector
127: /// </summary>
128: public double Magnitude
129: {
130: get { return System.Math.Sqrt((X * X) + (Y * Y) + (Z * Z)); }
131: }
132:
133: /// <summary>
134: /// X value
135: /// </summary>
136: [XmlElement]
137: public double X { get; set; }
138:
139: /// <summary>
140: /// Y Value
141: /// </summary>
142: [XmlElement]
143: public double Y { get; set; }
144:
145: /// <summary>
146: /// Z value
147: /// </summary>
148: [XmlElement]
149: public double Z { get; set; }
150:
151: #endregion
152:
153: #region Public Static Functions
154:
155: public static Vector3 operator +(Vector3 V1, Vector3 V2)
156: {
157: return new Vector3(V1.X + V2.X, V1.Y + V2.Y, V1.Z + V2.Z);
158: }
159:
160: public static Vector3 operator -(Vector3 V1, Vector3 V2)
161: {
162: return new Vector3(V1.X - V2.X, V1.Y - V2.Y, V1.Z - V2.Z);
163: }
164:
165: public static Vector3 operator -(Vector3 V1)
166: {
167: return new Vector3(-V1.X, -V1.Y, -V1.Z);
168: }
169:
170: public static bool operator <(Vector3 V1, Vector3 V2)
171: {
172: return V1.Magnitude < V2.Magnitude;
173: }
174:
175: public static bool operator <=(Vector3 V1, Vector3 V2)
176: {
177: return V1.Magnitude <= V2.Magnitude;
178: }
179:
180: public static bool operator >(Vector3 V1, Vector3 V2)
181: {
182: return V1.Magnitude > V2.Magnitude;
183: }
184:
185: public static bool operator >=(Vector3 V1, Vector3 V2)
186: {
187: return V1.Magnitude >= V2.Magnitude;
188: }
189:
190: public static bool operator ==(Vector3 V1, Vector3 V2)
191: {
192: return V1.X == V2.X && V1.Y == V2.Y && V1.Z == V2.Z;
193: }
194:
195: public static bool operator !=(Vector3 V1, Vector3 V2)
196: {
197: return !(V1 == V2);
198: }
199:
200: public static Vector3 operator /(Vector3 V1, double D)
201: {
202: return new Vector3(V1.X / D, V1.Y / D, V1.Z / D);
203: }
204:
205: public static Vector3 operator *(Vector3 V1, double D)
206: {
207: return new Vector3(V1.X * D, V1.Y * D, V1.Z * D);
208: }
209:
210: public static Vector3 operator *(double D, Vector3 V1)
211: {
212: return new Vector3(V1.X * D, V1.Y * D, V1.Z * D);
213: }
214: /// <summary>
215: /// Does a cross product
216: /// </summary>
217: public static Vector3 operator *(Vector3 V1, Vector3 V2)
218: {
219: Vector3 TempVector = new Vector3(0.0, 0.0, 0.0);
220: TempVector.X = (V1.Y * V2.Z) - (V1.Z * V2.Y);
221: TempVector.Y = (V1.Z * V2.X) - (V1.X * V2.Z);
222: TempVector.Z = (V1.X * V2.Y) - (V1.Y * V2.X);
223: return TempVector;
224: }
225:
226: /// <summary>
227: /// Does a dot product
228: /// </summary>
229: /// <param name="V1">Vector 1</param>
230: /// <param name="V2">Vector 2</param>
231: /// <returns>a dot product</returns>
232: public static double DotProduct(Vector3 V1, Vector3 V2)
233: {
234: return (V1.X * V2.X) + (V1.Y * V2.Y) + (V1.Z * V2.Z);
235: }
236:
237: /// <summary>
238: /// Interpolates between the vectors
239: /// </summary>
240: /// <param name="V1">Vector 1</param>
241: /// <param name="V2">Vector 2</param>
242: /// <param name="Control">Percent to move between 1 and 2</param>
243: /// <returns>The interpolated vector</returns>
244: public static Vector3 Interpolate(Vector3 V1, Vector3 V2, double Control)
245: {
246: Vector3 TempVector = new Vector3(0.0, 0.0, 0.0);
247: TempVector.X = (V1.X * (1 - Control)) + (V2.X * Control);
248: TempVector.Y = (V1.Y * (1 - Control)) + (V2.Y * Control);
249: TempVector.Z = (V1.Z * (1 - Control)) - (V2.Z * Control);
250: return TempVector;
251: }
252:
253: /// <summary>
254: /// The distance between two vectors
255: /// </summary>
256: /// <param name="V1">Vector 1</param>
257: /// <param name="V2">Vector 2</param>
258: /// <returns>Distance between the vectors</returns>
259: public static double Distance(Vector3 V1, Vector3 V2)
260: {
261: return System.Math.Sqrt(((V1.X - V2.X) * (V1.X - V2.X)) + ((V1.Y - V2.Y) * (V1.Y - V2.Y)) + ((V1.Z - V2.Z) * (V1.Z - V2.Z)));
262: }
263:
264: /// <summary>
265: /// Determines the angle between the vectors
266: /// </summary>
267: /// <param name="V1">Vector 1</param>
268: /// <param name="V2">Vector 2</param>
269: /// <returns>Angle between the vectors</returns>
270: public static double Angle(Vector3 V1, Vector3 V2)
271: {
272: V1.Normalize();
273: V2.Normalize();
274: return System.Math.Acos(Vector3.DotProduct(V1, V2));
275: }
276:
277: #endregion
278: }
279: }