<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Thomas Bernal &#187; C#</title>
	<atom:link href="http://davidthomasbernal.com/blog/category/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://davidthomasbernal.com/blog</link>
	<description>Codeasaurus-rex</description>
	<lastBuildDate>Wed, 12 May 2010 05:48:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>C# Image Processing Performance &#8211; Unsafe vs. Safe code, Part II</title>
		<link>http://davidthomasbernal.com/blog/2008/03/14/c-image-processing-performance-unsafe-vs-safe-code-part-ii/</link>
		<comments>http://davidthomasbernal.com/blog/2008/03/14/c-image-processing-performance-unsafe-vs-safe-code-part-ii/#comments</comments>
		<pubDate>Fri, 14 Mar 2008 09:46:33 +0000</pubDate>
		<dc:creator>David Thomas Bernal</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.obnoxiouslyverbose.com/9/c-image-processing-performance-unsafe-vs-safe-code-part-ii</guid>
		<description><![CDATA[In Part I of this article, I outlined a method of performing pixel-level operations on an image that required neither unsafe code, nor the use of the GetPixel and SetPixel methods, which are notoriously slow. The one thing I neglected to include was an actual comparison of the IntPtr and pointer methods with the GetPixel\SetPixel [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://davidthomasbernal.com/blog/8/c-image-processing-performance-unsafe-vs-safe-code-part-i">Part I of this article</a>, I outlined a method of performing pixel-level operations on an image that required neither unsafe code, nor the use of the <code>GetPixel</code> and <code>SetPixel</code> methods, which are notoriously slow. The one thing I neglected to include was an actual comparison of the <code>IntPtr</code> and pointer methods with the <code>GetPixel\SetPixel</code> methods. As such, I present such a method below. It looks tantalizingly simple, but we&#8217;ll soon see that it is basically worthless.</p>

<pre><code>public Image ThresholdGS(float thresh)
{
    Bitmap b = new Bitmap(_image);

    for (int i = 0; i &lt; b.Height; ++i)
    {
        for (int j = 0; j &lt; b.Width; ++j)
        {
            Color c = b.GetPixel(j, i);

            double magnitude = 1 / 3d * (c.B+c.G+c.R);

            if (magnitude &lt; thresh)
            {
                b.SetPixel(j,i,Color.FromArgb(0,0,0));
            }
            else
            {
                b.SetPixel(j,i, Color.FromArgb(255,255,255));
            }
        }
    }

    return b;
}
</code></pre>

<h3>Results</h3>

<p>As outlined in the previous post, I created a form that would allow me to run each threshold method repeatedly to find an average time per threshold operation. The results are given in the table below. For these tests, an arbitrary threshold of 125 was chosen. The image used 24 bits-per-color and had a size of 479 x 700 pixels.</p>

<table>
<thead>
<tr>
<th>Algorithm</th>
<th>Total Time (ms)</th>
<th>% Difference</th>
</tr>
</thead>
<tr>
<td colspan="3" style="border-top:1px solid black; border-bottom:1px solid black">
<strong>N=10</strong>
</td>
</tr>
<tr>
<td>
unsafe
</td>
<td>
194
</td>
<td>
0
</td>
</tr>
<tr>
<td>
<code>IntPtr</code>
</td>
<td>
262
</td>
<td>
35%
</td>
</tr>
<td>
<code>GetPixel</code>
</td>
<td>
238,299 (~4 min.)
</td>
<td>
122,734%
<td>
</tr>
<tr>
<td colspan="3" style="border-bottom:1px solid black">
<strong>N=100</strong>
</td>
</tr>
<tr>
<td>
unsafe
</td>
<td>
1951
</td>
<td>
0
</td>
</tr>
<tr>
<td>
<code>IntPtr</code>
</td>
<td>
2361
</td>
<td>
21%
</td>
</tr>
<tr>
<td colspan="3" style="border-bottom:1px solid black">
<strong>N=500</strong>
</td>
</tr>
<tr>
<td>
unsafe
</td>
<td>
9783
</td>
<td>
0
</td>
</tr>
<tr>
<td>
<code>IntPtr</code>
</td>
<td>
11,499
</td>
<td>
17%
</td>
</tr>
</table>

<p>The first observation is simple: <code>GetPixel\SetPixel</code> SUCKS! It took longer to do 10 operations using that method than it took to do 500 using either of the other two. We also see that the <code>IntPtr</code> method, while not a terrible alternative (if, for some reason, the use of unsafe code was strictly not allowed) is also moderately slower than the pointer method.</p>

<h3>Test Program</h3>

<p>I wrote up a simple test program to perform these tests. It also includes a subjective test, wherein one can select the threshold method and then move a slider to set different threshold values to see how quickly the image changes. The subjective test agrees with the results above.</p>

<p>If you poke around in the program a bit, you&#8217;ll also discover a couple of extras, including some tests of using a square-root-of-squares type method for finding the magnitude of a pixel (applied to thresholding, and grayscaling). There is also a method that allows convolution filters to be applied to the image, though editing the filters is very cumbersome. Expect to see new, more-complete versions this program in the future.</p>

<p>The program and code are attached. The code includes a .sln file. To run the program (if you don&#8217;t download the code), just unzip the .dll and .exe into any directory on your system. To load an image, drag and drop one onto the big empty picture box from your filesystem. You can start the tool I used to generate the numbers by clicking the performance analysis button. If you modify the program in any non-trivial way, or use it or the image processing library in anything else, please notify me. You may not use either the program or the library to make a profit in any way without my express written permission.</p>

<div style="width:30%;margin:0 auto;border:2px dotted black;text-align:center"><a href='http://davidthomasbernal.com/wp-content/uploads/2008/03/shockexecutable.zip' title='Executable'>Executable</a>
<a href='http://davidthomasbernal.com/wp-content/uploads/2008/03/shock.zip' title='Code'>Code</a>
</div>
]]></content:encoded>
			<wfw:commentRss>http://davidthomasbernal.com/blog/2008/03/14/c-image-processing-performance-unsafe-vs-safe-code-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# Image Processing Performance &#8211; Unsafe vs. Safe code, Part I</title>
		<link>http://davidthomasbernal.com/blog/2008/03/13/c-image-processing-performance-unsafe-vs-safe-code-part-i/</link>
		<comments>http://davidthomasbernal.com/blog/2008/03/13/c-image-processing-performance-unsafe-vs-safe-code-part-i/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 09:14:45 +0000</pubDate>
		<dc:creator>David Thomas Bernal</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[image processing]]></category>
		<category><![CDATA[unsafe]]></category>

		<guid isPermaLink="false">http://www.obnoxiouslyverbose.com/8/c-image-processing-performance-unsafe-vs-safe-code-part-i</guid>
		<description><![CDATA[It&#8217;s spring break at my school, and my travel plans fell through, so I&#8217;ve taken some time to get back into one of my favorite topics in C#, image processing. If you&#8217;re not familiar with doing this in C#, I&#8217;d highly encourage you to start reading the great series of articles on the subject by [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s spring break at my school, and my travel plans fell through, so I&#8217;ve taken some time to get back into one of my favorite topics in C#, image processing. If you&#8217;re not familiar with doing this in C#, I&#8217;d highly encourage you to start reading the <a href="http://www.codeproject.com/KB/GDI-plus/csharpgraphicfilters11.aspx">great series of articles</a> on the subject by Code Project user <a href="http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=6556">Christian Graus</a>. Reading and understanding that first article should get you far enough along to be able to follow this one.</p>

<p>I first became interested in C# image processing when I decided for some reason that I should write a program that would allow me to control a media player (e.g., Winamp) on my computer using a webcam and a laser pointer. This remains, to me, an interesting project, but it was simply too audacious for my skill level (and still is, to be honest, as I am but a beginner). One of the first problems I ran into in my naive approach was that using the <code><a href="http://msdn2.microsoft.com/en-us/library/system.drawing.bitmap.getpixel.aspx">Bitmap.Getpixel</a></code> and <code><a href="msdn2.microsoft.com/en-us/library/system.drawing.bitmap.setpixel.aspx">Bitmap.Setpixel</a></code> methods was ridiculously slow. Some quick googling revealed that what I needed was the magic of unsafe code and pointers. I quickly rewrote my functions, and was on my way.</p>

<h3>A Different Approach</h3>

<p>Recently, however, I discovered that there is a middle ground between unsafe code and the <code>Getpixel</code> and <code>Setpixel</code> methods which does not required the use of the unsafe keyword or pointers. I decided to give this a try to see how it performed, both objectively and subjectively.</p>

<p>The key thing to note here was that the Scan0 property of the <code><a href="http://msdn2.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.aspx">BitmapData</a> class</code> is an <code>IntPtr</code> and not a pointer. This means that rather than dropping into an <code>unsafe</code> block, we can simply use the overloads of the <code><a href="http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.marshal.copy.aspx">System.Runtime.InteropServices.Marshal.Copy</a></code> method to copy bytes to and from the location of the image in memory.</p>

<p>To test the performance of this method and the usual unsafe method, I wrote two methods which would each threshold an image. I also created a Windows form with a slider that would allow me to change the threshold value in real time, and watch how quickly the image responded (the subjective part of the test). The reasons I chose thresholding were that it&#8217;s often one of the first things done to an image during machine processing,  and it&#8217;s simple to write. Aside from that, we&#8217;re really only interested in the time consumed by reading and writing the data to the image, which shouldn&#8217;t be affected by the operations perfomed on the data.</p>

<p>The first method, listed below, uses the IntPtr approach.</p>

<pre><code>/*No unsafe keyword!*/
public Image ThresholdMA(float thresh)
{
    Bitmap b = new Bitmap(_image);

    BitmapData bData = b.LockBits(new Rectangle(0, 0, _image.Width, _image.Height), ImageLockMode.ReadWrite, b.PixelFormat);

    /* GetBitsPerPixel just does a switch on the PixelFormat and returns the number */
    byte bitsPerPixel = GetBitsPerPixel(bData.PixelFormat);

    /*the size of the image in bytes */
    int size = bData.Stride * bData.Height;

    /*Allocate buffer for image*/
    byte[] data = new byte[size];

    /*This overload copies data of /size/ into /data/ from location specified (/Scan0/)*/
    System.Runtime.InteropServices.Marshal.Copy(bData.Scan0, data, 0, size);

    for (int i = 0; i &lt; size; i += bitsPerPixel / 8 )
    {
        double magnitude = 1/3d*(data[i] +data[i + 1] +data[i + 2]);
        if (magnitude &lt; thresh)
        {
            data[i] = 0;
            data[i + 1] = 0;
            data[i + 2] = 0;
        }
        else
        {
            data[i] = 255;
            data[i + 1] = 255;
            data[i + 2] = 255;
        }
    }

    /* This override copies the data back into the location specified */
    System.Runtime.InteropServices.Marshal.Copy(data, 0, bData.Scan0, data.Length);

    b.UnlockBits(bData);

    return b;
}
</code></pre>

<p>The second method uses pointers.</p>

<pre><code>/*Note unsafe keyword*/
public unsafe Image ThresholdUA(float thresh)
{
    Bitmap b = new Bitmap(_image);

    BitmapData bData = b.LockBits(new Rectangle(0, 0, _image.Width, _image.Height), ImageLockMode.ReadWrite, b.PixelFormat);

    byte bitsPerPixel = GetBitsPerPixel(bData.PixelFormat);

    /*This time we convert the IntPtr to a ptr*/
    byte* scan0 = (byte*)bData.Scan0.ToPointer();

    for (int i = 0; i &lt; bData.Height; ++i)
    {
        for (int j = 0; j &lt; bData.Width; ++j)
        {
            byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;

            double magnitude = 1/3d*(data[0] + data[1] + data[2]);
            /*Just write the data into memory*/
            if (magnitude &lt; thresh)
            {
                data[0] = 0;
                data[1] = 0;
                data[2] = 0;
            }
            else
            {
                data[0] = 255;
                data[1] = 255;
                data[2] = 255;
            }
        }
    }

    b.UnlockBits(bData);

    return b;
}
</code></pre>

<p>That basically covers the code and approach. In Part II (tomorrow, I promise!!), I&#8217;ll post a full .sln and results of the comparison.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidthomasbernal.com/blog/2008/03/13/c-image-processing-performance-unsafe-vs-safe-code-part-i/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>An LCD Sunset Countdown Timer Using C#, Part 2</title>
		<link>http://davidthomasbernal.com/blog/2008/01/25/an-lcd-sunset-countdown-timer-using-c-part-2/</link>
		<comments>http://davidthomasbernal.com/blog/2008/01/25/an-lcd-sunset-countdown-timer-using-c-part-2/#comments</comments>
		<pubDate>Sat, 26 Jan 2008 03:26:27 +0000</pubDate>
		<dc:creator>David Thomas Bernal</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[LCD]]></category>
		<category><![CDATA[sunset]]></category>

		<guid isPermaLink="false">http://www.obnoxiouslyverbose.com/4/an-lcd-sunset-countdown-timer-using-c-part-2</guid>
		<description><![CDATA[Sorry for the long gap between posts, I&#8217;ve recently moved to a new place, and started school again, so things have been hectic. In any case, back to the timer. In Part 1, I had investigated the options for the LCD plugin, and settled on LCD Smartie. I also implemented the algorithm I would use [...]]]></description>
			<content:encoded><![CDATA[<p>Sorry for the long gap between posts, I&#8217;ve recently moved to a new place, and started school again, so things have been hectic. In any case, back to the timer. In <a href="http://davidthomasbernal.com/resume/3/an-lcd-sunset-countdown-timer-using-c-part-1">Part 1</a>, I had investigated the options for the LCD plugin, and settled on <a href="http://lcdsmartie.sourceforge.net/">LCD Smartie</a>. I also implemented the algorithm I would use to calculate the sunset time in C#. The last step was to create the actual plugin, tying all the elements together.</p>

<p>As previously discussed, LCD Smartie supports .Net plugins already. The requirements are that a public class be created with the name as LCDSmartie. This class can have up to 20 methods called <code>funtion1</code>-<code>function20</code>. These functions should take two strings, and return a string. (For more details, you can check out the <a href="http://lcdsmartie.sourceforge.net/plugins.html">instruction page</a> for plugin authors.)</p>

<p>I wanted to be able to test the function which did the actual counting down, so I created a new solution as a console application, and then added a second project as a library that would actually do the countdown. Structuring the solution this way makes it so that both a .dll and an .exe are generated when the project is compiled.</p>

<p>My <code>function1</code> looks like this:</p>

<pre><code>public string function1(string a, string b)
{
    DateTime sunset = Sunset(DateTime.Now);

    if (DateTime.Compare(sunset, DateTime.Now) &lt; 0)
        sunset = Sunset(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day + 1));

    //doing this subtraction returns a TimeSpan object, whose ToString method I call
    return (sunset - DateTime.Now).ToString();

}
</code></pre>

<p>The return value of this function is a string representing the amount of time between now and sunset. If the sunset has already happened today (a very depressing turn of events indeed), it counts down till tomorrow&#8217;s sunset.</p>

<p>After testing my function using the the console application, the final step was to get LCD Smartie to call my <code>function1</code> and send the output to the LCD. In line with the rest of the software&#8217;s philosophy, this was quite simple. All I had to do was copy the .dll to Smartie&#8217;s plugin directory, and then go to the configuration screen. The screen has a formidable look, but is quite simple. To get an item to display on a given line, you just enter that function on that line (my LCD has 4 lines, so there are 4 input boxes). The $dll function is used to call a .dll implementing the plugin interface. It takes 4 arguments: the dll name, the function number, and two strings that will be passed to the function. Below is a screenshot of my configuration screen.</p>

<p><a href="http://davidthomasbernal.com/wp-content/uploads/2008/01/config.png" title="Configuration Screen"></a></p>

<p style="text-align: center"><a href="http://davidthomasbernal.com/wp-content/uploads/2008/01/config.png" title="Configuration Screen"><img src="http://davidthomasbernal.com/wp-content/uploads/2008/01/config.thumbnail.png" alt="Configuration Screen" /></a></p>

<p>One thing to note on this screen is I use the <a href="http://lcdsmartie.sourceforge.net/BigNumPlugin.html" title="Click for info.">BigNum plugin</a> to display multi-line numbers. The plugin is widely configurable, so I&#8217;ll refer you to their site for that information. And finally, a screenshot of LCD Smartie&#8217;s preview window. Unfortunately, I don&#8217;t have any pics of my actual timer available right now.</p>

<p><a href="http://davidthomasbernal.com/wp-content/uploads/2008/01/smartie.png" title="Screenshot of LCD Window"></a></p>

<p style="text-align: center"><a href="http://davidthomasbernal.com/wp-content/uploads/2008/01/smartie.png" title="Screenshot of LCD Window"><img src="http://davidthomasbernal.com/wp-content/uploads/2008/01/smartie.png" alt="Screenshot of LCD Window" /></a></p>

<p>And finally, here is the <a href="http://davidthomasbernal.com/wp-content/uploads/2008/01/smartielcd.cs" title="Code for LCD Smartie plugin.">code for LCD Smartie plugin.</a> This is self-contained enough that I will just release the .cs file, but if you have any trouble configuring the solution or projects, let me know. For more complicated projects in the future, I will release full .slns. This code is in the public domain, but if you happen to do something interesting with it, or find it useful, it would be nice if you let me know.<a href="http://davidthomasbernal.com/wp-content/uploads/2008/01/smartielcd.cs" title="Code for LCD Smartie plugin.">
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidthomasbernal.com/blog/2008/01/25/an-lcd-sunset-countdown-timer-using-c-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An LCD Sunset Countdown Timer Using C#, Part 1</title>
		<link>http://davidthomasbernal.com/blog/2008/01/09/an-lcd-sunset-countdown-timer-using-c-part-1/</link>
		<comments>http://davidthomasbernal.com/blog/2008/01/09/an-lcd-sunset-countdown-timer-using-c-part-1/#comments</comments>
		<pubDate>Wed, 09 Jan 2008 10:14:27 +0000</pubDate>
		<dc:creator>David Thomas Bernal</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[LCD]]></category>
		<category><![CDATA[sunset]]></category>

		<guid isPermaLink="false">http://www.obnoxiouslyverbose.com/blog/3/an-lcd-sunset-countdown-timer-using-c-part-1</guid>
		<description><![CDATA[An important tradition between a few people at my office is the daily viewing of the sunset. I&#8217;m not really sure how exactly, but at some point, it was discovered that from our office parking lot, we have a relatively unhindered view of the beautiful Arizona sunset. Combine this with programmers eager to quit coding [...]]]></description>
			<content:encoded><![CDATA[<p>An important tradition between a few people at <a href="http://www.synapsestudios.com">my office</a> is the daily viewing of the sunset. I&#8217;m not really sure how exactly, but at some point, it was discovered that from our office parking lot, we have a relatively unhindered view of the beautiful Arizona sunset. Combine this with programmers eager to quit coding for a while, and our lack of windows, and you&#8217;ve got a daily ritual. Well, back in December, I was rooting around in<em> The Box</em>, a box of random computer-y ephemera, when I discovered a <a href="http://www.crystalfontz.com/products/632usb/index.html">Crystalfontz USB LCD</a> leftover from a previous project, just sitting there looking sad and lonely. My coworkers quickly came up with the purpose for this thing: a countdown to sunset. We already had <a href="http://www.ambientdevices.com/cat/orb/orborder.html">The Orb</a> setup to grow redder as sunset approached, but found it sometimes was laggy and often lost its signal in our windowless office.</p>

<p>C# is my language of choice for desktop applications, so I immediately set out to find a way to use it to write the controller software for the LCD. At first, I looked to the Crystalfontz LCD <a href="http://www.crystalfontz.com/software/crystalcontrol/index.html">software</a>, but found the software to be poorly documented, and plugins difficult to write, requiring that a DLL be written, which would be loaded by a Windows service running the in the background. After some time fruitlessly spent searching for help on the Crystalfontz forums, I ended up finding a different program entirely: <a href="http://lcdsmartie.sourceforge.net/">LCD Smartie</a>. LCD Smartie has built-in support for writing plugins in .NET, and simply requires that plugin-authors create a class with the same name as their DLL filename, which implements up to 20 public methods named <code>function1</code>-<code>function20</code>.</p>

<p>Knowing that this would do exactly what I wanted, I moved on to calculating the time of sunset. Fortunately, I&#8217;d recently discovered one of those obscure functions that PHP is known for, <a href="http://www.php.net/date_sunset">date_sunset</a>, and more importantly, djwice&#8217;s <a href="http://www.php.net/manual/en/function.date-sunset.php#47838">comment</a>, containing links to information on the algorithm used by this function. I implemented the following sunset function using the algorithm outlined on <a href="http://williams.best.vwh.net/sunrise_sunset_algorithm.htm">this page</a>.</p>

<pre><code>public DateTime Sunset(DateTime date)
{
    int dayOfYear = date.DayOfYear;

    double tApprox = dayOfYear + ((18 - LON / 15) / 24);

    double meanAnomaly = (0.9856 * tApprox) - 3.289;

    double sunTrueLon = meanAnomaly + (1.916 * Sin(meanAnomaly)) + (0.020 * Sin(2 * meanAnomaly)) + 282.634;

    if (sunTrueLon &gt; 360) while (sunTrueLon &gt; 360) sunTrueLon -= 360;
    if (sunTrueLon &lt; 0) while (sunTrueLon &lt; 0) sunTrueLon += 360;

    double rightAscension = Atan(0.91764 * Tan(sunTrueLon));

    if (rightAscension &gt; 360) while (rightAscension &gt; 360) rightAscension -= 360;
    if (rightAscension &lt; 0) while (rightAscension &lt; 0) rightAscension += 360;

    rightAscension = rightAscension + 90 * (Math.Floor(sunTrueLon / 90) - Math.Floor(rightAscension / 90));

    rightAscension = rightAscension / 15;

    double sinDec = .39782 * Sin(sunTrueLon);
    double cosDec = Cos(Asin(sinDec));

    double cosHour = (Cos(ZENITH) - sinDec * Sin(LAT)) / (cosDec * Cos(LAT));

    double hour = Acos(cosHour) / 15;

    double time = hour + rightAscension - (0.06571 * tApprox) - 6.622;

    time = time - LON / 15;
    time -= 7;

    while (time &lt; 0) time += 24;
    while (time &gt; 24) time -= 24;

    DateTime sunset = new DateTime(date.Year, date.Month, date.Day, (int)time, (int)((time - (int)time) * 60), 0);

    return sunset;
}
</code></pre>

<p>Since geography is done using degrees, but math is done in radians, I decided to write my own trig functions that handled the conversion for me. I&#8217;m sure you all know how to do that ( :p ), but in case you don&#8217;t, here are cosine and arccosine, from which you should be able to extrapolate to figure out the rest.</p>

<pre><code>private double Cos(double degrees)
{
    return Math.Cos(Math.PI / 180 * degrees);
}

private double Atan(double x)
{
    return 180 / Math.PI * Math.Atan(x);
}
</code></pre>

<p>Also note that I use the constants LAT (latitude), LON (longitude) and <a href="http://en.wikipedia.org/wiki/Zenith_distance">ZENITH</a>. latitude and longitude are simply the ones corresponding to your location (<a href="http://brainoff.com/geocoder/">lookup here</a>), and the standardised value for the zenith is given in the above algorithm link to be 90° 50&#8242;, or 90.83333°. After some fiddling, I found that the above code in fact generated the same exact sunset time as the one printed in my local papers. With that done, I moved on to writing the plugin and tweaking the timer to display well on the LCD.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidthomasbernal.com/blog/2008/01/09/an-lcd-sunset-countdown-timer-using-c-part-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
