External/OxyPlot/OxyPlot/Foundation/FractionHelper.cs
author StephaneLenclud
Tue, 03 Feb 2015 10:14:18 +0100
branchMiniDisplay
changeset 450 f2d8620e2434
permissions -rw-r--r--
Rebracer update.
moel@391
     1
// --------------------------------------------------------------------------------------------------------------------
moel@391
     2
// <copyright file="FractionHelper.cs" company="OxyPlot">
moel@391
     3
//   The MIT License (MIT)
moel@391
     4
//
moel@391
     5
//   Copyright (c) 2012 Oystein Bjorke
moel@391
     6
//
moel@391
     7
//   Permission is hereby granted, free of charge, to any person obtaining a
moel@391
     8
//   copy of this software and associated documentation files (the
moel@391
     9
//   "Software"), to deal in the Software without restriction, including
moel@391
    10
//   without limitation the rights to use, copy, modify, merge, publish,
moel@391
    11
//   distribute, sublicense, and/or sell copies of the Software, and to
moel@391
    12
//   permit persons to whom the Software is furnished to do so, subject to
moel@391
    13
//   the following conditions:
moel@391
    14
//
moel@391
    15
//   The above copyright notice and this permission notice shall be included
moel@391
    16
//   in all copies or substantial portions of the Software.
moel@391
    17
//
moel@391
    18
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
moel@391
    19
//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
moel@391
    20
//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
moel@391
    21
//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
moel@391
    22
//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
moel@391
    23
//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
moel@391
    24
//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
moel@391
    25
// </copyright>
moel@391
    26
// <summary>
moel@391
    27
//   Generates fraction strings from double values.
moel@391
    28
// </summary>
moel@391
    29
// --------------------------------------------------------------------------------------------------------------------
moel@391
    30
namespace OxyPlot
moel@391
    31
{
moel@391
    32
    using System;
moel@391
    33
    using System.Globalization;
moel@391
    34
moel@391
    35
    /// <summary>
moel@391
    36
    /// Provides functionality to generate fraction strings from double values.
moel@391
    37
    /// </summary>
moel@391
    38
    /// <remarks>
moel@391
    39
    /// Examples: "3/4", "PI/2"
moel@391
    40
    /// </remarks>
moel@391
    41
    public static class FractionHelper
moel@391
    42
    {
moel@391
    43
        /// <summary>
moel@391
    44
        /// Converts a double to a fraction string.
moel@391
    45
        /// </summary>
moel@391
    46
        /// <param name="value">
moel@391
    47
        /// The value.
moel@391
    48
        /// </param>
moel@391
    49
        /// <param name="unit">
moel@391
    50
        /// The unit.
moel@391
    51
        /// </param>
moel@391
    52
        /// <param name="unitSymbol">
moel@391
    53
        /// The unit symbol.
moel@391
    54
        /// </param>
moel@391
    55
        /// <param name="eps">
moel@391
    56
        /// The tolerance.
moel@391
    57
        /// </param>
moel@391
    58
        /// <param name="formatProvider">
moel@391
    59
        /// The format Provider.
moel@391
    60
        /// </param>
moel@391
    61
        /// <returns>
moel@391
    62
        /// The convert to fraction string.
moel@391
    63
        /// </returns>
moel@391
    64
        public static string ConvertToFractionString(
moel@391
    65
            double value,
moel@391
    66
            double unit = 1,
moel@391
    67
            string unitSymbol = null,
moel@391
    68
            double eps = 1e-6,
moel@391
    69
            IFormatProvider formatProvider = null)
moel@391
    70
        {
moel@391
    71
            if (Math.Abs(value) < eps)
moel@391
    72
            {
moel@391
    73
                return "0";
moel@391
    74
            }
moel@391
    75
moel@391
    76
            // ½, ⅝, ¾
moel@391
    77
            value /= unit;
moel@391
    78
moel@391
    79
            // int whole = (int)(value - (int) value);
moel@391
    80
            // int N = 10000;
moel@391
    81
            // int frac = (int) ((value - whole)*N);
moel@391
    82
            // var d = GCF(N,frac);
moel@391
    83
            for (int d = 1; d <= 64; d++)
moel@391
    84
            {
moel@391
    85
                double n = value * d;
moel@391
    86
                var ni = (int)Math.Round(n);
moel@391
    87
                if (Math.Abs(n - ni) < eps)
moel@391
    88
                {
moel@391
    89
                    string nis = unitSymbol == null || ni != 1 ? ni.ToString(CultureInfo.InvariantCulture) : string.Empty;
moel@391
    90
                    if (d == 1)
moel@391
    91
                    {
moel@391
    92
                        return string.Format("{0}{1}", nis, unitSymbol);
moel@391
    93
                    }
moel@391
    94
moel@391
    95
                    return string.Format("{0}{1}/{2}", nis, unitSymbol, d);
moel@391
    96
                }
moel@391
    97
            }
moel@391
    98
moel@391
    99
            return string.Format(formatProvider ?? CultureInfo.CurrentCulture, "{0}{1}", value, unitSymbol);
moel@391
   100
        }
moel@391
   101
moel@391
   102
        /// <summary>
moel@391
   103
        /// Finds the greates common divisor.
moel@391
   104
        /// </summary>
moel@391
   105
        /// <param name="a">
moel@391
   106
        /// The a.
moel@391
   107
        /// </param>
moel@391
   108
        /// <param name="b">
moel@391
   109
        /// The b.
moel@391
   110
        /// </param>
moel@391
   111
        /// <returns>
moel@391
   112
        /// The gcd.
moel@391
   113
        /// </returns>
moel@391
   114
        public static int gcd(int a, int b)
moel@391
   115
        {
moel@391
   116
            if (b == 0)
moel@391
   117
            {
moel@391
   118
                return a;
moel@391
   119
            }
moel@391
   120
moel@391
   121
            return gcd(b, a % b);
moel@391
   122
        }
moel@391
   123
moel@391
   124
        /// <summary>
moel@391
   125
        /// Finds the greatest common factor.
moel@391
   126
        /// </summary>
moel@391
   127
        /// <param name="x">
moel@391
   128
        /// The x.
moel@391
   129
        /// </param>
moel@391
   130
        /// <param name="y">
moel@391
   131
        /// The y.
moel@391
   132
        /// </param>
moel@391
   133
        /// <returns>
moel@391
   134
        /// The gcf.
moel@391
   135
        /// </returns>
moel@391
   136
        private static int GCF(int x, int y)
moel@391
   137
        {
moel@391
   138
            x = Math.Abs(x);
moel@391
   139
            y = Math.Abs(y);
moel@391
   140
            int z;
moel@391
   141
            do
moel@391
   142
            {
moel@391
   143
                z = x % y;
moel@391
   144
                if (z == 0)
moel@391
   145
                {
moel@391
   146
                    return y;
moel@391
   147
                }
moel@391
   148
moel@391
   149
                x = y;
moel@391
   150
                y = z;
moel@391
   151
            }
moel@391
   152
            while (true);
moel@391
   153
        }
moel@391
   154
    }
moel@391
   155
}