Source (adapted for GenericImage) -> http://stackoverflow.com/a/11176961/341706

/// <summary>
        /// Rotates the image.
        /// </summary>
        /// <param name="image">
        /// The source image to rotate.
        /// </param>
        /// <param name="angle">
        /// The angle in degrees to rotate the image.
        /// </param>
        /// <param name="centerX">The x position of the rotation axis.</param>
        /// <param name="centerY">The y position of the rotation axis.</param>
        /// <returns>
        /// Returns a new rotated image.
        /// </returns>
        public static GenericImage<T> Rotate<T>(this GenericImage<T> image, int centerX, int centerY, float angle)
        {
            // source (adapted for GenericImage) -> http://stackoverflow.com/a/11176961/341706
            var radians = (Math.PI / 180) * angle;
            var cos = Math.Cos(radians);
            var sin = Math.Sin(radians);
            var newImage = new GenericImage<T>(image.Width, image.Height);

            for (var x = 0; x < image.Width; x++)
                for (var y = 0; y < image.Height; y++)
                {
                    var m = x - centerX;
                    var n = y - centerY;
                    var j = ((int)(m * cos + n * sin)) + centerX;
                    var k = ((int)(n * cos - m * sin)) + centerY;
                    if (j >= 0 && j < image.Width && k >= 0 && k < image.Height)
                    {
                        newImage[x, y] = image[j, k];
                    }
                }

            return newImage;
        }

Source -> http://stackoverflow.com/questions/10322341/simple-algorithm-for-drawing-filled-ellipse-in-c-c

/// <summary>
        /// Draws a filled Ellipse.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="x">
        /// The x left most position of the ellipse.
        /// </param>
        /// <param name="y">
        /// The y top most position of the ellipse.
        /// </param>
        /// <param name="width">
        /// The width of the ellipse.
        /// </param>
        /// <param name="height">
        /// The height of the ellipse.
        /// </param>
        /// <param name="color">
        /// The color to use.
        /// </param>
        public static void FillEllipse<T>(this GenericImage<T> image, int x, int y, int width, int height, T color)
        {
            width = width / 2;
            height = height / 2;
            var centerX = x + width;
            var centerY = y + height;

            // source -> http://stackoverflow.com/questions/10322341/simple-algorithm-for-drawing-filled-ellipse-in-c-c
            for (var indexY = -height; indexY <= height; indexY++)
            {
                for (var indexX = -width; indexX <= width; indexX++)
                {
                    var dx = indexX / (double)width;
                    var dy = indexY / (double)height;
                    if (dx * dx + dy * dy <= 1)
                    {
                        image[centerX + indexX, centerY + indexY] = color;
                    }
                }
            }
        }

Source (converted from C++) -> http://www.dailyfreecode.com/Code/draw-ellipse-midpoint-ellipse-algorithm-714.aspx

