[12503] | 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 |
|
---|
| 8 | namespace 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 | }
|
---|