/Controls/HelixToolkit.Wpf/Visual3Ds/Manipulators/RotateManipulator.cs

https://bitbucket.org/kubrakms/thermalconductivity · C# · 227 lines · 137 code · 33 blank · 57 comment · 9 complexity · b4b6d063ba036b0dd93f22881424ae50 MD5 · raw file

  1. // --------------------------------------------------------------------------------------------------------------------
  2. // <copyright file="RotateManipulator.cs" company="Helix 3D Toolkit">
  3. // http://helixtoolkit.codeplex.com, license: Ms-PL
  4. // </copyright>
  5. // --------------------------------------------------------------------------------------------------------------------
  6. namespace HelixToolkit.Wpf
  7. {
  8. using System;
  9. using System.Windows;
  10. using System.Windows.Input;
  11. using System.Windows.Media.Media3D;
  12. /// <summary>
  13. /// A visual element containing a manipulator that can rotate around an axis.
  14. /// </summary>
  15. public class RotateManipulator : Manipulator
  16. {
  17. #region Constants and Fields
  18. /// <summary>
  19. /// The axis property.
  20. /// </summary>
  21. public static readonly DependencyProperty AxisProperty = DependencyProperty.Register(
  22. "Axis",
  23. typeof(Vector3D),
  24. typeof(RotateManipulator),
  25. new UIPropertyMetadata(new Vector3D(0, 0, 1), GeometryChanged));
  26. /// <summary>
  27. /// The diameter property.
  28. /// </summary>
  29. public static readonly DependencyProperty DiameterProperty = DependencyProperty.Register(
  30. "Diameter", typeof(double), typeof(RotateManipulator), new UIPropertyMetadata(3.0, GeometryChanged));
  31. /// <summary>
  32. /// The inner diameter property.
  33. /// </summary>
  34. public static readonly DependencyProperty InnerDiameterProperty = DependencyProperty.Register(
  35. "InnerDiameter", typeof(double), typeof(RotateManipulator), new UIPropertyMetadata(2.5, GeometryChanged));
  36. /// <summary>
  37. /// The length property.
  38. /// </summary>
  39. public static readonly DependencyProperty LengthProperty = DependencyProperty.Register(
  40. "Length", typeof(double), typeof(RotateManipulator), new UIPropertyMetadata(0.1, GeometryChanged));
  41. /// <summary>
  42. /// The last point.
  43. /// </summary>
  44. private Point3D lastPoint;
  45. #endregion
  46. #region Constructors and Destructors
  47. /// <summary>
  48. /// Initializes a new instance of the <see cref = "RotateManipulator" /> class.
  49. /// </summary>
  50. public RotateManipulator()
  51. {
  52. this.Model = new GeometryModel3D();
  53. this.Visual3DModel = this.Model;
  54. this.OnGeometryChanged();
  55. }
  56. #endregion
  57. #region Public Properties
  58. /// <summary>
  59. /// Gets or sets the rotation axis.
  60. /// </summary>
  61. /// <value>The axis.</value>
  62. public Vector3D Axis
  63. {
  64. get
  65. {
  66. return (Vector3D)this.GetValue(AxisProperty);
  67. }
  68. set
  69. {
  70. this.SetValue(AxisProperty, value);
  71. }
  72. }
  73. /// <summary>
  74. /// Gets or sets the diameter.
  75. /// </summary>
  76. /// <value>The diameter.</value>
  77. public double Diameter
  78. {
  79. get
  80. {
  81. return (double)this.GetValue(DiameterProperty);
  82. }
  83. set
  84. {
  85. this.SetValue(DiameterProperty, value);
  86. }
  87. }
  88. /// <summary>
  89. /// Gets or sets the inner diameter.
  90. /// </summary>
  91. /// <value>The inner diameter.</value>
  92. public double InnerDiameter
  93. {
  94. get
  95. {
  96. return (double)this.GetValue(InnerDiameterProperty);
  97. }
  98. set
  99. {
  100. this.SetValue(InnerDiameterProperty, value);
  101. }
  102. }
  103. /// <summary>
  104. /// Gets or sets the length of the cylinder.
  105. /// </summary>
  106. /// <value>The length.</value>
  107. public double Length
  108. {
  109. get
  110. {
  111. return (double)this.GetValue(LengthProperty);
  112. }
  113. set
  114. {
  115. this.SetValue(LengthProperty, value);
  116. }
  117. }
  118. #endregion
  119. #region Methods
  120. /// <summary>
  121. /// The on geometry changed.
  122. /// </summary>
  123. protected override void OnGeometryChanged()
  124. {
  125. var mb = new MeshBuilder(false, false);
  126. var p0 = new Point3D(0, 0, 0);
  127. var d = this.Axis;
  128. d.Normalize();
  129. var p1 = p0 - (d * this.Length * 0.5);
  130. var p2 = p0 + (d * this.Length * 0.5);
  131. mb.AddPipe(p1, p2, this.InnerDiameter, this.Diameter, 60);
  132. this.Model.Geometry = mb.ToMesh();
  133. }
  134. /// <summary>
  135. /// The on mouse down.
  136. /// </summary>
  137. /// <param name="e">
  138. /// The event arguments.
  139. /// </param>
  140. protected override void OnMouseDown(MouseButtonEventArgs e)
  141. {
  142. base.OnMouseDown(e);
  143. var hitPlaneOrigin = this.ToWorld(this.Position);
  144. var hitPlaneNormal = this.ToWorld(this.Axis);
  145. var p = e.GetPosition(this.ParentViewport);
  146. var hitPoint = this.GetHitPlanePoint(p, hitPlaneOrigin, hitPlaneNormal);
  147. if (hitPoint != null)
  148. {
  149. this.lastPoint = this.ToLocal(hitPoint.Value);
  150. }
  151. }
  152. /// <summary>
  153. /// The on mouse move.
  154. /// </summary>
  155. /// <param name="e">
  156. /// The event arguments.
  157. /// </param>
  158. protected override void OnMouseMove(MouseEventArgs e)
  159. {
  160. base.OnMouseMove(e);
  161. if (this.IsMouseCaptured)
  162. {
  163. var hitPlaneOrigin = this.ToWorld(this.Position);
  164. var hitPlaneNormal = this.ToWorld(this.Axis);
  165. var position = e.GetPosition(this.ParentViewport);
  166. var hitPoint = this.GetHitPlanePoint(position, hitPlaneOrigin, hitPlaneNormal);
  167. if (hitPoint == null)
  168. {
  169. return;
  170. }
  171. var currentPoint = this.ToLocal(hitPoint.Value);
  172. var v = this.lastPoint - this.Position;
  173. var u = currentPoint - this.Position;
  174. v.Normalize();
  175. u.Normalize();
  176. var currentAxis = Vector3D.CrossProduct(u, v);
  177. double sign = -Vector3D.DotProduct(this.Axis, currentAxis);
  178. double theta = Math.Sign(sign) * Math.Asin(currentAxis.Length) / Math.PI * 180;
  179. this.Value += theta;
  180. if (this.TargetTransform != null)
  181. {
  182. var rotateTransform = new RotateTransform3D(new AxisAngleRotation3D(this.Axis, theta), Pivot);
  183. this.TargetTransform = Transform3DHelper.CombineTransform(rotateTransform, this.TargetTransform);
  184. }
  185. hitPoint = this.GetHitPlanePoint(position, hitPlaneOrigin, hitPlaneNormal);
  186. if (hitPoint != null)
  187. {
  188. this.lastPoint = this.ToLocal(hitPoint.Value);
  189. }
  190. }
  191. }
  192. #endregion
  193. }
  194. }