/// <summary>
        /// Draws a Ellipse.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="centerX">
        /// The x center position of the circle.
        /// </param>
        /// <param name="centerY">
        /// The y center position of the circle.
        /// </param>
        /// <param name="width">
        /// The width of the Ellipse.
        /// </param>
        /// <param name="height">
        /// The height of the Ellipse.
        /// </param>
        /// <param name="color">
        /// The color to use.
        /// </param>
        public static void DrawEllipse<T>(this GenericImage<T> image, int centerX, int centerY, int width, int height, T color)
        {
            // source (converted from C++) -> http://www.dailyfreecode.com/Code/draw-ellipse-midpoint-ellipse-algorithm-714.aspx
            float aa = (width * width);
            float bb = (height * height);
            float aa2 = (aa * 2);
            float bb2 = (bb * 2);

            float x = 0;
            float y = height;

            float fx = 0;
            float fy = (aa2 * height);

            float p = (int)(bb - (aa * height) + (0.25 * aa) + 0.5);

            image[(int)(centerX + x), (int)(centerY + y)] = color;
            image[(int)(centerX + x), (int)(centerY - y)] = color;
            image[(int)(centerX - x), (int)(centerY - y)] = color;
            image[(int)(centerX - x), (int)(centerY + y)] = color;

            while (fx < fy)
            {
                x++;
                fx += bb2;

                if (p < 0) p += (fx + bb);

                else
                {
                    y--;
                    fy -= aa2;
                    p += (fx + bb - fy);
                }

                image[(int)(centerX + x), (int)(centerY + y)] = color;
                image[(int)(centerX + x), (int)(centerY - y)] = color;
                image[(int)(centerX - x), (int)(centerY - y)] = color;
                image[(int)(centerX - x), (int)(centerY + y)] = color;
            }

            p = (int)((bb * (x + 0.5) * (x + 0.5)) + (aa * (y - 1) * (y - 1)) - (aa * bb) + 0.5);

            while (y > 0)
            {
                y--;
                fy -= aa2;

                if (p >= 0) p += (aa - fy);

                else
                {
                    x++;
                    fx += bb2;
                    p += (fx + aa - fy);
                }

                image[(int)(centerX + x), (int)(centerY + y)] = color;
                image[(int)(centerX + x), (int)(centerY - y)] = color;
                image[(int)(centerX - x), (int)(centerY - y)] = color;
                image[(int)(centerX - x), (int)(centerY + y)] = color;
            }
        }


Source -> http://www.dailyfreecode.com/code/fill-circle-scan-line-circle-fill-675.aspx

/// <summary>
        /// Fills a circle.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="centerX">
        /// The x center position of the circle.
        /// </param>
        /// <param name="centerY">
        /// The y center position of the circle.
        /// </param>
        /// <param name="radius">
        /// The radius of the circle.
        /// </param>  
        /// <param name="color">
        /// The color to use.
        /// </param>    
        public static void FillCircle<T>(this GenericImage<T> image, int centerX, int centerY, int radius, T color)
        {
            // source -> http://www.dailyfreecode.com/code/fill-circle-scan-line-circle-fill-675.aspx
            int x1;
            int x2;

            var counter = (centerY + radius);

            for (var count = (centerY - radius); count <= counter; count++)
            {
                x1 = (int)(centerX + Math.Sqrt((radius * radius) - ((count - centerY) * (count - centerY))) + 0.5);
                x2 = (int)(centerX - Math.Sqrt((radius * radius) - ((count - centerY) * (count - centerY))) + 0.5);

                image.DrawLine(x1, count, x2, count, color);
            }
        }


Source (converted from Java) -> http://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm#Java

/// <summary>
        /// Draws a circle.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="centerX">
        /// The x center position of the circle.
        /// </param>
        /// <param name="centerY">
        /// The y center position of the circle.
        /// </param>
        /// <param name="radius">
        /// The radius of the circle.
        /// </param>  
        /// <param name="color">
        /// The color to use.
        /// </param>    
        public static void DrawCircle<T>(this GenericImage<T> image, int centerX, int centerY, int radius, T color)
        {
            // source (converted from Java) -> http://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm#Java
            var d = (5 - radius * 4) / 4;
            var x = 0;
            var y = radius;

            do
            {
                // ensure index is in range before setting (depends on your image implementation)
                // in this case we check if the pixel location is within the bounds of the image before setting the pixel
                image[centerX + x, centerY + y] = color;
                image[centerX + x, centerY - y] = color;
                image[centerX - x, centerY + y] = color;
                image[centerX - x, centerY - y] = color;
                image[centerX + y, centerY + x] = color;
                image[centerX + y, centerY - x] = color;
                image[centerX - y, centerY + x] = color;
                image[centerX - y, centerY - x] = color;
                if (d < 0)
                {
                    d += 2 * x + 1;
                }
                else
                {
                    d += 2 * (x - y) + 1;
                    y--;
                }
                x++;
            } while (x <= y);
        }


