Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Media3D / Vector3D.cs / 1 / Vector3D.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: 3D vector implementation. // // See spec at http://avalon/medialayer/Specifications/Avalon3D%20API%20Spec.mht // // History: // 06/02/2003 : t-gregr - Created // //--------------------------------------------------------------------------- using MS.Internal; using MS.Internal.Media3D; using System; using System.Windows; using System.Windows.Media.Media3D; namespace System.Windows.Media.Media3D { ////// Vector3D - 3D vector representation. /// public partial struct Vector3D { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Constructor that sets vector's initial values. /// /// Value of the X coordinate of the new vector. /// Value of the Y coordinate of the new vector. /// Value of the Z coordinate of the new vector. public Vector3D(double x, double y, double z) { _x = x; _y = y; _z = z; } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Length of the vector. /// public double Length { get { return Math.Sqrt(_x * _x + _y * _y + _z * _z); } } ////// Length of the vector squared. /// public double LengthSquared { get { return _x * _x + _y * _y + _z * _z; } } ////// Updates the vector to maintain its direction, but to have a length /// of 1. Equivalent to dividing the vector by its Length. /// Returns NaN if length is zero. /// public void Normalize() { // Computation of length can overflow easily because it // first computes squared length, so we first divide by // the largest coefficient. double m = Math.Abs(_x); double absy = Math.Abs(_y); double absz = Math.Abs(_z); if (absy > m) { m = absy; } if (absz > m) { m = absz; } _x /= m; _y /= m; _z /= m; double length = Math.Sqrt(_x * _x + _y * _y + _z * _z); this /= length; } ////// Computes the angle between two vectors. /// /// First vector. /// Second vector. ////// Returns the angle required to rotate vector1 into vector2 in degrees. /// This will return a value between [0, 180] degrees. /// (Note that this is slightly different from the Vector member /// function of the same name. Signed angles do not extend to 3D.) /// public static double AngleBetween(Vector3D vector1, Vector3D vector2) { vector1.Normalize(); vector2.Normalize(); double ratio = DotProduct(vector1, vector2); // The "straight forward" method of acos(u.v) has large precision // issues when the dot product is near +/-1. This is due to the // steep slope of the acos function as we approach +/- 1. Slight // precision errors in the dot product calculation cause large // variation in the output value. // // | | // \__ | // ---___ | // ---___ | // ---_|_ // | ---___ // | ---___ // | ---__ // | \ // | | // -|-------------------+-------------------|- // -1 0 1 // // acos(x) // // To avoid this we use an alternative method which finds the // angle bisector by (u-v)/2: // // _> // u _- \ (u-v)/2 // _- __-v // _=__-- // .=-----------> // v // // Because u and v and unit vectors, (u-v)/2 forms a right angle // with the angle bisector. The hypotenuse is 1, therefore // 2*asin(|u-v|/2) gives us the angle between u and v. // // The largest possible value of |u-v| occurs with perpendicular // vectors and is sqrt(2)/2 which is well away from extreme slope // at +/-1. // // (See Windows OS Bug #1706299 for details) double theta; if (ratio < 0) { theta = Math.PI - 2.0 * Math.Asin((-vector1 - vector2).Length / 2.0); } else { theta = 2.0 * Math.Asin((vector1 - vector2).Length / 2.0); } return M3DUtil.RadiansToDegrees(theta); } ////// Operator -Vector (unary negation). /// /// Vector being negated. ///Negation of the given vector. public static Vector3D operator -(Vector3D vector) { return new Vector3D(-vector._x, -vector._y, -vector._z); } ////// Negates the values of X, Y, and Z on this Vector3D /// public void Negate() { _x = -_x; _y = -_y; _z = -_z; } ////// Vector addition. /// /// First vector being added. /// Second vector being added. ///Result of addition. public static Vector3D operator +(Vector3D vector1, Vector3D vector2) { return new Vector3D(vector1._x + vector2._x, vector1._y + vector2._y, vector1._z + vector2._z); } ////// Vector addition. /// /// First vector being added. /// Second vector being added. ///Result of addition. public static Vector3D Add(Vector3D vector1, Vector3D vector2) { return new Vector3D(vector1._x + vector2._x, vector1._y + vector2._y, vector1._z + vector2._z); } ////// Vector subtraction. /// /// Vector that is subtracted from. /// Vector being subtracted. ///Result of subtraction. public static Vector3D operator -(Vector3D vector1, Vector3D vector2) { return new Vector3D(vector1._x - vector2._x, vector1._y - vector2._y, vector1._z - vector2._z); } ////// Vector subtraction. /// /// Vector that is subtracted from. /// Vector being subtracted. ///Result of subtraction. public static Vector3D Subtract(Vector3D vector1, Vector3D vector2) { return new Vector3D(vector1._x - vector2._x, vector1._y - vector2._y, vector1._z - vector2._z); } ////// Vector3D + Point3D addition. /// /// Vector by which we offset the point. /// Point being offset by the given vector. ///Result of addition. public static Point3D operator +(Vector3D vector, Point3D point) { return new Point3D(vector._x + point._x, vector._y + point._y, vector._z + point._z); } ////// Vector3D + Point3D addition. /// /// Vector by which we offset the point. /// Point being offset by the given vector. ///Result of addition. public static Point3D Add(Vector3D vector, Point3D point) { return new Point3D(vector._x + point._x, vector._y + point._y, vector._z + point._z); } ////// Vector3D - Point3D subtraction. /// /// Vector by which we offset the point. /// Point being offset by the given vector. ///Result of subtraction. public static Point3D operator -(Vector3D vector, Point3D point) { return new Point3D(vector._x - point._x, vector._y - point._y, vector._z - point._z); } ////// Vector3D - Point3D subtraction. /// /// Vector by which we offset the point. /// Point being offset by the given vector. ///Result of subtraction. public static Point3D Subtract(Vector3D vector, Point3D point) { return new Point3D(vector._x - point._x, vector._y - point._y, vector._z - point._z); } ////// Scalar multiplication. /// /// Vector being multiplied. /// Scalar value by which the vector is multiplied. ///Result of multiplication. public static Vector3D operator *(Vector3D vector, double scalar) { return new Vector3D(vector._x * scalar, vector._y * scalar, vector._z * scalar); } ////// Scalar multiplication. /// /// Vector being multiplied. /// Scalar value by which the vector is multiplied. ///Result of multiplication. public static Vector3D Multiply(Vector3D vector, double scalar) { return new Vector3D(vector._x * scalar, vector._y * scalar, vector._z * scalar); } ////// Scalar multiplication. /// /// Scalar value by which the vector is multiplied /// Vector being multiplied. ///Result of multiplication. public static Vector3D operator *(double scalar, Vector3D vector) { return new Vector3D(vector._x * scalar, vector._y * scalar, vector._z * scalar); } ////// Scalar multiplication. /// /// Scalar value by which the vector is multiplied /// Vector being multiplied. ///Result of multiplication. public static Vector3D Multiply(double scalar, Vector3D vector) { return new Vector3D(vector._x * scalar, vector._y * scalar, vector._z * scalar); } ////// Scalar division. /// /// Vector being divided. /// Scalar value by which we divide the vector. ///Result of division. public static Vector3D operator /(Vector3D vector, double scalar) { return vector * (1.0 / scalar); } ////// Scalar division. /// /// Vector being divided. /// Scalar value by which we divide the vector. ///Result of division. public static Vector3D Divide(Vector3D vector, double scalar) { return vector * (1.0 / scalar); } ////// Vector3D * Matrix3D multiplication /// /// Vector being tranformed. /// Transformation matrix applied to the vector. ///Result of multiplication. public static Vector3D operator *(Vector3D vector, Matrix3D matrix) { return matrix.Transform(vector); } ////// Vector3D * Matrix3D multiplication /// /// Vector being tranformed. /// Transformation matrix applied to the vector. ///Result of multiplication. public static Vector3D Multiply(Vector3D vector, Matrix3D matrix) { return matrix.Transform(vector); } ////// Vector dot product. /// /// First vector. /// Second vector. ///Dot product of two vectors. public static double DotProduct(Vector3D vector1, Vector3D vector2) { return DotProduct(ref vector1, ref vector2); } ////// Faster internal version of DotProduct that avoids copies /// /// vector1 and vector2 to a passed by ref for perf and ARE NOT MODIFIED /// internal static double DotProduct(ref Vector3D vector1, ref Vector3D vector2) { return vector1._x * vector2._x + vector1._y * vector2._y + vector1._z * vector2._z; } ////// Vector cross product. /// /// First vector. /// Second vector. ///Cross product of two vectors. public static Vector3D CrossProduct(Vector3D vector1, Vector3D vector2) { Vector3D result; CrossProduct(ref vector1, ref vector2, out result); return result; } ////// Faster internal version of CrossProduct that avoids copies /// /// vector1 and vector2 to a passed by ref for perf and ARE NOT MODIFIED /// internal static void CrossProduct(ref Vector3D vector1, ref Vector3D vector2, out Vector3D result) { result._x = vector1._y * vector2._z - vector1._z * vector2._y; result._y = vector1._z * vector2._x - vector1._x * vector2._z; result._z = vector1._x * vector2._y - vector1._y * vector2._x; } ////// Vector3D to Point3D conversion. /// /// Vector being converted. ///Point representing the given vector. public static explicit operator Point3D(Vector3D vector) { return new Point3D(vector._x, vector._y, vector._z); } ////// Explicit conversion to Size3D. Note that since Size3D cannot contain negative values, /// the resulting size will contains the absolute values of X, Y, and Z. /// /// The vector to convert to a size. ///A size equal to this vector. public static explicit operator Size3D(Vector3D vector) { return new Size3D(Math.Abs(vector._x), Math.Abs(vector._y), Math.Abs(vector._z)); } #endregion Public Methods } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: 3D vector implementation. // // See spec at http://avalon/medialayer/Specifications/Avalon3D%20API%20Spec.mht // // History: // 06/02/2003 : t-gregr - Created // //--------------------------------------------------------------------------- using MS.Internal; using MS.Internal.Media3D; using System; using System.Windows; using System.Windows.Media.Media3D; namespace System.Windows.Media.Media3D { ////// Vector3D - 3D vector representation. /// public partial struct Vector3D { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Constructor that sets vector's initial values. /// /// Value of the X coordinate of the new vector. /// Value of the Y coordinate of the new vector. /// Value of the Z coordinate of the new vector. public Vector3D(double x, double y, double z) { _x = x; _y = y; _z = z; } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Length of the vector. /// public double Length { get { return Math.Sqrt(_x * _x + _y * _y + _z * _z); } } ////// Length of the vector squared. /// public double LengthSquared { get { return _x * _x + _y * _y + _z * _z; } } ////// Updates the vector to maintain its direction, but to have a length /// of 1. Equivalent to dividing the vector by its Length. /// Returns NaN if length is zero. /// public void Normalize() { // Computation of length can overflow easily because it // first computes squared length, so we first divide by // the largest coefficient. double m = Math.Abs(_x); double absy = Math.Abs(_y); double absz = Math.Abs(_z); if (absy > m) { m = absy; } if (absz > m) { m = absz; } _x /= m; _y /= m; _z /= m; double length = Math.Sqrt(_x * _x + _y * _y + _z * _z); this /= length; } ////// Computes the angle between two vectors. /// /// First vector. /// Second vector. ////// Returns the angle required to rotate vector1 into vector2 in degrees. /// This will return a value between [0, 180] degrees. /// (Note that this is slightly different from the Vector member /// function of the same name. Signed angles do not extend to 3D.) /// public static double AngleBetween(Vector3D vector1, Vector3D vector2) { vector1.Normalize(); vector2.Normalize(); double ratio = DotProduct(vector1, vector2); // The "straight forward" method of acos(u.v) has large precision // issues when the dot product is near +/-1. This is due to the // steep slope of the acos function as we approach +/- 1. Slight // precision errors in the dot product calculation cause large // variation in the output value. // // | | // \__ | // ---___ | // ---___ | // ---_|_ // | ---___ // | ---___ // | ---__ // | \ // | | // -|-------------------+-------------------|- // -1 0 1 // // acos(x) // // To avoid this we use an alternative method which finds the // angle bisector by (u-v)/2: // // _> // u _- \ (u-v)/2 // _- __-v // _=__-- // .=-----------> // v // // Because u and v and unit vectors, (u-v)/2 forms a right angle // with the angle bisector. The hypotenuse is 1, therefore // 2*asin(|u-v|/2) gives us the angle between u and v. // // The largest possible value of |u-v| occurs with perpendicular // vectors and is sqrt(2)/2 which is well away from extreme slope // at +/-1. // // (See Windows OS Bug #1706299 for details) double theta; if (ratio < 0) { theta = Math.PI - 2.0 * Math.Asin((-vector1 - vector2).Length / 2.0); } else { theta = 2.0 * Math.Asin((vector1 - vector2).Length / 2.0); } return M3DUtil.RadiansToDegrees(theta); } ////// Operator -Vector (unary negation). /// /// Vector being negated. ///Negation of the given vector. public static Vector3D operator -(Vector3D vector) { return new Vector3D(-vector._x, -vector._y, -vector._z); } ////// Negates the values of X, Y, and Z on this Vector3D /// public void Negate() { _x = -_x; _y = -_y; _z = -_z; } ////// Vector addition. /// /// First vector being added. /// Second vector being added. ///Result of addition. public static Vector3D operator +(Vector3D vector1, Vector3D vector2) { return new Vector3D(vector1._x + vector2._x, vector1._y + vector2._y, vector1._z + vector2._z); } ////// Vector addition. /// /// First vector being added. /// Second vector being added. ///Result of addition. public static Vector3D Add(Vector3D vector1, Vector3D vector2) { return new Vector3D(vector1._x + vector2._x, vector1._y + vector2._y, vector1._z + vector2._z); } ////// Vector subtraction. /// /// Vector that is subtracted from. /// Vector being subtracted. ///Result of subtraction. public static Vector3D operator -(Vector3D vector1, Vector3D vector2) { return new Vector3D(vector1._x - vector2._x, vector1._y - vector2._y, vector1._z - vector2._z); } ////// Vector subtraction. /// /// Vector that is subtracted from. /// Vector being subtracted. ///Result of subtraction. public static Vector3D Subtract(Vector3D vector1, Vector3D vector2) { return new Vector3D(vector1._x - vector2._x, vector1._y - vector2._y, vector1._z - vector2._z); } ////// Vector3D + Point3D addition. /// /// Vector by which we offset the point. /// Point being offset by the given vector. ///Result of addition. public static Point3D operator +(Vector3D vector, Point3D point) { return new Point3D(vector._x + point._x, vector._y + point._y, vector._z + point._z); } ////// Vector3D + Point3D addition. /// /// Vector by which we offset the point. /// Point being offset by the given vector. ///Result of addition. public static Point3D Add(Vector3D vector, Point3D point) { return new Point3D(vector._x + point._x, vector._y + point._y, vector._z + point._z); } ////// Vector3D - Point3D subtraction. /// /// Vector by which we offset the point. /// Point being offset by the given vector. ///Result of subtraction. public static Point3D operator -(Vector3D vector, Point3D point) { return new Point3D(vector._x - point._x, vector._y - point._y, vector._z - point._z); } ////// Vector3D - Point3D subtraction. /// /// Vector by which we offset the point. /// Point being offset by the given vector. ///Result of subtraction. public static Point3D Subtract(Vector3D vector, Point3D point) { return new Point3D(vector._x - point._x, vector._y - point._y, vector._z - point._z); } ////// Scalar multiplication. /// /// Vector being multiplied. /// Scalar value by which the vector is multiplied. ///Result of multiplication. public static Vector3D operator *(Vector3D vector, double scalar) { return new Vector3D(vector._x * scalar, vector._y * scalar, vector._z * scalar); } ////// Scalar multiplication. /// /// Vector being multiplied. /// Scalar value by which the vector is multiplied. ///Result of multiplication. public static Vector3D Multiply(Vector3D vector, double scalar) { return new Vector3D(vector._x * scalar, vector._y * scalar, vector._z * scalar); } ////// Scalar multiplication. /// /// Scalar value by which the vector is multiplied /// Vector being multiplied. ///Result of multiplication. public static Vector3D operator *(double scalar, Vector3D vector) { return new Vector3D(vector._x * scalar, vector._y * scalar, vector._z * scalar); } ////// Scalar multiplication. /// /// Scalar value by which the vector is multiplied /// Vector being multiplied. ///Result of multiplication. public static Vector3D Multiply(double scalar, Vector3D vector) { return new Vector3D(vector._x * scalar, vector._y * scalar, vector._z * scalar); } ////// Scalar division. /// /// Vector being divided. /// Scalar value by which we divide the vector. ///Result of division. public static Vector3D operator /(Vector3D vector, double scalar) { return vector * (1.0 / scalar); } ////// Scalar division. /// /// Vector being divided. /// Scalar value by which we divide the vector. ///Result of division. public static Vector3D Divide(Vector3D vector, double scalar) { return vector * (1.0 / scalar); } ////// Vector3D * Matrix3D multiplication /// /// Vector being tranformed. /// Transformation matrix applied to the vector. ///Result of multiplication. public static Vector3D operator *(Vector3D vector, Matrix3D matrix) { return matrix.Transform(vector); } ////// Vector3D * Matrix3D multiplication /// /// Vector being tranformed. /// Transformation matrix applied to the vector. ///Result of multiplication. public static Vector3D Multiply(Vector3D vector, Matrix3D matrix) { return matrix.Transform(vector); } ////// Vector dot product. /// /// First vector. /// Second vector. ///Dot product of two vectors. public static double DotProduct(Vector3D vector1, Vector3D vector2) { return DotProduct(ref vector1, ref vector2); } ////// Faster internal version of DotProduct that avoids copies /// /// vector1 and vector2 to a passed by ref for perf and ARE NOT MODIFIED /// internal static double DotProduct(ref Vector3D vector1, ref Vector3D vector2) { return vector1._x * vector2._x + vector1._y * vector2._y + vector1._z * vector2._z; } ////// Vector cross product. /// /// First vector. /// Second vector. ///Cross product of two vectors. public static Vector3D CrossProduct(Vector3D vector1, Vector3D vector2) { Vector3D result; CrossProduct(ref vector1, ref vector2, out result); return result; } ////// Faster internal version of CrossProduct that avoids copies /// /// vector1 and vector2 to a passed by ref for perf and ARE NOT MODIFIED /// internal static void CrossProduct(ref Vector3D vector1, ref Vector3D vector2, out Vector3D result) { result._x = vector1._y * vector2._z - vector1._z * vector2._y; result._y = vector1._z * vector2._x - vector1._x * vector2._z; result._z = vector1._x * vector2._y - vector1._y * vector2._x; } ////// Vector3D to Point3D conversion. /// /// Vector being converted. ///Point representing the given vector. public static explicit operator Point3D(Vector3D vector) { return new Point3D(vector._x, vector._y, vector._z); } ////// Explicit conversion to Size3D. Note that since Size3D cannot contain negative values, /// the resulting size will contains the absolute values of X, Y, and Z. /// /// The vector to convert to a size. ///A size equal to this vector. public static explicit operator Size3D(Vector3D vector) { return new Size3D(Math.Abs(vector._x), Math.Abs(vector._y), Math.Abs(vector._z)); } #endregion Public Methods } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- propertyentry.cs
- NestedContainer.cs
- HScrollBar.cs
- Helpers.cs
- SineEase.cs
- SoapAttributeOverrides.cs
- BamlTreeMap.cs
- DefaultAutoFieldGenerator.cs
- ActiveXSite.cs
- ValidateNames.cs
- XmlBinaryReader.cs
- HtmlUtf8RawTextWriter.cs
- TextServicesCompartmentContext.cs
- ReadOnlyDictionary.cs
- DateTimeUtil.cs
- SapiRecognizer.cs
- ActiveXContainer.cs
- ArgumentException.cs
- TypeNameConverter.cs
- TypeGeneratedEventArgs.cs
- StoreAnnotationsMap.cs
- PagesChangedEventArgs.cs
- ParameterCollection.cs
- SafeSecurityHelper.cs
- DiagnosticTrace.cs
- ArglessEventHandlerProxy.cs
- MapPathBasedVirtualPathProvider.cs
- ContainerUIElement3D.cs
- ButtonFlatAdapter.cs
- UnhandledExceptionEventArgs.cs
- ComponentEditorPage.cs
- PkcsUtils.cs
- TableItemPatternIdentifiers.cs
- LineVisual.cs
- ProcessThread.cs
- SingleObjectCollection.cs
- LineMetrics.cs
- ResourcePermissionBase.cs
- HttpRuntime.cs
- IpcPort.cs
- SmiTypedGetterSetter.cs
- VectorCollectionConverter.cs
- RelatedImageListAttribute.cs
- X509CertificateStore.cs
- DecimalAnimation.cs
- AlignmentXValidation.cs
- OleAutBinder.cs
- TypeUnloadedException.cs
- FontSizeConverter.cs
- NavigationHelper.cs
- ImplicitInputBrush.cs
- DataMemberConverter.cs
- HtmlInputHidden.cs
- CompilerResults.cs
- UTF7Encoding.cs
- TypeName.cs
- MDIControlStrip.cs
- ModelPropertyCollectionImpl.cs
- LinqDataSourceContextEventArgs.cs
- MsmqInputMessagePool.cs
- ControlAdapter.cs
- CheckBoxList.cs
- AnimationStorage.cs
- WebBaseEventKeyComparer.cs
- RawStylusInputReport.cs
- ClientApiGenerator.cs
- TypeConverterHelper.cs
- NetWebProxyFinder.cs
- DCSafeHandle.cs
- HyperlinkAutomationPeer.cs
- AssemblyCache.cs
- DataSet.cs
- MLangCodePageEncoding.cs
- UrlMappingCollection.cs
- XhtmlBasicLiteralTextAdapter.cs
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
- UnsafeNativeMethods.cs
- ToolStripItemTextRenderEventArgs.cs
- SecurityPolicyVersion.cs
- ToolStripPanelRenderEventArgs.cs
- ResourceContainerWrapper.cs
- SqlComparer.cs
- WmlFormAdapter.cs
- PerformanceCounter.cs
- _ProxyRegBlob.cs
- AutomationPatternInfo.cs
- StreamReader.cs
- XslException.cs
- RadioButton.cs
- SafeThreadHandle.cs
- XPathMessageContext.cs
- DbConnectionHelper.cs
- HtmlControlPersistable.cs
- TreeViewCancelEvent.cs
- ConfigurationPropertyCollection.cs
- SqlInfoMessageEvent.cs
- XmlNamespaceMappingCollection.cs
- XmlReflectionImporter.cs
- WebPartMenuStyle.cs
- CodeCompileUnit.cs