<?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>magnetiq.com &#187; Experiments</title>
	<atom:link href="http://magnetiq.com/category/experiments/feed/" rel="self" type="application/rss+xml" />
	<link>http://magnetiq.com</link>
	<description>Ates Goral's Personal Playground and Project Repository</description>
	<lastBuildDate>Thu, 23 Jul 2009 04:10:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Subpixel Scrolltext in JavaScript</title>
		<link>http://magnetiq.com/2008/08/05/subpixel-scrolltext-in-javascript/</link>
		<comments>http://magnetiq.com/2008/08/05/subpixel-scrolltext-in-javascript/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 04:49:50 +0000</pubDate>
		<dc:creator>Ates Goral</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://magnetiq.com/2008/08/05/subpixel-scrolltext-in-javascript/</guid>
		<description><![CDATA[After having it in my to-do list (the &#8220;what if?&#8221; section) for a long time, I&#8217;ve finally managed to spend some time on a JavaScript implementation of a very tiny scrolltext; using a 5&#215;5 font with subpixel rendering (aka ClearType). Knowing what subpixel-rendered static letters look like on an LCD, I wanted to see the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/spst"><img width="130" height="130" src="http://magnetiq.com/wp-content/uploads/2008/08/spst_ss_zoom.gif" alt="Subpixel Scrolltext Snapshot" class="alignleft"/></a>After having it in my to-do list (the &#8220;what if?&#8221; section) for a long time, I&#8217;ve finally managed to spend some time on a <a href="/spst">JavaScript implementation of a very tiny scrolltext</a>; using a <a href="http://www.dafont.com/redensek.font" title="Redensek">5&#215;5 font</a> with <a href="http://en.wikipedia.org/wiki/Subpixel_rendering">subpixel rendering</a> (aka <a href="http://en.wikipedia.org/wiki/ClearType">ClearType</a>). Knowing what subpixel-rendered static letters look like on an LCD, I wanted to see the effect of scrolling them, 1/3 pixel at a time. Note: you need an LCD monitor to see the full effect.<span id="more-76"></span></p>
<p>Since I&#8217;m shifting the letters 1/3 pixel at a time and not as whole pixels, the actual pixels used for rendering the text constantly change color, coming back to the same color every 3 frames. My speculation is, this constant shifting of colors improves the clarity of the text.</p>
<p>An artifact of subpixel rendering is colored halos around letters due to the fact that colored pixels are required to render even completely black text. However, since the colored pixels of the scrolltext keep taking on different colors, they&#8217;re just being perceived as tones of gray. The colored halos are barely noticeable when the text is on the move.</p>
<p>This effect is not evident when <a href="http://www.grc.com/cttech.htm">anti-aliasing</a> (for eliminating color fringing) is fully enabled. When the anti-aliasing level is changed, the effect can be observed on the intermediate buffer that I use as a speed optimization and kept visible for the purpose of this demo. Since the letters on the intermediate buffer are static, the colored halo effect is noticeable:</p>
<p><img width="130" height="20" src="http://magnetiq.com/wp-content/uploads/2008/08/sp_f2.gif" alt="Full anti-aliasing" /></p>
<p>With partial anti-aliasing, the halos are going to get worse:</p>
<p><img width="130" height="20" src="http://magnetiq.com/wp-content/uploads/2008/08/sp_f1.gif" alt="Partial anti-aliasing" /></p>
<p>Finally with anti-aliasing turned off, it&#8217;s a whole mess of bright colors, making the text almost completely unreadable:</p>
<p><img width="130" height="20" src="http://magnetiq.com/wp-content/uploads/2008/08/sp_f0.gif" alt="No anti-aliasing" /></p>
<p>However, if you look at the scrolling text at all anti-aliasing levels, you&#8217;ll observe that even when anti-aliasing is completely turned off, the color halo lessens and what you see is mostly a horribly flickering black text.</p>
]]></content:encoded>
			<wfw:commentRss>http://magnetiq.com/2008/08/05/subpixel-scrolltext-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Burrito 1.0b &#8211; FTP to POP3 Protocol Translator</title>
		<link>http://magnetiq.com/2007/05/07/burito-10b-ftp-to-pop3-protocol-translator/</link>
		<comments>http://magnetiq.com/2007/05/07/burito-10b-ftp-to-pop3-protocol-translator/#comments</comments>
		<pubDate>Mon, 07 May 2007 05:04:19 +0000</pubDate>
		<dc:creator>Ates Goral</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Freeware]]></category>

		<guid isPermaLink="false">http://magnetiq.com/2007/05/07/burito-10b-ftp-to-pop3-protocol-translator/</guid>
		<description><![CDATA[With Burrito you can read and manage your e-mails with any FTP client! It acts as a POP3/FTP protocol translator -- it's actually an FTP server that translates FTP commands to POP3 commands and serves your e-mail messages as individual files. You can view, delete and copy your e-mail messages as if they were files on an FTP server.]]></description>
			<content:encoded><![CDATA[<p>With Burrito you can read and manage your e-mails with any FTP client! It acts as a POP3/FTP protocol translator &#8212; it&#8217;s actually an FTP server that translates FTP commands to POP3 commands and serves your e-mail messages as individual files. You can view, delete and copy your e-mail messages as if they were files on an FTP server.</p>
<div class="download">Download <a href="/downloads/burrito10b.exe">burrito10b.exe</a> (479 KB)</div>
<p><span id="more-14"></span></p>
<p>This is a programming experiment that dates back to 2002. Having played around with POP3 for a while (see <a href="/2006/07/10/e-res-q-13/">E-Res-Q</a>), I just wanted to prove to myself that POP3/FTP protocol translation could work (and I guess I also had more free time back then). Burrito is certainly not a utility that would appeal to the general public, due to its obscure function. The only real-life scenario I can think of is an employee trying to circumvent the company firewall that blocks POP3 traffic (which is something I&#8217;ve experienced first-hand).</p>
<h3>Very Brief Usage Instructions</h3>
<p>The <em>About</em> tab has an <em>Check for update</em> button which takes you back to this site to tell you that you&#8217;re using the most recent version of Burrito (since I currently don&#8217;t have any intentions of releasing updates).</p>
<div class="center">
<p><img src="/wp-content/uploads/2007/05/idle.jpg" width="400" height="313" alt="About Tab"/></p>
<p><small>About Tab</small>
</div>
<p>In the <em>Options</em> tab, you can determine how you&#8217;ll be passing the POP3 username and server to your FTP server. The password that you use for the FTP connection is used as the POP3 server password, so Burrito doesn&#8217;t have to know your password in advance. However, the POP3 username and password must be combined and used as the FTP username. You can change the username-server separator here (defaults to &#8220;\&#8221;).</p>
<p>You can also configure how filenames for individual messages are to be composed. The default is to use the name of the sender, followed by a dash, followed by the message subject. The default file extension is &#8220;.eml&#8221;. After copying files to your local disk, you should be able to simply double click to view them in Outlook Express. Use &#8220;.msg&#8221; etc. to match whatever e-mail client you&#8217;re actually using.</p>
<div class="center">
<p><img src="/wp-content/uploads/2007/05/options.jpg" width="400" height="313" alt="Options Tab"/></p>
<p><small>Options Tab</small>
</div>
<p>By default, Burrito listens on port 21, on all IP addresses. The <em>Security</em> tab allows you to tweak the FTP server listen settings.</p>
<div class="center">
<p><img src="/wp-content/uploads/2007/05/security.jpg" width="400" height="313" alt="Security Tab"/></p>
<p><small>Security Tab</small>
</div>
<p>Here&#8217;s how a typical FTP client configuration looks like (I use <a href="http://ghisler.com" target="_blank">Total Commander</a>):</p>
<div class="center">
<p><img src="/wp-content/uploads/2007/05/ftpsettings.jpg" width="373" height="403" alt="FTP Client Settings"/></p>
<p><small>FTP Client Settings</small>
</div>
<p>And here&#8217;s how your e-mail messages appear as files in your FTP client:</p>
<div class="center">
<p><img src="/wp-content/uploads/2007/05/ftpaction.jpg" width="400" height="300" alt="FTP Client in Action"/></p>
<p><small>FTP Client in Action</small>
</div>
<p>For every FTP connection you establish with Burrito, it will typically open a POP3 connection to the server that specified in the FTP username. It has a connection sharing feature for when multiple FTP clients access the same POP3 account.</p>
<p>Because Burrito doesn&#8217;t download entire messages until you attempt to do an FTP-copy, simply listing and deleting messages are typically faster than a normal POP3 client. Therefore, it can actually be used for cleaning up a POP3 account after it gets choked by a huge messages or spam.</p>
<p>Cool? I guess so. Pointless? Probably :)</p>
<h3>Known Issues</h3>
<ul>
<li>After the system wakes up from hibernation/suspension, the FTP listen port becomes unresponsive. Momentarily chaning the <em>FTP server listen mode</em> in the <em>Security</em> tab to some other mode may (depending on the mode change) reset the listen port.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://magnetiq.com/2007/05/07/burito-10b-ftp-to-pop3-protocol-translator/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Rendering N-sided Polygons with DHTML</title>
		<link>http://magnetiq.com/2006/11/28/rendering-n-sided-polygons-with-dhtml/</link>
		<comments>http://magnetiq.com/2006/11/28/rendering-n-sided-polygons-with-dhtml/#comments</comments>
		<pubDate>Tue, 28 Nov 2006 05:16:29 +0000</pubDate>
		<dc:creator>Ates Goral</dc:creator>
				<category><![CDATA[DHTML]]></category>
		<category><![CDATA[Experiments]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://magnetiq.com/2006/11/28/rendering-n-sided-polygons-with-dhtml/</guid>
		<description><![CDATA[With this technique, convex polygons with any number of sides can be rendered, with a solid color or a background image as the fill.]]></description>
			<content:encoded><![CDATA[<p><script src="/wp-content/scripts/poly_popup.js"></script><br />
With this technique, convex polygons with any number of sides can be rendered, with a solid color or a background image as the fill. Click <a href="#" onclick="return popup()">here</a> or the image below to launch the demo (opens in a pop-up window).</p>
<div class="center">
<p><a href="#" onclick="return popup()"><img src="/wp-content/uploads/2008/06/poly_ss.png" width="400" height="267" alt="DHTML Polygon Rendering Demo"/></a></p>
</div>
<p>You can probably figure it out on your own by playing with the checkboxes at the lower left corner of the pop-up, but read on to find out how it all works.<span id="more-26"></span></p>
<p>The demo renders only regular polygons, but any convex, irregular, closed area can be rendered.</p>
<p>We start with a list of vertices:</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/poly_vertices.png" width="376" height="380" alt="Vertices" class="bordered"/></p>
<p><small>The five vertices of a regular pentagon at an arbitrary orientation</small>
</div>
<p>Then we find the bounding rectangle (minimum and maximum x and y coordinates) of the vertices and apply the fill &lt;div&gt; with either a solid color or a background image:</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/poly_fill.png" width="376" height="380" alt="Fill" class="bordered"/></p>
<p><small>The bounding rectangle is used as the fill</small>
</div>
<p>Now the fill rectangle has to be masked to leave behind our filled polygon. Notice that each side of a polygon can be fitted with a right angle triangle:</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/poly_masks.png" width="376" height="380" alt="Masks" class="bordered"/></p>
<p><small>The right angle triangles and rectangles that act as masks</small>
</div>
<p>For vertices that lie on the bounding (or fill) rectangle, the right angle triangles will be flush with the sides of the bounding rectangle (I, II and III above). For vertices that fall inside the bounding rectangle, the right angle triangles (IV and V) will leave behind rectangles (VI). The number of rectangles depends on the number of sides of the polygon and also its orientation.</p>
<p>What we want to do now is to place triangles and rectangles over the numbered areas so that only the actual polygon will remain visible. For rectangular masks, absolutely positioned &lt;div&gt; elements (with the background color) will do the trick, but for triangles we&#8217;ll have to think about the rectangles that bound them:</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/poly_triangles.png" width="376" height="380" alt="Triangle masks" class="bordered"/></p>
<p><small>Bounding rectangles for triangular masks</small>
</div>
<p>Since we can&#8217;t have an infinite supply of right angle triangle images at all sorts of slants, we can simply resize isosceles right angle triangles to get any angle variations we want. We will need at least four different triangles, with their right angles at each corner. The filled parts of the triangles should be of the background color and the rest should be transparent:</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/poly_nw.png" width="75" height="75" class="bordered"/><img src="/wp-content/uploads/2008/06/poly_ne.png" width="75" height="75" class="bordered"/><img src="/wp-content/uploads/2008/06/poly_se.png" width="75" height="75" class="bordered"/><img src="/wp-content/uploads/2008/06/poly_sw.png" width="75" height="75" class="bordered"/></p>
<p><small>Triangular masks for the NW, NE, SE and SW corners, respectively</small>
</div>
<p>Since these triangles will be resized, it&#8217;s important to make them sufficiently large to minimize aliasing. The images used in the demo are 600 x 600 in dimensions. Once the remaining areas are masked with the triangular masks, all we&#8217;re left with is our polygon:</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/poly_final.png" width="376" height="380" alt="The polygon" class="bordered"/></p>
<p><small>VoilÃ !</small>
</div>
<p>The edges may look jagged a bit, but when the polygon is animated, it&#8217;s barely noticeable.</p>
<p>Concave areas can be filled if the angles don&#8217;t cause overlapping of the masks. I&#8217;ve played around with drawing n-spoked stars instead of convex polygons, but couldn&#8217;t perfect the method to entirely avoid overlaps. The technique can also be used for rendering circles, since as the side count grows, polygons eventually start to look like circles.</p>
]]></content:encoded>
			<wfw:commentRss>http://magnetiq.com/2006/11/28/rendering-n-sided-polygons-with-dhtml/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spelling &#8220;Quake&#8221; With The Quake Logo</title>
		<link>http://magnetiq.com/2006/07/10/spelling-quake-with-the-quake-logo/</link>
		<comments>http://magnetiq.com/2006/07/10/spelling-quake-with-the-quake-logo/#comments</comments>
		<pubDate>Tue, 11 Jul 2006 04:01:58 +0000</pubDate>
		<dc:creator>Ates Goral</dc:creator>
				<category><![CDATA[Experiments]]></category>

		<guid isPermaLink="false">http://magnetiq.com/?p=9</guid>
		<description><![CDATA[I created this GIF animation back in 1997, when I used to play Quake 25 hours a day.]]></description>
			<content:encoded><![CDATA[<p>I created this GIF animation back in 1997, when I used to play Quake 25 hours a day. I recall the tedious process of <strong>manual </strong>tweening to create the individual frames (by calculating the angle and position differences and dividing them by the number of frames) using Freehand. I would probably use Flash if I were to do it today&#8230;</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/quake_black.gif" width="320" height="100" alt="Quake Anim"/></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://magnetiq.com/2006/07/10/spelling-quake-with-the-quake-logo/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Morphing Depth of Field</title>
		<link>http://magnetiq.com/2006/07/10/depth-of-field/</link>
		<comments>http://magnetiq.com/2006/07/10/depth-of-field/#comments</comments>
		<pubDate>Tue, 11 Jul 2006 03:50:23 +0000</pubDate>
		<dc:creator>Ates Goral</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Processing]]></category>

		<guid isPermaLink="false">http://magnetiq.com/?p=5</guid>
		<description><![CDATA[Two (or more) photographs of the same scene and that have different focal distances can be joined together to create an image where both distant and close objects can be in focus.]]></description>
			<content:encoded><![CDATA[<p>Two (or more) photographs of the same scene and that have different focal distances can be joined together to create an image where both distant and close objects can be in focus. <span id="more-5"></span></p>
<p>Quoting from <a target="_blank" href="http://www.graficaobscura.com/depth/index.html">A Multifocus Method for Controlling Depth of Field</a> by <strong>Paul Haeberli</strong>:</p>
<blockquote><p>
When a photograph is taken with a camera, the lens is focused at a particular distance. Objects nearer or farther than this focal distance will appear blurred. By changing the focus of the lens, near objects or distant objects can be made to appear in sharp focus. If you want to create an image where distant objects as well as close objects are in focus, two or more images can be merged together to make an image with increased depth of field&#8230;
</p></blockquote>
<p>Instead of creating a single, in-focus image from two images, I wanted to see how a smooth morphing effect would look like.</p>
<div class="center">
<applet code="Depth_of_Field" archive="/wp-content/processing/multi_focus/multi_focus.jar" width="250" height="250"><br />
</applet>
</div>
<p>Hovering over the image controls how much each of the two images contributes to the final image. Vertical movement controls the contribution amount of the image where the bottle at the front in-focus. Horizontal movement controls the image where the bottle at the back is in-focus.</p>
<p>To get a natural, focus-back-and-forth experience, move the mouse from the top right corner to the bottom left corner and back.</p>
<p>This Java applet was done using <a target="_blank" href="http://processing.org">Processing</a>. The source is below. You can also download the <a href="/wp-content/processing/multi_focus/multi_focus.pde">PDE file</a>.</p>
<pre name="code" class="java:nocontrols:nogutter">/*
   Depth of Field

   by Ates Goral
   Nov 6, 2003

   Based on
   "A Multifocus Method for Controlling Depth of Field"
   by Paul Haeberli
   http://www.sgi.com/grafica/depth/index.html

   The images that are used are taken from the original
   document.

   Instructions:
   - Roll over the photograph to bring the near and far
     portions in and out of focus.
   - Vertical movement controls the near portion.
   - Horizontal movement controls the far portion.
*/

// Globals
PImage imgNear, imgFar, imgSel, imgTxtNear, imgTxtFar;
boolean bInitial; // Initial paint?

void setup()
{
    size(250, 250);
    cursor(CROSS);

    imgNear = loadImage("near_in_focus.gif");
    imgFar = loadImage("far_in_focus.gif");
    imgSel = loadImage("selector.gif"); // Pixel selector

    imgTxtFar = loadImage("txt_far.gif");
    imgTxtNear = loadImage("txt_near.gif");

    // Thin frame around the photograph
    stroke(0);
    noFill();
    rect(0, 0, 240, 240);

    // Small decorative rectangle at bottom right
    noStroke();
    fill(0);
    rect(241, 241, 9, 9);

    bInitial = true; // Enforce initial paint
}

void loop()
{
    // Don't bother if the mouse hasn't moved
    if (pmouseX == mouseX &#038;&#038; pmouseY == mouseY &#038;&#038; !bInitial)
        return;

    float nearFade, farFade;

    if (!bInitial) // If not doing the initial paint, use
                   // mouse input
    {
        nearFade = mouseY / 239.0;
        farFade = mouseX / 239.0;
    }
    else // If doing the inital paint, assume 50% fade
    {
        nearFade = 0.5;
        farFade = 0.5;
        bInitial = false;
    }

    for (int y = 0; y < 239; y++)
    {
        int offY = y * 239;

        for (int x = 0; x < 239; x++)
        {
            int offXY = offY + x; // Pixel offset

            float briNear = (imgNear.pixels[offXY] &#038; 0xff) /
                255.0;
            float briFar = (imgFar.pixels[offXY] &#038; 0xff) /
                255.0;
            int sel = imgSel.pixels[offXY] & 1;

            // Calculate brightness - this expression can
            // probably be simplified, but then it would
            // become harder to follow...
            float bri = (briNear * nearFade +
                briFar * (1 - nearFade)) * (1 - sel) +
                (briFar * farFade + briNear *
                (1 - farFade)) * sel;

            // Plot using a sepia hue
            set(x + 1, y + 1, color(228 * bri, 212 * bri,
                180 * bri));
        }
    }

    // Vertical/near fade
    fill(255 * farFade);
    rect(241, 0, 9, 241);

    // Horizontal/far fade
    fill(255 * nearFade);
    rect(0, 241, 241, 9);

    // Put the text, centered
    image(imgTxtNear, (241 - imgTxtNear.width) >> 1, 242);
    image(imgTxtFar, 243, (241 - imgTxtFar.height) >> 1);
}
</pre>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://magnetiq.com/2006/07/10/depth-of-field/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiple Synthetic Lights</title>
		<link>http://magnetiq.com/2006/04/18/multiple-synthetic-lights/</link>
		<comments>http://magnetiq.com/2006/04/18/multiple-synthetic-lights/#comments</comments>
		<pubDate>Wed, 19 Apr 2006 04:51:52 +0000</pubDate>
		<dc:creator>Ates Goral</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Processing]]></category>

		<guid isPermaLink="false">http://magnetiq.com/?p=4</guid>
		<description><![CDATA[Multiple photographs taken with different light sources can be blended together to create images that appear to have all the light sources simultaneously active. The light sources can be attributed arbitrary colors as well, allowing the creation of an infinite number of synthetic scenes.]]></description>
			<content:encoded><![CDATA[<p>Multiple photographs taken with different light sources can be blended together to create images that appear to have all the light sources simultaneously active. The light sources can be attributed arbitrary colors as well, allowing the creation of an infinite number of synthetic scenes. <span id="more-4"></span></p>
<p>Quoting from <a target="_blank" href="http://www.graficaobscura.com/synth/index.html">Synthetic Lighting for Photography</a> by <strong>Paul Haeberli</strong>:</p>
<blockquote><p>
Light from different light sources add together to illuminate objects in a scene. We can use this super-position principle to modify the lighting of a scene after it has been photographed&#8230;
</p></blockquote>
<p>I&#8217;ve created an interactive application with three light sources with different colors.</p>
<div class="center">
<applet width="250" height="250" code="Multi_Light" archive="/wp-content/processing/multi_light/multi_light.jar"><br />
</applet>
</div>
<p>Hover over the image to change the intensities of the three light sources.</p>
<p>This Java applet was done using <a target="_blank" href="http://processing.org/">Processing</a>. The source is below. You can also download the <a href="/wp-content/processing/multi_light/multi_light.pde">PDE file</a>.</p>
<pre name="code" class="java:nocontrols:nogutter">/*
   Multiple Synthetic Lights

   by Ates Goral
   Sometime, 2003

   Based on
   "Synthetic Lighting for Photography"
   by Paul Haeberli
   http://www.sgi.com/misc/grafica/synth/index.html

   Instructions:
   - Roll over the photograph to change the intensities of
     the three different light sources.
*/

// Globals
PImage imgAmb, imgA, imgB, imgC;
float[] ambs, diffA, diffB, diffC;
color clrAmb, clrA, clrB, clrC;
boolean bInitial; // Initial paint?

// Calculate the difference between an image and the ambient
// image
void genDiff(PImage img, float[] arr)
{
    for (int y = 0; y < 250; y++)
    {
        for (int x = 0; x < 250; x++)
        {
            int offs = y * 250 + x;

            float sub = red(img.pixels[offs]) / 255.0 -
            ambs[offs];

            if (sub < 0)
            {
                sub = 0;
            }

            arr[offs] = sub;
        }
    }
}

void setup()
{
    size(250, 250);
    cursor(CROSS);

    imgAmb = loadImage("lighting-11.jpg"); // Ambient
    imgA = loadImage("lighting-09.jpg");
    imgB = loadImage("lighting-10.jpg");
    imgC = loadImage("lighting-14.jpg");

    ambs = new float[250 * 250];
    diffA = new float[250 * 250];
    diffB = new float[250 * 250];

    diffC = new float[250 * 250];

    for (int y = 0; y < 250; y++)
    {
        for (int x = 0; x < 250; x++)
        {
            int offs = y * 250 + x;
            // Normalize to 1.0
            ambs[offs] = red(imgAmb.pixels[offs]) / 255.0;
        }
    }

    genDiff(imgA, diffA);
    genDiff(imgB, diffB);
    genDiff(imgC, diffC);

    // Colors
    clrAmb = #202A35;
    clrA = #7F1025;
    clrB = #8A8768;
    clrC = #291D80;

    bInitial = true; // Enforce initial paint
}

void loop()
{
    // Don't bother if the mouse hasn't moved
    if (pmouseX == mouseX &#038;&#038; pmouseY == mouseY &#038;&#038; !bInitial)
    {
        return;
    }

    float mX, mY;

    if (!bInitial) // If not doing the initial paint,
                    // use mouse input
    {
        mX = mouseX / 250.0;
        mY = mouseY / 250.0;
    }
    else // If doing the inital paint, assume 50% fade
    {
        mX = 0.5;
        mY = 0.5;
        bInitial = false;
    }

    // Coefficients
    float coeffA = pow((1 - mX), 0.5);
    float coeffC = pow(mX, 0.5);
    float coeffB = (1 - mY);

    for (int y = 0; y < 250; y++)
    {
        for (int x = 0; x < 250; x++)
        {
            int offs = y * 250 + x;
            float amb = ambs[offs];

            // Contribution of each light source
            float contrA = diffA[offs] * coeffA;
            float contrB = diffB[offs] * coeffB;
            float contrC = diffC[offs] * coeffC;

            // Calculate components
            float cmpR = red(clrAmb) * amb +
                red(clrA) * contrA +
                red(clrB) * contrB +
                red(clrC) * contrC;

            float cmpG = green(clrAmb) * amb +
                green(clrA) * contrA +
                green(clrB) * contrB +
                green(clrC) * contrC;

            float cmpB = blue(clrAmb) * amb +
                blue(clrA) * contrA +
                blue(clrB) * contrB +
                blue(clrC) * contrC;

            set(x, y, color(cmpR, cmpG, cmpB));
        }
    }
}
</pre>
<p>The original images I used are below. <del datetime="2008-06-25T04:29:53+00:00">I had snatched them a while ago from a search result on Google Images but I can't find the actual source anymore. So, this will have to go without credit. Please drop me a comment if you know the source of these images.</del> <ins datetime="2008-06-25T04:29:53+00:00">They're from the <a href="http://www.megapixel.net/html/articles/article-lightdir.php">"Lighting direction" article</a> at <a href="http://www.megapixel.net/">megapixel.net</a>. I've submitted a belated permission to use these images in this article and I'm waiting for their response.</ins></p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/lighting-11.jpg" alt="Ambient light" height="250" width="250"/></p>
<p><small>Ambient Light</small>
</div>
<p>&nbsp;</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/lighting-09.jpg" alt="Light coming from the left" height="250" width="250"/></p>
<p><small>Light coming from the left</small>
</div>
<p>&nbsp;</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/lighting-10.jpg" alt="Light coming from the top" height="250" width="250"/></p>
<p><small>Light coming from the top</small>
</div>
<p>&nbsp;</p>
<div class="center">
<p><img src="/wp-content/uploads/2008/06/lighting-14.jpg" alt="Light coming from the right" height="250" width="250"/></p>
<p><small>Light coming from the right</small>
</div>
]]></content:encoded>
			<wfw:commentRss>http://magnetiq.com/2006/04/18/multiple-synthetic-lights/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