Source (converted from C) -> http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C

/// <summary>
        /// Draws a line on an <see cref="GenericImage{T}"/>.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="x1">
        /// The x position for the start of the line.
        /// </param>
        /// <param name="y1">
        /// The y position for the start of the line.
        /// </param>
        /// <param name="x2">
        /// The x position for the end of the line.
        /// </param>
        /// <param name="y2">
        /// The y position for the end of the line.
        /// </param>
        /// <param name="color">
        /// The color that the line will be drawn with.
        /// </param>
        public static void DrawLine<T>(this GenericImage<T> image, int x1, int y1, int x2, int y2, T color)
        {
            // source (converted from C) -> http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C
            int dx = Math.Abs(x2 - x1), sx = x1 < x2 ? 1 : -1;
            int dy = Math.Abs(y2 - y1), sy = y1 < y2 ? 1 : -1;
            int err = (dx > dy ? dx : -dy) / 2;

            for (; ; )
            {
                image[x1, y1] = color;
                if (x1 == x2 && y1 == y2) break;
                int e2 = err;
                if (e2 > -dx) { err -= dy; x1 += sx; }
                if (e2 < dy) { err += dx; y1 += sy; }
            }
        }

You can get access to the build order for scenes in your editor scripts by calling EditorBuildSettings.scenes. This allows you to control what scenes are included with the build through your editor code.

    public class SceneDump
    {
        [MenuItem("Codefarts/Dump Scenes")]
        public static void Dump()
        {
            var parts = from part in EditorBuildSettings.scenes
                        select string.Format("{0} - {1}", part.enabled, part.path);

            Debug.Log(string.Join("\r\n", parts.ToArray()));
        }
    }

DumpScenes


If you have some editor scripts and you want to detect weather or not unity has compiled your scripts you can try this simple method.

Created a private class within your editor window and declare a field of that private class.

public class YourEditor : EditorWindow
{
    private RecompileClass recompile;

    private class RecompileClass
    {  
    }
}

In the OnGUI method (or where appropriate) perform a check to see if the field is null. If it’s null you can assume that unity compiled your scripts again so do what you need to do is create a new instance of the private class and assign it to the field.

public class YourEditor : EditorWindow
{
    private RecompileClass recompile;
      
    private class RecompileClass
    {
    }

    public void OnGUI()
    {
        // check if recompile variable is null 
        if (this.recompile == null  )
        {
            // if yes assume recompile then create a reference to a recompile class 
            this.recompile = new RecompileClass();

            // do what you need to do here after detecting a recompile  
        }

        // do regular stuff here
    }
}

