Subversion Repositories AndroidProjects

Rev

Rev 817 | Blame | Compare with Previous | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BauzoidNET.math
{
    public class MathUtil
    {
        public const float EPSILON = 0.0000001f;

        /// <summary>
        /// Check if value is in range (inclusive).
        /// </summary>
        public static bool isInRange(float value, float min, float max)
        {
            return ((value >= min) && (value <= max));
        }

        /// <summary>
        /// Check if value is in range (inclusive min, exclusive max).
        /// </summary>
            public static bool isInRangeInEx(float value, float min, float max)
            {
                    return ((value >= min) && (value < max));          
            }

        /// <summary>
        /// Check if value is in range (exclusive min, inclusive max).
        /// </summary>
            public static bool isInRangeExIn(float value, float min, float max)
            {
                    return ((value > min) && (value <= max));          
            }

        /// <summary>
        /// Check if value is in range (exclusive).
        /// </summary>
            public static bool isInRangeEx(float value, float min, float max)
            {
                    return ((value > min) && (value < max));           
            }

        /// <summary>
        /// Check if value is in range (inclusive).
        /// </summary>
            public static bool isInRange(int value, int min, int max)
            {
                    return ((value >= min) && (value <= max));
            }

        /// <summary>
        /// Clamp value to range.
        /// </summary>
            public static float clamp(float value, float min, float max)
            {
                    if (value < min)
                            return min;
                    if (value > max)
                            return max;
                    return value;
            }

        /// <summary>
        /// Clamp value to range.
        /// </summary>
            public static int clamp(int value, int min, int max)
            {
                    if (value < min)
                            return min;
                    if (value > max)
                            return max;
                    return value;
            }

        /// <summary>
        /// Float-based sine function in degrees.
        /// </summary>
            public static float sin(float degrees)
            {
                    return (float)Math.Sin(degToRad(degrees));
            }

        /// <summary>
        /// Float-based cosine function in degrees.
        /// </summary>
            public static float cos(float degrees)
            {
                    return (float)Math.Cos(degToRad(degrees));
            }

        /// <summary>
        /// Float-based tangent function in degrees.
        /// </summary>
            public static float tan(float degrees)
            {
                    return (float)Math.Tan(degToRad(degrees));
            }

        /// <summary>
        /// Convert from degrees to radians.
        /// </summary>
            public static float degToRad(float degrees)
            {
                    return (float)(degrees * Math.PI / 180.0f);
            }

        /// <summary>
        /// Convert from radians to degrees.
        /// </summary>
            public static float radToDeg(float rad)
            {
                    return (float)(rad * 180.0f / Math.PI);
            }

        /// <summary>
        /// Return the angle inside a range of 0 to 360 degrees.
        /// </summary>
            public static float stayInDegrees0to360(float degrees)
            {
                    float result = degrees;
                    while (result > 360.0f)
                            result -= 360.0f;
                    while (result < 0.0f)
                            result += 360.0f;
                    return result;
            }

        /// <summary>
        /// Return the (smaller) angle in degrees between the two angles.
        /// </summary>
            public static float turnDegrees(float rot1, float rot2)
            {
                    if (Math.Abs(rot1 - rot2) > (180.0f))
                    {
                            if (rot1 < rot2)
                            {
                                    rot1 += 360.0f;
                            }
                            else
                            {
                                    rot1 -= 360.0f;
                            }
                    }
            return Math.Abs(rot2 - rot1);
            }

        /// <summary>
        /// Convert RGB values to HSV values
        /// </summary>
        public static Vector3 rgbToHsv(Vector3 rgbColor)
        {
            float r = rgbColor.x;
            float g = rgbColor.y;
            float b = rgbColor.z;

            float h = 0;
            float s = 0;
            float v = 0;

            float min = rgbColor.min();
            float max = rgbColor.max();

            v = max;

            float delta = max - min;
            if (v != 0)
            {
                r /= v;
                g /= v;
                b /= v;
                Vector3 rgb = new Vector3(r, g, b);
                min = rgb.min();
                max = rgb.max();

                s = max - min;
                if (s == 0)
                {
                    h = 0;
                    return new Vector3(h, s, v);
                }

                rgb.x = (rgb.x - min) / (max - min);
                rgb.y = (rgb.y - min) / (max - min);
                rgb.z = (rgb.z - min) / (max - min);
                min = rgb.min();
                max = rgb.max();

                if (max == rgb.x)
                {
                    h = 0.0f + 60.0f * (rgb.y - rgb.z);
                    if (h < 0.0f)
                        h += 360.0f;
                }
                else if (max == rgb.y)
                {
                    h = 120.0f + 60.0f * (rgb.z - rgb.x);
                }
                else
                {
                    h = 240.0f + 60.0f * (rgb.x - rgb.y);
                }

                //h = hueDegrees / 360.0f;



                /*s = delta / max;

                if (r == max)
                    h = (g - b) / delta;
                else if (g == max)
                    h = 2 + (b - r) / delta;
                else
                    h = 4 + (r - g) / delta;

                h *= 60;

                if (h < 0)
                    h += 360;*/

            }
            else
            {
                s = 0;
                h = 0;
            }

            return new Vector3(h, s, v);
        }

        /// <summary>
        /// Convert HSV values to RGBvalues
        /// </summary>
        public static Vector3 hsvToRgb(Vector3 hsvColor)
        {
            float h = hsvColor.x;
            float s = hsvColor.y;
            float v = hsvColor.z;

            //if (h == 1.0f)
            //    h = 0.0f;

            float r = 0;
            float g = 0;
            float b = 0;

            if (s == 0)
            {
                // achromatic (grey)
                r = v;
                g = v;
                b = v;
            }
            else
            {
                /*h /= 60;
                int i = (int)Math.Floor(h);
                float f = h - i;    // factorial part of h
                float p = v * (1 - s);
                float q = v * (1 - s * f);
                float t = v * (1 - s * (1 - f));*/


                double step = 1.0 / 60.0;
                double vh = h * step;

                int i = (int)System.Math.Floor(vh);

                float f = (float)(vh - i);
                float p = (float)(v * (1.0 - s));
                float q = (float)(v * (1.0 - (s * f)));
                float t = (float)(v * (1.0 - (s * (1.0 - f))));

                switch(i)
                {
                    case 0:
                        r = v;
                        g = t;
                        b = p;
                        break;
                    case 1:
                        r = q;
                        g = v;
                        b = p;
                        break;
                    case 2:
                        r = p;
                        g = v;
                        b = t;
                        break;
                    case 3:
                        r = p;
                        g = q;
                        b = v;
                        break;
                    case 4:
                        r = t;
                        g = p;
                        b = v;
                        break;
                    default:
                        r = v;
                        g = p;
                        b = q;
                        break;
                }
            }

            return new Vector3(r, g, b);
        }
    }
}