PageRenderTime 18ms CodeModel.GetById 16ms app.highlight 1ms RepoModel.GetById 1ms 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
 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}