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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
23 // Chris Toshok (toshok@ximian.com)
27 using System
.ComponentModel
;
28 using System
.Windows
.Markup
;
29 using System
.Windows
.Media
.Converters
;
30 using System
.Windows
.Threading
;
32 namespace System
.Windows
.Media
{
35 [TypeConverter (typeof(MatrixConverter
))]
36 [ValueSerializer (typeof (MatrixValueSerializer
))]
37 public struct Matrix
: IFormattable
{
46 public Matrix (double m11
,
57 this.offsetX
= offsetX
;
58 this.offsetY
= offsetY
;
61 public void Append (Matrix matrix
)
70 _m11
= m11
* matrix
.M11
+ m12
* matrix
.M21
;
71 _m12
= m11
* matrix
.M12
+ m12
* matrix
.M22
;
72 _m21
= m21
* matrix
.M11
+ m22
* matrix
.M21
;
73 _m22
= m21
* matrix
.M12
+ m22
* matrix
.M22
;
75 _offsetX
= offsetX
* matrix
.M11
+ offsetY
* matrix
.M21
+ matrix
.OffsetX
;
76 _offsetY
= offsetX
* matrix
.M12
+ offsetY
* matrix
.M22
+ matrix
.OffsetY
;
86 public bool Equals (Matrix
value)
88 return (m11
== value.M11
&&
92 offsetX
== value.OffsetX
&&
93 offsetY
== value.OffsetY
);
96 public override bool Equals (object o
)
101 return Equals ((Matrix
)o
);
104 public static bool Equals (Matrix matrix1
,
107 return matrix1
.Equals (matrix2
);
110 public override int GetHashCode ()
112 throw new NotImplementedException ();
115 public void Invert ()
118 throw new InvalidOperationException ("Transform is not invertible.");
120 double d
= Determinant
;
122 /* 1/(ad-bc)[d -b; -c a] */
129 double _offsetX
= m21
* offsetY
- m22
* offsetX
;
130 double _offsetY
= m12
* offsetX
- m11
* offsetY
;
136 offsetX
= _offsetX
/ d
;
137 offsetY
= _offsetY
/ d
;
140 public static Matrix
Multiply (Matrix trans1
,
148 public static bool operator == (Matrix matrix1
,
151 return matrix1
.Equals (matrix2
);
154 public static bool operator != (Matrix matrix1
,
157 return !matrix1
.Equals (matrix2
);
160 public static Matrix
operator * (Matrix trans1
,
163 Matrix result
= trans1
;
164 result
.Append (trans2
);
168 public static Matrix
Parse (string source
)
170 throw new NotImplementedException ();
173 public void Prepend (Matrix matrix
)
182 _m11
= matrix
.M11
* m11
+ matrix
.M12
* m21
;
183 _m12
= matrix
.M11
* m12
+ matrix
.M12
* m22
;
184 _m21
= matrix
.M21
* m11
+ matrix
.M22
* m21
;
185 _m22
= matrix
.M21
* m12
+ matrix
.M22
* m22
;
187 _offsetX
= matrix
.OffsetX
* m11
+ matrix
.OffsetY
* m21
+ offsetX
;
188 _offsetY
= matrix
.OffsetX
* m12
+ matrix
.OffsetY
* m22
+ offsetY
;
198 public void Rotate (double angle
)
200 // R_theta==[costheta -sintheta; sintheta costheta],
201 double theta
= angle
* Math
.PI
/ 180;
203 Matrix r_theta
= new Matrix (Math
.Cos (theta
), Math
.Sin(theta
),
204 -Math
.Sin (theta
), Math
.Cos(theta
),
210 public void RotateAt (double angle
,
214 Translate (-centerX
, -centerY
);
216 Translate (centerX
, centerY
);
219 public void RotateAtPrepend (double angle
,
223 Matrix m
= Matrix
.Identity
;
224 m
.RotateAt (angle
, centerX
, centerY
);
228 public void RotatePrepend (double angle
)
230 Matrix m
= Matrix
.Identity
;
235 public void Scale (double scaleX
,
238 Matrix scale
= new Matrix (scaleX
, 0,
245 public void ScaleAt (double scaleX
,
250 Translate (-centerX
, -centerY
);
251 Scale (scaleX
, scaleY
);
252 Translate (centerX
, centerY
);
255 public void ScaleAtPrepend (double scaleX
,
260 Matrix m
= Matrix
.Identity
;
261 m
.ScaleAt (scaleX
, scaleY
, centerX
, centerY
);
265 public void ScalePrepend (double scaleX
,
268 Matrix m
= Matrix
.Identity
;
269 m
.Scale (scaleX
, scaleY
);
273 public void SetIdentity ()
277 offsetX
= offsetY
= 0.0;
280 public void Skew (double skewX
,
283 Matrix skew_m
= new Matrix (1, Math
.Tan (skewY
* Math
.PI
/ 180),
284 Math
.Tan (skewX
* Math
.PI
/ 180), 1,
289 public void SkewPrepend (double skewX
,
292 Matrix m
= Matrix
.Identity
;
293 m
.Skew (skewX
, skewY
);
297 string IFormattable
.ToString (string format
,
298 IFormatProvider provider
)
300 throw new NotImplementedException ();
303 public override string ToString ()
308 return string.Format ("{0},{1},{2},{3},{4},{5}",
309 m11
, m12
, m21
, m22
, offsetX
, offsetY
);
312 public string ToString (IFormatProvider provider
)
314 throw new NotImplementedException ();
317 public Point
Transform (Point point
)
319 return Point
.Multiply (point
, this);
322 public void Transform (Point
[] points
)
324 for (int i
= 0; i
< points
.Length
; i
++)
325 points
[i
] = Transform (points
[i
]);
328 public Vector
Transform (Vector vector
)
330 return Vector
.Multiply (vector
, this);
333 public void Transform (Vector
[] vectors
)
335 for (int i
= 0; i
< vectors
.Length
; i
++)
336 vectors
[i
] = Transform (vectors
[i
]);
339 public void Translate (double offsetX
,
342 this.offsetX
+= offsetX
;
343 this.offsetY
+= offsetY
;
346 public void TranslatePrepend (double offsetX
,
349 Matrix m
= Matrix
.Identity
;
350 m
.Translate (offsetX
, offsetY
);
354 public double Determinant
{
355 get { return m11 * m22 - m12 * m21; }
358 public bool HasInverse
{
359 get { return Determinant != 0; }
362 public static Matrix Identity
{
363 get { return new Matrix (1.0, 0.0, 0.0, 1.0, 0.0, 0.0); }
366 public bool IsIdentity
{
367 get { return Equals (Matrix.Identity); }
386 public double OffsetX
{
387 get { return offsetX; }
388 set { offsetX = value; }
390 public double OffsetY
{
391 get { return offsetY; }
392 set { offsetY = value; }