PageRenderTime 38ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/Main/src/DynamicDataDisplay/ViewportConstraints/PhysicalProportionsConstraint.cs

#
C# | 93 lines | 60 code | 10 blank | 23 comment | 8 complexity | 7f0135b5bc806fdd01ab9daa64e5754c MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Diagnostics;
  7. namespace Microsoft.Research.DynamicDataDisplay.ViewportConstraints
  8. {
  9. /// <summary>
  10. /// Represents a restriction in which actual visible rect's proportions depends on
  11. /// actual output rect's proportions.
  12. /// </summary>
  13. public sealed class PhysicalProportionsConstraint : ViewportConstraint
  14. {
  15. /// <summary>
  16. /// Initializes a new instance of the <see cref="PhysicalProportionsConstraint"/> class.
  17. /// </summary>
  18. public PhysicalProportionsConstraint() { }
  19. /// <summary>
  20. /// Initializes a new instance of the <see cref="PhysicalProportionsConstraint"/> class with the given proportion ratio.
  21. /// </summary>
  22. /// <param name="proportionRatio">The proportion ratio.</param>
  23. public PhysicalProportionsConstraint(double proportionRatio)
  24. {
  25. ProportionRatio = proportionRatio;
  26. }
  27. private double proportionRatio = 1.0;
  28. /// <summary>Gets or sets the proportion ratio (width / height). Default value is 1.0.</summary>
  29. /// <value>The proportion ratio.</value>
  30. public double ProportionRatio
  31. {
  32. get { return proportionRatio; }
  33. set
  34. {
  35. if (proportionRatio != value)
  36. {
  37. proportionRatio = value;
  38. RaiseChanged();
  39. }
  40. }
  41. }
  42. /// <summary>
  43. /// Applies the restriction.
  44. /// </summary>
  45. /// <param name="previousDataRect">Previous data rectangle.</param>
  46. /// <param name="proposedDataRect">Proposed data rectangle.</param>
  47. /// <param name="viewport">The viewport, to which current restriction is being applied.</param>
  48. /// <returns>New changed visible rectangle.</returns>
  49. public override DataRect Apply(DataRect previousDataRect, DataRect proposedDataRect, Viewport2D viewport)
  50. {
  51. Rect output = viewport.Output;
  52. if (output.Height == 0 || output.Width == 0)
  53. return proposedDataRect;
  54. double newRatio = proposedDataRect.Width * output.Height /
  55. (proposedDataRect.Height * output.Width);
  56. // Don't modify rect if new ratio differs only slightly
  57. if (Math.Abs(newRatio - proportionRatio) < 1e-3)
  58. return proposedDataRect;
  59. // Try to keep visible rect's square constant
  60. double width = proposedDataRect.Width, height = proposedDataRect.Height;
  61. double square = proposedDataRect.Width * proposedDataRect.Height;
  62. if (square > 0)
  63. {
  64. width = Math.Sqrt(proportionRatio * output.Width * square / output.Height);
  65. height = Math.Sqrt(output.Height * square / (proportionRatio * output.Width));
  66. }
  67. // Finally ensure we have correct aspect ratio
  68. double delta = (proportionRatio * height * output.Width - width * output.Height) /
  69. (output.Height + proportionRatio * output.Width);
  70. width += delta;
  71. height -= delta;
  72. double x0 = (proposedDataRect.XMax + proposedDataRect.XMin) / 2;
  73. double y0 = (proposedDataRect.YMax + proposedDataRect.YMin) / 2;
  74. return new DataRect
  75. {
  76. XMin = x0 - width / 2,
  77. Width = width,
  78. YMin = y0 - height / 2,
  79. Height = height
  80. };
  81. }
  82. }
  83. }