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