The next time unity recompiles your scripts the field will loose it’s reference and will be null again.


    using System;
    using System.Collections.Generic;

    /// <summary>
    /// Implements a generic equality comparer that uses a callback to perform the comparison.
    /// </summary>
    /// <typeparam name="T">The type we want to compare.</typeparam>
    public class EqualityComparerCallback<T> : IEqualityComparer<T>
    {
        /// <summary>
        /// Holds a reference to the callback that handles comparisons.
        /// </summary>
        private readonly Func<T, T, bool> function;

        /// <summary>
        /// Holds a reference to the callback used to calculate hash codes.
        /// </summary>
        private Func<T, int> hashFunction;
      
        /// <summary>
        /// Initializes a new instance of the <see cref="EqualityComparerCallback{T}"/> class.
        /// </summary>
        /// <param name="func">
        /// The callback function that will do the comparing.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Throws a <see cref="ArgumentNullException"/> if the <see cref="func"/> parameter is null.
        /// </exception>
        public EqualityComparerCallback(Func<T, T, bool> func)
        {
            if (func == null)
            {
                throw new ArgumentNullException("func");
            }

            this.function = func;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="EqualityComparerCallback{T}"/> class.
        /// </summary>
        /// <param name="func">
        /// The callback function that will do the comparing.
        /// </param>
        /// <param name="hash">
        /// The callback function that will return the hash code.
        /// </param>  
        public EqualityComparerCallback(Func<T, T, bool> func, Func<T, int> hash)
            : this(func)
        {
            this.hashFunction = hash;
        }

        /// <summary>
        /// Gets or sets the callback function to use to compute the hash.
        /// </summary>
        public Func<T, int> HashFunction
        {
            get
            {
                return this.hashFunction;
            }

            set
            {
                this.hashFunction = value;
            }
        }
                  
        /// <summary>
        /// Provides a static method for returning a <see cref="EqualityComparerCallback{T}"/> type.
        /// </summary>
        /// <param name="func">
        /// The callback function that will do the comparing.
        /// </param>
        /// <returns>Returns a new instance of a <see cref="EqualityComparerCallback{T}"/> type.</returns>
        public static IEqualityComparer<T> Compare(Func<T, T, bool> func)
        {
            return new EqualityComparerCallback<T>(func);
        }

        /// <summary>
        /// Determines whether the specified object instances are considered equal.
        /// </summary>
        /// <param name="x">The first object to compare.</param>
        /// <param name="y">The second object to compare.</param>
        /// <returns>True if the objects are considered equal otherwise, false. If both objA and objB are null, the method returns true.</returns>
        public bool Equals(T x, T y)
        {
            return this.function(x, y);
        }    

        /// <summary>
        /// The get hash code for a object.
        /// </summary>
        /// <param name="obj">
        /// The object whose hash code will be computed.          
        /// </param>
        /// <returns>
        /// Returns a <see cref="int"/> value representing the hash code.
        /// </returns>
        /// <remarks>If no callback function was set for the <see cref="HashFunction"/> the object default <see cref="GetHashCode"/> method will be used.</remarks>
        public int GetHashCode(T obj)
        {
            if (this.hashFunction == null)
            {
                return obj.GetHashCode();
            }

            return this.hashFunction(obj);
        }
    }

A usage scenario

    // build a list of unique categories
    var list = new List<string>();
    foreach (var rule in this.rules)
    {
        if (string.IsNullOrEmpty(rule.Category ?? string.Empty))
        {
            continue;
        }

        // check if already exists
        if (list.Contains(rule.Category, new EqualityComparerCallback<string>((a, b) => a.Trim() == b.Trim())))
        {
            continue;
        }
    }
    return list.ToArray();

Simple solution to get a MIME type from a file extension. Source –> http://stackoverflow.com/a/7161265/341706

public static class MIMEAssistant
{
  private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
  {
    {"ai", "application/postscript"},
    {"aif", "audio/x-aiff"},
    {"aifc", "audio/x-aiff"},
    {"aiff", "audio/x-aiff"},
    {"asc", "text/plain"},
    {"atom", "application/atom+xml"},
    {"au", "audio/basic"},
    {"avi", "video/x-msvideo"},
    {"bcpio", "application/x-bcpio"},
    {"bin", "application/octet-stream"},
    {"bmp", "image/bmp"},
    {"cdf", "application/x-netcdf"},
    {"cgm", "image/cgm"},
    {"class", "application/octet-stream"},
    {"cpio", "application/x-cpio"},
    {"cpt", "application/mac-compactpro"},
    {"csh", "application/x-csh"},
    {"css", "text/css"},
    {"dcr", "application/x-director"},
    {"dif", "video/x-dv"},
    {"dir", "application/x-director"},
    {"djv", "image/vnd.djvu"},
    {"djvu", "image/vnd.djvu"},
    {"dll", "application/octet-stream"},
    {"dmg", "application/octet-stream"},
    {"dms", "application/octet-stream"},
    {"doc", "application/msword"},
    {"docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
    {"dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
    {"docm","application/vnd.ms-word.document.macroEnabled.12"},
    {"dotm","application/vnd.ms-word.template.macroEnabled.12"},
    {"dtd", "application/xml-dtd"},
    {"dv", "video/x-dv"},
    {"dvi", "application/x-dvi"},
    {"dxr", "application/x-director"},
    {"eps", "application/postscript"},
    {"etx", "text/x-setext"},
    {"exe", "application/octet-stream"},
    {"ez", "application/andrew-inset"},
    {"gif", "image/gif"},
    {"gram", "application/srgs"},
    {"grxml", "application/srgs+xml"},
    {"gtar", "application/x-gtar"},
    {"hdf", "application/x-hdf"},
    {"hqx", "application/mac-binhex40"},
    {"htm", "text/html"},
    {"html", "text/html"},
    {"ice", "x-conference/x-cooltalk"},
    {"ico", "image/x-icon"},
    {"ics", "text/calendar"},
    {"ief", "image/ief"},
    {"ifb", "text/calendar"},
    {"iges", "model/iges"},
    {"igs", "model/iges"},
    {"jnlp", "application/x-java-jnlp-file"},
    {"jp2", "image/jp2"},
    {"jpe", "image/jpeg"},
    {"jpeg", "image/jpeg"},
    {"jpg", "image/jpeg"},
    {"js", "application/x-javascript"},
    {"kar", "audio/midi"},
    {"latex", "application/x-latex"},
    {"lha", "application/octet-stream"},
    {"lzh", "application/octet-stream"},
    {"m3u", "audio/x-mpegurl"},
    {"m4a", "audio/mp4a-latm"},
    {"m4b", "audio/mp4a-latm"},
    {"m4p", "audio/mp4a-latm"},
    {"m4u", "video/vnd.mpegurl"},
    {"m4v", "video/x-m4v"},
    {"mac", "image/x-macpaint"},
    {"man", "application/x-troff-man"},
    {"mathml", "application/mathml+xml"},
    {"me", "application/x-troff-me"},
    {"mesh", "model/mesh"},
    {"mid", "audio/midi"},
    {"midi", "audio/midi"},
    {"mif", "application/vnd.mif"},
    {"mov", "video/quicktime"},
    {"movie", "video/x-sgi-movie"},
    {"mp2", "audio/mpeg"},
    {"mp3", "audio/mpeg"},
    {"mp4", "video/mp4"},
    {"mpe", "video/mpeg"},
    {"mpeg", "video/mpeg"},
    {"mpg", "video/mpeg"},
    {"mpga", "audio/mpeg"},
    {"ms", "application/x-troff-ms"},
    {"msh", "model/mesh"},
    {"mxu", "video/vnd.mpegurl"},
    {"nc", "application/x-netcdf"},
    {"oda", "application/oda"},
    {"ogg", "application/ogg"},
    {"pbm", "image/x-portable-bitmap"},
    {"pct", "image/pict"},
    {"pdb", "chemical/x-pdb"},
    {"pdf", "application/pdf"},
    {"pgm", "image/x-portable-graymap"},
    {"pgn", "application/x-chess-pgn"},
    {"pic", "image/pict"},
    {"pict", "image/pict"},
    {"png", "image/png"}, 
    {"pnm", "image/x-portable-anymap"},
    {"pnt", "image/x-macpaint"},
    {"pntg", "image/x-macpaint"},
    {"ppm", "image/x-portable-pixmap"},
    {"ppt", "application/vnd.ms-powerpoint"},
    {"pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation"},
    {"potx","application/vnd.openxmlformats-officedocument.presentationml.template"},
    {"ppsx","application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
    {"ppam","application/vnd.ms-powerpoint.addin.macroEnabled.12"},
    {"pptm","application/vnd.ms-powerpoint.presentation.macroEnabled.12"},
    {"potm","application/vnd.ms-powerpoint.template.macroEnabled.12"},
    {"ppsm","application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},
    {"ps", "application/postscript"},
    {"qt", "video/quicktime"},
    {"qti", "image/x-quicktime"},
    {"qtif", "image/x-quicktime"},
    {"ra", "audio/x-pn-realaudio"},
    {"ram", "audio/x-pn-realaudio"},
    {"ras", "image/x-cmu-raster"},
    {"rdf", "application/rdf+xml"},
    {"rgb", "image/x-rgb"},
    {"rm", "application/vnd.rn-realmedia"},
    {"roff", "application/x-troff"},
    {"rtf", "text/rtf"},
    {"rtx", "text/richtext"},
    {"sgm", "text/sgml"},
    {"sgml", "text/sgml"},
    {"sh", "application/x-sh"},
    {"shar", "application/x-shar"},
    {"silo", "model/mesh"},
    {"sit", "application/x-stuffit"},
    {"skd", "application/x-koan"},
    {"skm", "application/x-koan"},
    {"skp", "application/x-koan"},
    {"skt", "application/x-koan"},
    {"smi", "application/smil"},
    {"smil", "application/smil"},
    {"snd", "audio/basic"},
    {"so", "application/octet-stream"},
    {"spl", "application/x-futuresplash"},
    {"src", "application/x-wais-source"},
    {"sv4cpio", "application/x-sv4cpio"},
    {"sv4crc", "application/x-sv4crc"},
    {"svg", "image/svg+xml"},
    {"swf", "application/x-shockwave-flash"},
    {"t", "application/x-troff"},
    {"tar", "application/x-tar"},
    {"tcl", "application/x-tcl"},
    {"tex", "application/x-tex"},
    {"texi", "application/x-texinfo"},
    {"texinfo", "application/x-texinfo"},
    {"tif", "image/tiff"},
    {"tiff", "image/tiff"},
    {"tr", "application/x-troff"},
    {"tsv", "text/tab-separated-values"},
    {"txt", "text/plain"},
    {"ustar", "application/x-ustar"},
    {"vcd", "application/x-cdlink"},
    {"vrml", "model/vrml"},
    {"vxml", "application/voicexml+xml"},
    {"wav", "audio/x-wav"},
    {"wbmp", "image/vnd.wap.wbmp"},
    {"wbmxl", "application/vnd.wap.wbxml"},
    {"wml", "text/vnd.wap.wml"},
    {"wmlc", "application/vnd.wap.wmlc"},
    {"wmls", "text/vnd.wap.wmlscript"},
    {"wmlsc", "application/vnd.wap.wmlscriptc"},
    {"wrl", "model/vrml"},
    {"xbm", "image/x-xbitmap"},
    {"xht", "application/xhtml+xml"},
    {"xhtml", "application/xhtml+xml"},
    {"xls", "application/vnd.ms-excel"},                        
    {"xml", "application/xml"},
    {"xpm", "image/x-xpixmap"},
    {"xsl", "application/xml"},
    {"xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
    {"xltx","application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
    {"xlsm","application/vnd.ms-excel.sheet.macroEnabled.12"},
    {"xltm","application/vnd.ms-excel.template.macroEnabled.12"},
    {"xlam","application/vnd.ms-excel.addin.macroEnabled.12"},
    {"xlsb","application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
    {"xslt", "application/xslt+xml"},
    {"xul", "application/vnd.mozilla.xul+xml"},
    {"xwd", "image/x-xwindowdump"},
    {"xyz", "chemical/x-xyz"},
    {"zip", "application/zip"}
  };

  public static string GetMIMEType(string fileName)
  {
    if (Path.GetExtension(fileName).Length > 1 && MIMETypesDictionary.ContainsKey(Path.GetExtension(fileName).Remove(0, 1)))
    {
      return MIMETypesDictionary[Path.GetExtension(fileName).Remove(0, 1)];
    }
    return "unknown/unknown";
  }
}

Created by: X

Just another personal website in this crazy online world

Name of author Dean Lunz (aka Created by: X)
Computer programming nerd, and tech geek.
About Me -- Resume