1 // Permission is hereby granted, free of charge, to any person obtaining 2 // a copy of this software and associated documentation files (the 3 // "Software"), to deal in the Software without restriction, including 4 // without limitation the rights to use, copy, modify, merge, publish, 5 // distribute, sublicense, and/or sell copies of the Software, and to 6 // permit persons to whom the Software is furnished to do so, subject to 7 // the following conditions: 8 // 9 // The above copyright notice and this permission notice shall be 10 // included in all copies or substantial portions of the Software. 11 // 12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 // 20 // Copyright (c) 2007 Novell, Inc. (http://www.novell.com) 21 // 22 // Authors: 23 // Chris Toshok (toshok@novell.com) 24 // 25 26 using System.ComponentModel; 27 using System.Globalization; 28 using System.Windows.Converters; 29 using System.Windows.Markup; 30 using System.Windows.Media; 31 32 namespace System.Windows { 33 34 [Serializable] 35 [ValueSerializer (typeof (VectorValueSerializer))] 36 [TypeConverter (typeof (VectorConverter))] 37 public struct Vector : IFormattable 38 { VectorSystem.Windows.Vector39 public Vector (double x, double y) 40 { 41 this._x = x; 42 this._y = y; 43 } 44 EqualsSystem.Windows.Vector45 public bool Equals (Vector value) 46 { 47 return _x == value.X && _y == value.Y; 48 } 49 EqualsSystem.Windows.Vector50 public override bool Equals (object o) 51 { 52 if (!(o is Vector)) 53 return false; 54 55 return Equals ((Vector)o); 56 } 57 GetHashCodeSystem.Windows.Vector58 public override int GetHashCode () 59 { 60 unchecked 61 { 62 return (_x.GetHashCode () * 397) ^ _y.GetHashCode (); 63 } 64 } 65 EqualsSystem.Windows.Vector66 public static bool Equals (Vector vector1, Vector vector2) 67 { 68 return vector1.Equals (vector2); 69 } 70 AddSystem.Windows.Vector71 public static Point Add (Vector vector, Point point) 72 { 73 return new Point (vector.X + point.X, vector.Y + point.Y); 74 } 75 AddSystem.Windows.Vector76 public static Vector Add (Vector vector1, Vector vector2) 77 { 78 return new Vector (vector1.X + vector2.X, 79 vector1.Y + vector2.Y); 80 } 81 AngleBetweenSystem.Windows.Vector82 public static double AngleBetween (Vector vector1, Vector vector2) 83 { 84 double cos_theta = (vector1.X * vector2.X + vector1.Y * vector2.Y) / (vector1.Length * vector2.Length); 85 86 return Math.Acos (cos_theta) / Math.PI * 180; 87 } 88 CrossProductSystem.Windows.Vector89 public static double CrossProduct (Vector vector1, Vector vector2) 90 { 91 // ... what operation is this exactly? 92 return vector1.X * vector2.Y - vector1.Y * vector2.X; 93 } 94 DeterminantSystem.Windows.Vector95 public static double Determinant (Vector vector1, Vector vector2) 96 { 97 // same as CrossProduct, it appears. 98 return vector1.X * vector2.Y - vector1.Y * vector2.X; 99 } 100 DivideSystem.Windows.Vector101 public static Vector Divide (Vector vector, double scalar) 102 { 103 return new Vector (vector.X / scalar, vector.Y / scalar); 104 } 105 MultiplySystem.Windows.Vector106 public static double Multiply (Vector vector1, Vector vector2) 107 { 108 return vector1.X * vector2.X + vector1.Y * vector2.Y; 109 } 110 MultiplySystem.Windows.Vector111 public static Vector Multiply (Vector vector, Matrix matrix) 112 { 113 return new Vector (vector.X * matrix.M11 + vector.Y * matrix.M21, 114 vector.X * matrix.M12 + vector.Y * matrix.M22); 115 } 116 MultiplySystem.Windows.Vector117 public static Vector Multiply (double scalar, Vector vector) 118 { 119 return new Vector (scalar * vector.X, scalar * vector.Y); 120 } 121 MultiplySystem.Windows.Vector122 public static Vector Multiply (Vector vector, double scalar) 123 { 124 return new Vector (scalar * vector.X, scalar * vector.Y); 125 } 126 NegateSystem.Windows.Vector127 public void Negate () 128 { 129 _x = -_x; 130 _y = -_y; 131 } 132 NormalizeSystem.Windows.Vector133 public void Normalize () 134 { 135 double ls = LengthSquared; 136 if (ls == 1) 137 return; 138 139 double l = Math.Sqrt (ls); 140 _x /= l; 141 _y /= l; 142 } 143 SubtractSystem.Windows.Vector144 public static Vector Subtract (Vector vector1, Vector vector2) 145 { 146 return new Vector (vector1.X - vector2.X, vector1.Y - vector2.Y); 147 } 148 ParseSystem.Windows.Vector149 public static Vector Parse (string source) 150 { 151 if (source == null) 152 throw new ArgumentNullException ("source"); 153 var tokenizer = new NumericListTokenizer (source, CultureInfo.InvariantCulture); 154 double x; 155 double y; 156 if (!double.TryParse (tokenizer.GetNextToken (), NumberStyles.Float, CultureInfo.InvariantCulture, out x) || 157 !double.TryParse (tokenizer.GetNextToken (), NumberStyles.Float, CultureInfo.InvariantCulture, out y)) 158 { 159 throw new FormatException (string.Format ("Invalid Vector format: {0}", source)); 160 } 161 if (!tokenizer.HasNoMoreTokens ()) 162 { 163 throw new InvalidOperationException("Invalid Vector format: " + source); 164 } 165 return new Vector(x, y); 166 } 167 ToStringSystem.Windows.Vector168 public override string ToString () 169 { 170 return ToString(null); 171 } 172 ToStringSystem.Windows.Vector173 public string ToString (IFormatProvider provider) 174 { 175 return ToString (null, provider); 176 } 177 IFormattable.ToStringSystem.Windows.Vector178 string IFormattable.ToString (string format, IFormatProvider provider) 179 { 180 return ToString (format, provider); 181 } 182 ToStringSystem.Windows.Vector183 private string ToString(string format,IFormatProvider formatProvider) 184 { 185 if (formatProvider == null) 186 formatProvider = CultureInfo.CurrentCulture; 187 if (format == null) 188 format = string.Empty; 189 var separator = NumericListTokenizer.GetSeparator (formatProvider); 190 var vectorFormat = string.Format ("{{0:{0}}}{1}{{1:{0}}}", format, separator); 191 return string.Format (formatProvider, vectorFormat, _x, _y); 192 } 193 194 public double Length { 195 get { return Math.Sqrt (LengthSquared); } 196 } 197 198 public double LengthSquared { 199 get { return _x * _x + _y * _y; } 200 } 201 202 public double X { 203 get { return _x; } 204 set { _x = value; } 205 } 206 207 public double Y { 208 get { return _y; } 209 set { _y = value; } 210 } 211 212 /* operators */ operator PointSystem.Windows.Vector213 public static explicit operator Point (Vector vector) 214 { 215 return new Point (vector.X, vector.Y); 216 } 217 operator SizeSystem.Windows.Vector218 public static explicit operator Size (Vector vector) 219 { 220 return new Size (vector.X, vector.Y); 221 } 222 operator -System.Windows.Vector223 public static Vector operator - (Vector vector1, Vector vector2) 224 { 225 return Subtract (vector1, vector2); 226 } 227 operator -System.Windows.Vector228 public static Vector operator - (Vector vector) 229 { 230 Vector result = vector; 231 result.Negate (); 232 return result; 233 } 234 operator !=System.Windows.Vector235 public static bool operator != (Vector vector1, Vector vector2) 236 { 237 return !Equals (vector1, vector2); 238 } 239 operator ==System.Windows.Vector240 public static bool operator == (Vector vector1, Vector vector2) 241 { 242 return Equals (vector1, vector2); 243 } 244 operator *System.Windows.Vector245 public static double operator * (Vector vector1, Vector vector2) 246 { 247 return Multiply (vector1, vector2); 248 } 249 operator *System.Windows.Vector250 public static Vector operator * (Vector vector, Matrix matrix) 251 { 252 return Multiply (vector, matrix); 253 } 254 operator *System.Windows.Vector255 public static Vector operator * (double scalar, Vector vector) 256 { 257 return Multiply (scalar, vector); 258 } 259 operator *System.Windows.Vector260 public static Vector operator * (Vector vector, double scalar) 261 { 262 return Multiply (vector, scalar); 263 } 264 operator /System.Windows.Vector265 public static Vector operator / (Vector vector, double scalar) 266 { 267 return Divide (vector, scalar); 268 } 269 operator +System.Windows.Vector270 public static Point operator + (Vector vector, Point point) 271 { 272 return Add (vector, point); 273 } 274 operator +System.Windows.Vector275 public static Vector operator + (Vector vector1, Vector vector2) 276 { 277 return Add (vector1, vector2); 278 } 279 280 double _x; 281 double _y; 282 } 283 284 } 285