<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-20076457</id><updated>2011-10-03T03:31:07.302-07:00</updated><category term='stereoscopic youtube hummingbird'/><title type='text'>Rants of a spud</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>27</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-20076457.post-2326124404554889324</id><published>2011-03-21T12:43:00.001-07:00</published><updated>2011-03-21T13:10:13.352-07:00</updated><title type='text'>Autumn 2010 - When Google jumped the shark</title><content type='html'>I cannot express the depths of my dismay at the "Search instead for..." misfeature that Google has added to search.  From the dates of the earliest cries of communal pain on the web, this feature appeared around September 2010.&lt;br /&gt;&lt;br /&gt;I am not the only angry customer. Google forums include multiple vigorous discussions of this topic.&lt;br /&gt;&lt;br /&gt;TimInBC &lt;a href="http://www.google.com/support/forum/p/Web+Search/thread?tid=71f1c6ef666229d7&amp;amp;hl=en&amp;amp;fid=71f1c6ef666229d7000494b9bd7f7480&amp;amp;hltp=2"&gt;writes&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;I agree, this is annoying, and not because I am promoting a site. I want to FIND stuff, and when I tell it to search for "Orangerie" I don't want it auto-corrected to "Orangutan" or anything else. I am a very good speller and I don't need Google to help me. Please give us a preference to say "Search for exactly what I tell you to search for".&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Alensha &lt;a href="http://www.google.pl/support/forum/p/Web+Search/thread?tid=7f57d27b17e4c1fd&amp;amp;hl=en&amp;amp;fid=7f57d27b17e4c1fd00049ad77f24ed2b&amp;amp;hltp=2"&gt;comments&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;It would be really good if this feature was optional instead of being  forced on us. I encounter it every day, and it messes up my search  results several times daily. Last time I was looking for the meaning of  the name of the Egyptian god Atum and of the first 50 results 46 were  about the name Autumn, explaining that it means, well, autumn. The "did  you mean" function was mostly harmless, but _changing_ the word I typed  to something else or filling the first ten pages of the search results  with completely irrelevant results is annoying.&lt;/blockquote&gt;&lt;br /&gt;This problem seriously interrupts my work flow too.  During my work day I run numerous web searches for information.  Now that Google is broken, I often find myself concluding "Darn, there must not be any relevant information on this topic on the web."  Then I notice that accursed, mocking, evil, cruel cancer of the web, "Search instead for &lt;exactly&gt;".  The number of near misses convinces me that I must have actually been completely misled many times by Google's cruel practical joke.&lt;br /&gt;&lt;br /&gt;Bing is the same way.  Here's the deal: Bing, if you create a configuration option to never second guess my search terms, I promise to drop Google and use Bing for my searches.  I recommend others make the same promise to Bing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-2326124404554889324?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/2326124404554889324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=2326124404554889324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/2326124404554889324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/2326124404554889324'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2011/03/autumn-2010-when-google-jumped-shark.html' title='Autumn 2010 - When Google jumped the shark'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-8222894615844896219</id><published>2009-11-22T08:40:00.000-08:00</published><updated>2009-11-22T20:17:32.493-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stereoscopic youtube hummingbird'/><title type='text'>YouTube supports 3D stereoscopic video</title><content type='html'>Google's video service &lt;a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt; now supports stereoscopic video.  This is great news.  I predict that soon it will be possible to stream stereoscopic YouTube videos to stereoscopic monitors.&lt;br /&gt;&lt;br /&gt;The only technical information so far is one very long &lt;a href="http://www.google.com/support/forum/p/youtube/thread?tid=56b6f6f15dabf994"&gt;help thread&lt;/a&gt;.  The Google engineer behind 3d YouTube, "YouTube Pete", participates in that thread.&lt;br /&gt;&lt;br /&gt;I would like to take a moment to thank YouTube Pete for his beautiful work on the 3D YouTube project.  Kudos to Pete.  It is much appreciated.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;My hummingbird video&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;I made a &lt;a href="http://www.youtube.com/watch?v=2z-cg0qR-0A"&gt;hummingbird video&lt;/a&gt; to test out the 3d features myself.  The embedded video below does not show the 3D interface.  You must go to the &lt;a href="http://www.youtube.com/watch?v=2z-cg0qR-0A"&gt;YouTube page itself&lt;/a&gt; to see the full range of possibilities.  Grab a pair of red/blue 3D glasses if you have one.&lt;br /&gt;&lt;br /&gt;&lt;object height="340" width="560"&gt;&lt;param name="movie" value="http://www.youtube.com/v/2z-cg0qR-0A&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/2z-cg0qR-0A&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="340" width="560"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Remember to check out the &lt;a href="http://www.youtube.com/watch?v=2z-cg0qR-0A"&gt;original movie&lt;/a&gt; to see all of the 3D viewing options.&lt;br /&gt;&lt;br /&gt;This hummingbird movie could be improved in several ways&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The left side is out of focus.  I meant to set the focus for both cameras to 15 cm, but it looks like the focal length of the left eye was set too short.&lt;/li&gt;&lt;li&gt;The sound doesn't seem to work.  I plugged in a microphone, and selected the one audio option that was available in AmCap, but I don't hear any sound in the video.  This needs to be investigated.&lt;/li&gt;&lt;li&gt;I should register &lt;a href="http://www.3dtv.at/Products/Multiplexer/"&gt;Stereoscopic Multiplexer&lt;/a&gt;, to avoid those watermarks on the video.  It will cost about $90.  Ouch.&lt;/li&gt;&lt;li&gt;It would be good to get more light on the bird.  Unfortunately, the sun won't shine on my patio until summer.&lt;/li&gt;&lt;li&gt;The format is Left-Right (parallel), but the emerging YouTube standard is Right-Left (cross-eye), so I should use the Right-Left convention in the future.  Plus I have an easier time free-viewing cross-eye, so it will be more convenient for me when viewing embedded videos like the one above.  I used the YouTube tag "&lt;span&gt;&lt;span&gt;yt3d:swap=true&lt;/span&gt;&lt;/span&gt;" to correct for this inversion.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Other YouTube 3D videos&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;The following are examples of other stereoscopic videos on YouTube, created by others:&lt;br /&gt;&lt;br /&gt;This so-called biodiversity documentary contains professional-quality footage of domesticated ducks, geese, and honeybees in India.  The narration is done with a top-quality computer generated voice.  The voice is only slightly creepy.&lt;br /&gt;&lt;br /&gt;&lt;object height="340" width="560"&gt;&lt;param name="movie" value="http://www.youtube.com/v/xn-0AwdCE98&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/xn-0AwdCE98&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="340" width="560"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;This next one is taken with a helmet camera.  It is interesting and entertaining.  It includes some cityscape images.  Unfortunately, a cityscape shows little depth when using a normal human interpupillary distance of 60 mm or so.  Hyperstereo might have been nice here.&lt;br /&gt;&lt;br /&gt;&lt;object height="340" width="560"&gt;&lt;param name="movie" value="http://www.youtube.com/v/moINIZuG38E&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/moINIZuG38E&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="340" width="560"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;There are many many other stereoscopic videos on YouTube.  &lt;a href="http://www.youtube.com/results?search_query=yt3d&amp;amp;search_type=&amp;amp;aq=f"&gt;Search for "yt3d" on YouTube&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How I made the hummingbird video&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;I created my hummingbird video using two USB pen cameras.  So I could get the two cameras as close as possible.  This setup is suited for small, close subjects, such as hummingbirds.  Because the two cameras are only 14 mm apart, as opposed to the 60 mm separation of human eyes, my setup yields a view as seen by another hummingbird, rather than what would be seen by a person.  This is called hypostereo.&lt;br /&gt;&lt;br /&gt;Two USB pen cameras and a portable netbook style computer are the basis of my stereoscopic video system.  I created a custom bracket for the cameras so I can mount them on a tripod.  The bracket is carefully shaped to compensate for the idiosyncrasies of these particular cameras.  These very cheap cameras do not point in exactly the same direction.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_zfTsYEB4J6A/SwmLgnKmOQI/AAAAAAAAAMg/mz5KA1v_bCc/s1600/pencapsetup.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_zfTsYEB4J6A/SwmLgnKmOQI/AAAAAAAAAMg/mz5KA1v_bCc/s320/pencapsetup.jpg" alt="" id="BLOGGER_PHOTO_ID_5407006220020496642" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The narrow 14 mm distance between the camera lenses is crucial to producing a subtle 3D effect with small close subjects such as the hummingbird.  I chose these pen cameras because this form factor permits the smallest camera separation I could find.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_zfTsYEB4J6A/SwmLgy1IRvI/AAAAAAAAAMo/O8EsOp5JbPA/s1600/pencamsep.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_zfTsYEB4J6A/SwmLgy1IRvI/AAAAAAAAAMo/O8EsOp5JbPA/s320/pencamsep.jpg" alt="" id="BLOGGER_PHOTO_ID_5407006223151679218" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is a shot of the whole setup prepared to take hummingbird videos.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_zfTsYEB4J6A/SwoMS0oPyOI/AAAAAAAAAMw/jfhxAic4RXs/s1600/wholesetup.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 240px; height: 320px;" src="http://3.bp.blogspot.com/_zfTsYEB4J6A/SwoMS0oPyOI/AAAAAAAAAMw/jfhxAic4RXs/s320/wholesetup.jpg" alt="" id="BLOGGER_PHOTO_ID_5407147820116330722" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-8222894615844896219?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/8222894615844896219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=8222894615844896219' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/8222894615844896219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/8222894615844896219'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2009/11/youtube-supports-3d-stereoscopic-video.html' title='YouTube supports 3D stereoscopic video'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_zfTsYEB4J6A/SwmLgnKmOQI/AAAAAAAAAMg/mz5KA1v_bCc/s72-c/pencapsetup.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-1756938463433082230</id><published>2009-08-22T07:16:00.000-07:00</published><updated>2009-09-06T07:05:40.175-07:00</updated><title type='text'>Tk 8.5 is better than wxWidgets on Windows</title><content type='html'>UPDATE: It appears this issue might be &lt;a href="http://trac.wxwidgets.org/ticket/11008"&gt;fixed&lt;/a&gt; in a future release of wxwidgets.&lt;br /&gt;&lt;br /&gt;I frequently write computer programs with graphical user interfaces ("GUI"s).  I insist that the interfaces look good on Windows, Mac, and Linux computers.  By "good", I mean that the widgets (the buttons, sliders, and what-not), look exactly like those found on most other applications developed specifically for that particular platform.  For example, buttons and progress bars on Mac must have that clear blue "Aqua" look.&lt;br /&gt;&lt;br /&gt;There are several programming tool kits which help to create native-looking user interfaces on multiple platforms.  The three platforms I pay particular attention to are Windows, Mac, and Linux. Cross-platform GUI tool kits include &lt;a href="http://www.wxwidgets.org/"&gt;wxWidgets&lt;/a&gt;, &lt;a href="http://www.tcl.tk/man/tcl8.5/TkCmd/contents.htm"&gt;Tk&lt;/a&gt;, and &lt;a href="http://http//java.sun.com/javase/6/docs/technotes/guides/swing/"&gt;Java Swing&lt;/a&gt;.  This post documents the failure of wxWidgets and Java Swing to respect Windows font sizes.&lt;br /&gt;&lt;br /&gt;Look at the following picture to see the failure of wx and Java to respect the Windows font sizes.  From left to right, the test programs are in Visual Basic, python/Tk, python/wx, and Java Swing.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_zfTsYEB4J6A/SpAbBa0HV9I/AAAAAAAAAMY/ac1oMiYPXXI/s1600-h/gui_font_sizes.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 93px;" src="http://3.bp.blogspot.com/_zfTsYEB4J6A/SpAbBa0HV9I/AAAAAAAAAMY/ac1oMiYPXXI/s400/gui_font_sizes.png" alt="" id="BLOGGER_PHOTO_ID_5372824066644727762" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;wxWidgets looks nice in some cases, but it has some ways to go to support native look and feel on Windows.  I am working on several Windows XP systems, on which I routinely select "Large Fonts" in my desktop preferences.  wxWidgets does not respect those preferences.&lt;br /&gt;&lt;br /&gt;To see the difference, first set extra large fonts on your desktop:&lt;br /&gt;&lt;br /&gt;Far click desktop -&gt; Properties -&gt; Appearance -&gt; Font Size -&gt; Extra Large Fonts&lt;br /&gt;&lt;br /&gt;Next, write an application using wxWidgets and test whether it respects your font choice.  I didn't think so.&lt;br /&gt;&lt;br /&gt;If it's any consolation, Java doesn't respect the Windows font size either.&lt;br /&gt;&lt;br /&gt;If you want to use a cross-platform widget tool kit, and your definition of "cross-platform"  includes Windows, my recommendation is to use Tk 8.5.&lt;br /&gt;&lt;br /&gt;The table below summarizes the results for the four test programs I wrote:&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;br /&gt;&lt;caption&gt;GUI tool kits on Windows&lt;/caption&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;br /&gt;&lt;th&gt;Tool Kit&lt;/th&gt;&lt;th&gt;Native look-and-feel?&lt;/th&gt;&lt;th&gt;Respects font size?&lt;/th&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;Visual basic&lt;/td&gt;&lt;td&gt;No(!)&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;Tk 8.5&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;wx 2.8.10&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;Java 1.6.0&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Below are the test programs I wrote to create the windows shown at the beginning of this post.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Visual Basic&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;' "Hello, World!" program in Visual Basic.&lt;br /&gt;Module Hello&lt;br /&gt;Sub Main()&lt;br /&gt;MsgBox("Hello, World! (VB)") ' Display message on computer screen.&lt;br /&gt;End Sub&lt;br /&gt;End Module&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Tk 8.5 (tkinter in python 3.1)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# Note - requires python 3.1 for ttk 8.5 support&lt;br /&gt;import tkinter as tk&lt;br /&gt;import tkinter.ttk as ttk&lt;br /&gt;&lt;br /&gt;root = tk.Tk()&lt;br /&gt;padding = 10&lt;br /&gt;panel = ttk.Frame(root, padding=padding).pack()&lt;br /&gt;label = ttk.Label(panel, text="Hello, World! (Tk)")&lt;br /&gt;label.pack(padx=padding, pady=padding)&lt;br /&gt;button = ttk.Button(panel, text="Hello", default="active")&lt;br /&gt;button.pack(padx=padding, pady=padding)&lt;br /&gt;root.mainloop()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;wx 2.8.10 (in python 2.6 with wxpython)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import wx&lt;br /&gt;&lt;br /&gt;padding = 10&lt;br /&gt;app = wx.App(0)&lt;br /&gt;frame = wx.Frame(None, -1, "Hello")&lt;br /&gt;panel = wx.Panel(frame)&lt;br /&gt;sizer = wx.BoxSizer(wx.VERTICAL)&lt;br /&gt;panel.SetSizer(sizer)&lt;br /&gt;text = wx.StaticText(panel, -1, "Hello, World! (wx)")&lt;br /&gt;sizer.Add(text, 0, wx.ALL, padding)&lt;br /&gt;button = wx.Button(panel, -1, "Hello")&lt;br /&gt;sizer.Add(button, 0, wx.ALL, padding)&lt;br /&gt;frame.Centre()&lt;br /&gt;frame.Show(True)&lt;br /&gt;app.MainLoop()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Java swing 1.6.0&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import javax.swing.*;&lt;br /&gt;import java.awt.Dimension;&lt;br /&gt;&lt;br /&gt;public class HelloWorldFrame extends JFrame&lt;br /&gt;{&lt;br /&gt;public static void main(String args[])&lt;br /&gt;{&lt;br /&gt;  new HelloWorldFrame();&lt;br /&gt;}&lt;br /&gt;HelloWorldFrame()&lt;br /&gt;{&lt;br /&gt;  try {&lt;br /&gt;      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());&lt;br /&gt;  } catch(Exception e) {}&lt;br /&gt;  JPanel panel = new JPanel();&lt;br /&gt;  add(panel);&lt;br /&gt;  panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));&lt;br /&gt;  panel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));&lt;br /&gt;  JLabel label = new JLabel("Hello, World! (java)");&lt;br /&gt;  panel.add(label);&lt;br /&gt;  panel.add(Box.createRigidArea(new Dimension(0, 10)));&lt;br /&gt;  JButton button = new JButton("Hello");&lt;br /&gt;  panel.add(button);&lt;br /&gt;  pack();&lt;br /&gt;  setVisible(true);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The wx bug tracker has had a couple of &lt;a href="http://trac.wxwidgets.org/ticket/1981"&gt;bug&lt;/a&gt; &lt;a href="http://trac.wxwidgets.org/ticket/11008"&gt;reports&lt;/a&gt; for this problem, one open for five years.  Somehow I doubt they are itching to fix this problem.&lt;br /&gt;&lt;br /&gt;The Tk source code that sets the windows correctly appears to be near line 418 of file win/tkWinFont.c in the Tk source code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,&lt;br /&gt;        sizeof(ncMetrics), &amp;amp;ncMetrics, 0)) {&lt;br /&gt;    CreateNamedSystemLogFont(interp, tkwin, "TkDefaultFont",&lt;br /&gt;        &amp;amp;ncMetrics.lfMessageFont);&lt;br /&gt;    CreateNamedSystemLogFont(interp, tkwin, "TkHeadingFont",&lt;br /&gt;        &amp;amp;ncMetrics.lfMessageFont);&lt;br /&gt;    CreateNamedSystemLogFont(interp, tkwin, "TkTextFont",&lt;br /&gt;        &amp;amp;ncMetrics.lfMessageFont);&lt;br /&gt;    CreateNamedSystemLogFont(interp, tkwin, "TkMenuFont",&lt;br /&gt;        &amp;amp;ncMetrics.lfMenuFont);&lt;br /&gt;    CreateNamedSystemLogFont(interp, tkwin, "TkTooltipFont",&lt;br /&gt;        &amp;amp;ncMetrics.lfStatusFont);&lt;br /&gt;    CreateNamedSystemLogFont(interp, tkwin, "TkCaptionFont",&lt;br /&gt;        &amp;amp;ncMetrics.lfCaptionFont);&lt;br /&gt;    CreateNamedSystemLogFont(interp, tkwin, "TkSmallCaptionFont",&lt;br /&gt;        &amp;amp;ncMetrics.lfSmCaptionFont);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The wx source code has similar code in a few locations.  But it appears that this technique may be only used for menu fonts and message dialog fonts.&lt;br /&gt;&lt;br /&gt;The main problem might be that the method wxGetCCDefaultFont() in the wx source code uses SPI_GETINCONTITLELOGFONT instead of SPI_GETNONCLIENTMETRICS.&lt;br /&gt;&lt;br /&gt;Microsoft has &lt;a href="http://msdn.microsoft.com/en-us/library/ms724506%28VS.85%29.aspx"&gt;documentation&lt;/a&gt; for the NONCLIENTMETRICS data structure.&lt;br /&gt;&lt;br /&gt;Even if the wx authors fix this today, I fear it will be a long time before the change trickles down into a wxPython release.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-1756938463433082230?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/1756938463433082230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=1756938463433082230' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/1756938463433082230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/1756938463433082230'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2009/08/tk-85-is-better-than-wxwidgets-on.html' title='Tk 8.5 is better than wxWidgets on Windows'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_zfTsYEB4J6A/SpAbBa0HV9I/AAAAAAAAAMY/ac1oMiYPXXI/s72-c/gui_font_sizes.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-838829220563284235</id><published>2009-08-15T14:57:00.000-07:00</published><updated>2009-08-15T16:19:59.137-07:00</updated><title type='text'>Write your own stereoscopic 3D program using nVidia's "consumer" stereo driver</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/Soc7Ov1CFSI/AAAAAAAAAMQ/dpCmiSNBVAA/s1600-h/cube.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 208px; height: 234px;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/Soc7Ov1CFSI/AAAAAAAAAMQ/dpCmiSNBVAA/s320/cube.png" alt="" id="BLOGGER_PHOTO_ID_5370326205205714210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I have always been a fan of &lt;a href="http://www.nvidia.com/"&gt;nVidia&lt;/a&gt; graphics boards because of their support for 3D stereoscopic games.  But the "consumer level" (non-Quadro) stereoscopic drivers only seem to work with games.  I have always wondered how to create my own applications that can use the stereoscopic drivers on less-expensive gaming video boards.  Now I have found a way.&lt;br /&gt;&lt;br /&gt;The "consumer" stereoscopic driver from nVidia only works with "full screen" games.  When I started experimenting with OpenGL, I assumed that using the call "&lt;a href="http://pyopengl.sourceforge.net/documentation/manual/glutFullScreen.3GLUT.html"&gt;glutFullScreen()&lt;/a&gt;" might be enough to get the stereoscopic drivers to kick in.  But it is not.&lt;br /&gt;&lt;br /&gt;The trick is to use the &lt;a href="http://pyopengl.sourceforge.net/documentation/manual/glutEnterGameMode.3GLUT.html"&gt;glutEnterGameMode()&lt;/a&gt; call.  I did a lot of searching on the internet, and nowhere is it mentioned that you must call glutEnterGameMode() to get the nVidia "consumer level" stereoscopic drivers to work.  That is why I am sharing this blog post.&lt;br /&gt;&lt;br /&gt;My working system is on Windows XP.  I am uncertain if this approach will work with Windows Vista/7.  I am a bit concerned because nVidia seems to be selling a &lt;a href="http://www.nvidia.com/object/3D_Vision_Overview.html"&gt;hardware stereoscopic product&lt;/a&gt; these days.  I am worried that my custom stereoscopic theater, which uses a pair of polarized video projectors, won't work if I upgrade my Windows version.&lt;br /&gt;&lt;br /&gt;Here is how you can do it too, on Windows XP:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Ensure you have a &lt;a href="http://www.3d.wep.dk/driverguide.html"&gt;supported nVidia graphics&lt;/a&gt; board in your computer.  See the stereoscopic driver &lt;a href="http://download.nvidia.com/Windows/77.77/77.77_3D_Stereo_User_Guide.pdf"&gt;users' guide&lt;/a&gt; for more details.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Get the stereoscopic driver from nVidia.  The most recent version (91.31) released for Windows XP is from 2006.  That is &lt;a href="http://www.nvidia.com/object/3dstereo_archive.html"&gt;the one I am using&lt;/a&gt;.  Consult &lt;a href="http://www.3d.wep.dk/driverguide.html"&gt;this driver guide&lt;/a&gt; for more details.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Install &lt;a href="http://www.python.org/download/"&gt;Python 2.6&lt;/a&gt; and &lt;a href="http://sourceforge.net/projects/pyopengl/files/"&gt;PyOpenGL version 3.0.0&lt;/a&gt;, so you can conveniently create OpenGL programs in python.&lt;/li&gt;&lt;li&gt;Familiarize yourself with OpenGL programming.  I got started by following the examples of the "red book", the &lt;a href="http://www.amazon.com/gp/product/0321481003?ie=UTF8&amp;amp;tag=rotatingpcom-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321481003"&gt;OpenGL Programming Guide&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Study my example program, below, to learn how to call glutGameModeString() and glutEnterGameMode().&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Below is the text of a complete working python program that works with the nVidia "consumer level" stereoscopic driver on my Windows XP computer.  (The stereoscopic presentation only appears in the full screen gaming mode):&lt;br /&gt;&lt;br /&gt;Modify the display() method and the animate() method to show whatever you want!&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/cygdrive/c/Python26/python&lt;br /&gt;&lt;br /&gt;from OpenGL.GL import *&lt;br /&gt;from OpenGL.GLU import *&lt;br /&gt;from OpenGL.GLUT import *&lt;br /&gt;import sys&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def do_nothing(*args):&lt;br /&gt; """&lt;br /&gt; Empty method for glutDisplayFunc during risky transition to game mode.&lt;br /&gt; """&lt;br /&gt; pass&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;class HelloOpenGL(object):&lt;br /&gt; """&lt;br /&gt; Creates a rotating wire frame cube using OpenGL.&lt;br /&gt;&lt;br /&gt; Pressing the "f" key toggles full screen game mode.&lt;br /&gt; This full screen mode works with nVidia stereoscopic&lt;br /&gt; driver for Windows XP.&lt;br /&gt; """&lt;br /&gt; def __init__(self):&lt;br /&gt;     self.animation_interval = 100 # milliseconds&lt;br /&gt;     self.rotation_angle = 0.0 # degrees, starting point&lt;br /&gt;     glutInit("Cube.py")&lt;br /&gt;     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)     &lt;br /&gt;     glEnable(GL_DEPTH_TEST)&lt;br /&gt;     glutInitWindowSize(200, 200)&lt;br /&gt;     # Remember window id for when we return from game mode.&lt;br /&gt;     self.window_id = glutCreateWindow('Wire Cube')&lt;br /&gt;     self.initialize_gl_context()     &lt;br /&gt;     # glutTimerFunc remains when GL context is replaced,&lt;br /&gt;     # so it does not go into self.initialize_gl_context()&lt;br /&gt;     glutTimerFunc(self.animation_interval, self.animate, 1)&lt;br /&gt;     glutMainLoop() # never returns&lt;br /&gt;&lt;br /&gt; def clear_gl_callbacks(self):&lt;br /&gt;     """&lt;br /&gt;     Set inoccuous callbacks during times when no valid context may be available.&lt;br /&gt;     """&lt;br /&gt;     glutDisplayFunc(do_nothing)&lt;br /&gt;     glutMotionFunc(None)&lt;br /&gt;     glutKeyboardFunc(None)&lt;br /&gt;&lt;br /&gt; def initialize_gl_context(self):&lt;br /&gt;     """&lt;br /&gt;     When switching between full-screen and windowed modes,&lt;br /&gt;     initialize_gl_context() reinitializes state.&lt;br /&gt;     """&lt;br /&gt;     glClearColor(0.5,0.5,0.5,0.0)&lt;br /&gt;     glutDisplayFunc(self.display)&lt;br /&gt;     # glutPassiveMotionFunc(self.mouse_motion)&lt;br /&gt;     glutMotionFunc(self.mouse_motion)&lt;br /&gt;     glutKeyboardFunc(self.keypress)&lt;br /&gt;     # establish the projection matrix (perspective)&lt;br /&gt;     glMatrixMode(GL_PROJECTION)&lt;br /&gt;     glLoadIdentity()&lt;br /&gt;     x,y,width,height = glGetDoublev(GL_VIEWPORT)&lt;br /&gt;     gluPerspective(&lt;br /&gt;         45, # field of view in degrees&lt;br /&gt;         width/float(height or 1), # aspect ratio&lt;br /&gt;         .25, # near clipping plane&lt;br /&gt;         200, # far clipping plane&lt;br /&gt;     )&lt;br /&gt;  &lt;br /&gt; def start_game_mode(self):&lt;br /&gt;     if glutGameModeGet(GLUT_GAME_MODE_ACTIVE):&lt;br /&gt;         return # already in game mode&lt;br /&gt;     glutGameModeString("800x600:16@60")&lt;br /&gt;     if glutGameModeGet(GLUT_GAME_MODE_POSSIBLE):&lt;br /&gt;         self.clear_gl_callbacks()&lt;br /&gt;         glutEnterGameMode()&lt;br /&gt;         self.initialize_gl_context()&lt;br /&gt;&lt;br /&gt; def start_windowed_mode(self):&lt;br /&gt;     if glutGameModeGet(GLUT_GAME_MODE_ACTIVE):&lt;br /&gt;         self.clear_gl_callbacks()&lt;br /&gt;         glutLeaveGameMode()&lt;br /&gt;         # Remember the window we created at start up?&lt;br /&gt;         glutSetWindow(self.window_id)&lt;br /&gt;     self.initialize_gl_context()     &lt;br /&gt;  &lt;br /&gt; def display(self):&lt;br /&gt;     """&lt;br /&gt;     "display()" method is called every time OpenGL updates the display.&lt;br /&gt;     """&lt;br /&gt;     # Erase the old image&lt;br /&gt;     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)&lt;br /&gt;     # Modelview must be set before geometry is sent&lt;br /&gt;     # or else crash when entering stereoscopic mode.&lt;br /&gt;     glMatrixMode(GL_MODELVIEW)&lt;br /&gt;     glLoadIdentity()&lt;br /&gt;     gluLookAt(&lt;br /&gt;         0,-0.5,5, # eyepoint&lt;br /&gt;         0,0,0, # center-of-view&lt;br /&gt;         0,1,0, # up-vector&lt;br /&gt;     )&lt;br /&gt;     # Rotate about the origin as animation progresses&lt;br /&gt;     glRotate(self.rotation_angle, 0, 1, 0)&lt;br /&gt;     glPushMatrix()&lt;br /&gt;     try:&lt;br /&gt;         # Draw the cube&lt;br /&gt;         glutWireCube(2.0)&lt;br /&gt;     finally:&lt;br /&gt;         glPopMatrix()&lt;br /&gt;     glutSwapBuffers()&lt;br /&gt;&lt;br /&gt; def mouse_motion(self, x, y):&lt;br /&gt;     pass&lt;br /&gt;&lt;br /&gt; def keypress(self, key, x, y):&lt;br /&gt;     if key == '\033':&lt;br /&gt;         # Escape key leaves full screen mode&lt;br /&gt;         if glutGameModeGet(GLUT_GAME_MODE_ACTIVE):&lt;br /&gt;             self.start_windowed_mode()&lt;br /&gt;     elif key == "f":&lt;br /&gt;         # "f" key toggle full screen and windowed mode.&lt;br /&gt;         if glutGameModeGet(GLUT_GAME_MODE_ACTIVE):&lt;br /&gt;             self.start_windowed_mode()&lt;br /&gt;         else:&lt;br /&gt;             self.start_game_mode()&lt;br /&gt;&lt;br /&gt; def animate(self, value):&lt;br /&gt;     """&lt;br /&gt;     Periodically change the rotation angle for the cube animation.&lt;br /&gt;  &lt;br /&gt;     This animate method() is called as a glutTimerFunc().&lt;br /&gt;     """&lt;br /&gt;     self.rotation_angle += 1.0&lt;br /&gt;     while self.rotation_angle &gt; 360.0:&lt;br /&gt;         self.rotation_angle -= 360.0&lt;br /&gt;     glutPostRedisplay()&lt;br /&gt;     # Be sure to come back for more&lt;br /&gt;     glutTimerFunc(self.animation_interval, self.animate, value+1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Run the HelloOpenGL application when this script is run directly.&lt;br /&gt;if (__name__ == '__main__'):&lt;br /&gt; HelloOpenGL()&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-838829220563284235?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/838829220563284235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=838829220563284235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/838829220563284235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/838829220563284235'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2009/08/write-your-own-stereoscopic-3d-program.html' title='Write your own stereoscopic 3D program using nVidia&apos;s &quot;consumer&quot; stereo driver'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_zfTsYEB4J6A/Soc7Ov1CFSI/AAAAAAAAAMQ/dpCmiSNBVAA/s72-c/cube.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-6040309973703633912</id><published>2007-07-13T15:18:00.000-07:00</published><updated>2007-07-13T15:24:31.990-07:00</updated><title type='text'>Phantom cell phone vibrations</title><content type='html'>I have had a cell phone (Treo 680) for about 8 months.  I keep it in my front right pants pocket.  I always have it set to "vibrate".  Lately, my leg has begun to vibrate right where the phone is, causing me to think that the phone is ringing.&lt;br /&gt;&lt;br /&gt;It's really creepy.&lt;br /&gt;&lt;br /&gt;One time I moved the cell phone away from my leg, but I could still feel the vibration in my leg.  I could feel my leg actually vibrating with my hand.  I couldn't get it to stop.  My leg kept on "ringing" occasionally for quite some time.  I have started keeping the phone in a different pocket.&lt;br /&gt;&lt;br /&gt;Judging by the number of "I thought it was just me..." responses in &lt;a href="http://ehealthforum.com/health/topic14052.html"&gt;a forum I found online&lt;/a&gt;, this is a surprisingly common phenomenon.  According to &lt;a href="http://jscms.jrn.columbia.edu/cns/2005-05-03/orso-phantomvibes/"&gt;this article&lt;/a&gt;, it happens when you are expecting a call.  I don't get very many calls, so it does not take much!&lt;br /&gt;&lt;br /&gt;Yikes!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jscms.jrn.columbia.edu/cns/2005-05-03/orso-phantomvibes/"&gt;Who's calling? Is it your leg or your cell phone? — JSCMS&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.usatoday.com/news/health/2007-06-12-cellphones_N.htm?csp=34"&gt;Good vibrations? Bad? None at all? - USATODAY.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://digg.com/health/Have_You_Noticed_the_Cell_Phone_Phantom_Vibration_Syndrome"&gt;Digg - Have You Noticed the Cell Phone "Phantom Vibration Syndrome"?&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-6040309973703633912?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/6040309973703633912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=6040309973703633912' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/6040309973703633912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/6040309973703633912'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/07/phantom-cell-phone-vibrations.html' title='Phantom cell phone vibrations'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-3031049177371722146</id><published>2007-07-09T11:28:00.000-07:00</published><updated>2007-07-09T12:29:16.104-07:00</updated><title type='text'>Using rxvt in cygwin</title><content type='html'>I don't like the default cygwin bash window.&lt;br /&gt;&lt;br /&gt;To get a nice terminal in cygwin, I have been typing "rxvt" from the cygwin bash shell for years. After several previous abortive attempts, I have finally succeeded in creating a clickable icon that directly launches a nice rxvt (xterm-like) terminal window under Windows.&lt;br /&gt;&lt;br /&gt;The solution I found is described at &lt;a href="http://freemode.net/archives/000121.html"&gt;http://freemode.net/archives/000121.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I made a few modifications, because I like a larger font, and the batch file did not work for me without modification.&lt;br /&gt;&lt;br /&gt;My ~/.Xdefaults file looks like this now:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;! ~/.Xdefaults - X default resource settings&lt;br /&gt;Rxvt*geometry: 120x40&lt;br /&gt;Rxvt*background: #000020&lt;br /&gt;Rxvt*foreground: #ffffbf&lt;br /&gt;!Rxvt*borderColor: Blue&lt;br /&gt;!Rxvt*scrollColor: Blue&lt;br /&gt;!Rxvt*troughColor: Gray&lt;br /&gt;Rxvt*scrollBar: True&lt;br /&gt;Rxvt*scrollBar_right: True&lt;br /&gt;! Rxvt*font: Lucida Console-12&lt;br /&gt;Rxvt*font: fixedsys&lt;br /&gt;Rxvt*SaveLines: 10000&lt;br /&gt;Rxvt*loginShell: True&lt;br /&gt;! VIM-like colors&lt;br /&gt;Rxvt*color0:    #000000&lt;br /&gt;Rxvt*color1:    #FFFFFF&lt;br /&gt;Rxvt*color2:    #00A800&lt;br /&gt;Rxvt*color3:    #FFFF00&lt;br /&gt;Rxvt*color4:    #0000A8&lt;br /&gt;Rxvt*color5:    #A800A8&lt;br /&gt;Rxvt*color6:    #00A8A8&lt;br /&gt;Rxvt*color7:    #D8D8D8&lt;br /&gt;Rxvt*color8:    #000000&lt;br /&gt;Rxvt*color9:    #FFFFFF&lt;br /&gt;Rxvt*color10:   #00A800&lt;br /&gt;Rxvt*color11:   #FFFF00&lt;br /&gt;Rxvt*color12:   #0000A8&lt;br /&gt;Rxvt*color13:   #A800A8&lt;br /&gt;Rxvt*color14:   #00A8A8&lt;br /&gt;Rxvt*color15:   #D8D8D8&lt;br /&gt;! eof&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;My replacement for the default "cygwin.bat", which I call "cygwin-rxvt.bat" is as follows:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;@echo off&lt;br /&gt;C:&lt;br /&gt;chdir C:\cygwin\bin&lt;br /&gt;set EDITOR=vi&lt;br /&gt;set VISUAL=vi&lt;br /&gt;set CYGWIN=codepage:oem tty binmode title&lt;br /&gt;set HOME=\cygwin\home\spud&lt;br /&gt;rxvt -e /bin/tcsh -l&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You will notice that I use tcsh rather than bash.  Yes, yes, I know that hard-core UNIX geeks disdain tcsh and only use bash.  Shut up.  I don't care about you.&lt;br /&gt;&lt;br /&gt;Finally, I use a simple prompt with tcsh, which has the side effect of setting the title bar for xterm-like terminals (including rxvt).  I add the following line to my .tcshrc file:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;set prompt="%{\033]0;%~%L\007%}\[%h\]&gt; "&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-3031049177371722146?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/3031049177371722146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=3031049177371722146' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/3031049177371722146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/3031049177371722146'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/07/using-rxvt-in-cygwin.html' title='Using rxvt in cygwin'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-402973903706305387</id><published>2007-04-22T14:27:00.000-07:00</published><updated>2007-04-24T07:55:13.966-07:00</updated><title type='text'>Extracting the magnitude component of an image Fourier transform</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_zfTsYEB4J6A/RivaiVPpxDI/AAAAAAAAAD0/jBBecYKN3dQ/s1600-h/mag_four_mask_gray_scale1L.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_zfTsYEB4J6A/RivaiVPpxDI/AAAAAAAAAD0/jBBecYKN3dQ/s320/mag_four_mask_gray_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5056375290006717490" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;New result!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I finally succeeded in extracting the magnitude component of the image Fourier transform (shown at right).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Recapping the story so far&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I previously created a picture of a bird, and a slightly translated version of the same image.  I intend to use these images to test ideas about using the Fourier transform to automatically align pairs of images to create aligned stereoscopic pairs.&lt;br /&gt;&lt;br /&gt;The input images, show in the previous post, are summarized below:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_zfTsYEB4J6A/Rigy9VPpw5I/AAAAAAAAACk/IbtoZp241Uw/s1600-h/scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_zfTsYEB4J6A/Rigy9VPpw5I/AAAAAAAAACk/IbtoZp241Uw/s200/scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346610979586962" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Original image&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/Rigy9lPpw6I/AAAAAAAAACs/Lskj7G6sLf4/s1600-h/trans_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/Rigy9lPpw6I/AAAAAAAAACs/Lskj7G6sLf4/s200/trans_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346615274554274" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Translated version of the original image, for testing my hypothesis.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RigzPlPpw_I/AAAAAAAAADU/juoI4TY1lLk/s1600-h/four_mask_gray_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RigzPlPpw_I/AAAAAAAAADU/juoI4TY1lLk/s200/four_mask_gray_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346924512199666" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Fourier transform of original, masked image.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RigzPlPpxAI/AAAAAAAAADc/8wX9uE3LRak/s1600-h/four_mask_gray_trans_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RigzPlPpxAI/AAAAAAAAADc/8wX9uE3LRak/s200/four_mask_gray_trans_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346924512199682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Fourier transform of translated, masked image&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I took the plunge and learned to write a filter using the pbmplus environment (see previous post).  Here is the program as I wrote and used it for this post:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;The new PGM filter I made&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I understand that it is tedious to mix GIMP and PBM tools in an image processing pipeline.  Perhaps I will port the FFT image processing to PBM later...&lt;br /&gt;&lt;br /&gt;What follows next is C language source code I just now wrote for a new image filter in the PBMPlus or NetPBM image processing tool kit:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;em&gt;/* pgm_fourier_recast.c - read a portable graymap produced by the&lt;br /&gt;** GIMP Fourier plug-in, and extract magnitude and phase components&lt;br /&gt;**&lt;br /&gt;** Copyright (C) 2007 by biospud@blogger.com&lt;br /&gt;**&lt;br /&gt;** Permission to use, copy, modify, and distribute this software and its&lt;br /&gt;** documentation for any purpose and without fee is hereby granted, provided&lt;br /&gt;** that the above copyright notice appear in all copies and that both that&lt;br /&gt;** copyright notice and this permission notice appear in supporting&lt;br /&gt;** documentation.  This software is provided "as is" without express or&lt;br /&gt;** implied warranty.&lt;br /&gt;*/&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;/*&lt;br /&gt;** 1) Place source file pgm_fourier_recast.c in directory with working build of netpbm/editor&lt;br /&gt;** 2) Add "pgm_fourier_recast" to list of files in Makefile&lt;br /&gt;** 3) "make pgm_fourier_recast" from netpbm/editor directory&lt;br /&gt;*/&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;#include&lt;/tt&gt; &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;tt&gt;#include&lt;/tt&gt; &amp;lt;math.h&amp;gt;&lt;br /&gt;&lt;tt&gt;#include&lt;/tt&gt; &lt;i&gt;"pgm.h"&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;typedef&lt;/b&gt; &lt;b&gt;struct&lt;/b&gt; pgm_image_struct {&lt;br /&gt;&lt;b&gt;int&lt;/b&gt; height;&lt;br /&gt;&lt;b&gt;int&lt;/b&gt; width;&lt;br /&gt;gray maximumValue;&lt;br /&gt;gray** data;&lt;br /&gt;} PgmImage;&lt;br /&gt;&lt;br /&gt;PgmImage getInputImage( &lt;b&gt;int&lt;/b&gt; argc, &lt;b&gt;char&lt;/b&gt; *argv[] );&lt;br /&gt;PgmImage convertFourierToPhaseMagnitude(PgmImage inputImage);&lt;br /&gt;&lt;b&gt;void&lt;/b&gt; writeImageAndQuit(PgmImage outputImage);&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; gimpFourierPixelToDouble(PgmImage image, &lt;b&gt;int&lt;/b&gt; x, &lt;b&gt;int&lt;/b&gt; y);&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; getNormalizationFactor(PgmImage image, &lt;b&gt;int&lt;/b&gt; x, &lt;b&gt;int&lt;/b&gt; y);&lt;br /&gt;gray doubleToGimpFourierPixel(&lt;b&gt;double&lt;/b&gt; value, PgmImage image, &lt;b&gt;int&lt;/b&gt; x, &lt;b&gt;int&lt;/b&gt; y);&lt;br /&gt;&lt;br /&gt;&lt;b&gt;int&lt;/b&gt; main( &lt;b&gt;int&lt;/b&gt; argc, &lt;b&gt;char&lt;/b&gt; *argv[] )&lt;br /&gt;{&lt;br /&gt;PgmImage inputImage;&lt;br /&gt;PgmImage outputImage;&lt;br /&gt;&lt;br /&gt;inputImage = getInputImage(argc, argv);&lt;br /&gt;outputImage = convertFourierToPhaseMagnitude(inputImage);&lt;br /&gt;writeImageAndQuit(outputImage);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;PgmImage getInputImage( &lt;b&gt;int&lt;/b&gt; argc, &lt;b&gt;char&lt;/b&gt; *argv[] ) {&lt;br /&gt;&lt;b&gt;const&lt;/b&gt; &lt;b&gt;char&lt;/b&gt;* &lt;b&gt;const&lt;/b&gt; usage = &lt;i&gt;"[pgmfile]"&lt;/i&gt;;&lt;br /&gt;&lt;b&gt;int&lt;/b&gt; argn;&lt;br /&gt;FILE* inputFile;&lt;br /&gt;&lt;br /&gt;PgmImage answer;&lt;br /&gt;&lt;br /&gt;pgm_init( &amp;amp;argc, argv );&lt;br /&gt;&lt;br /&gt;argn = 1;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;if&lt;/b&gt; ( argn &amp;lt; argc ) {&lt;br /&gt;  inputFile = pm_openr( argv[argn] );&lt;br /&gt;  ++argn;&lt;br /&gt;} &lt;b&gt;else&lt;/b&gt; {&lt;br /&gt;  inputFile = stdin;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;if&lt;/b&gt; ( argn != argc )&lt;br /&gt;pm_usage( usage );&lt;br /&gt;&lt;br /&gt;answer.data = pgm_readpgm(&lt;br /&gt;    inputFile,&lt;br /&gt;    &amp;answer.width,&lt;br /&gt;    &amp;amp;answer.height,&lt;br /&gt;    &amp;answer.maximumValue&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;pm_close( inputFile );&lt;br /&gt;&lt;br /&gt;&lt;b&gt;return&lt;/b&gt; answer;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; gimpFourierPixelToDouble(PgmImage image, &lt;b&gt;int&lt;/b&gt; x, &lt;b&gt;int&lt;/b&gt; y) {&lt;br /&gt;&lt;em&gt;/*&lt;br /&gt;** based on source code at&lt;br /&gt;** http://people.via.ecp.fr/~remi/soft/gimp/gimp_plugin_en.php3&lt;br /&gt;*/&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;gray pixel = image.data[x][y];&lt;br /&gt;&lt;br /&gt;&lt;em&gt;/*&lt;br /&gt;** renormalize&lt;br /&gt;** from (range 0 -&amp;gt; 255)&lt;br /&gt;** to range (-128 -&amp;gt; +127),&lt;br /&gt;*/&lt;/em&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; d128 = (&lt;b&gt;double&lt;/b&gt;)(pixel) - 128.0; &lt;em&gt;/* double128() */&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; bounded = (d128 / 128.0); &lt;em&gt;/* unboost() */&lt;/em&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; unboosted0 = 160 * (bounded * bounded); &lt;em&gt;/* unboost() */&lt;/em&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; unboosted = d128 &amp;gt; 0 ? unboosted0 : -unboosted0;  &lt;em&gt;/* unboost() */&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; answer = unboosted / getNormalizationFactor(image, x, y);&lt;br /&gt;&lt;br /&gt;&lt;b&gt;return&lt;/b&gt; answer;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;em&gt;/* Normalization factor that corrects scale of Fourier transform&lt;br /&gt;** pixel based upon distance from origin&lt;br /&gt;*/&lt;/em&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; getNormalizationFactor(PgmImage image, &lt;b&gt;int&lt;/b&gt; x, &lt;b&gt;int&lt;/b&gt; y) {&lt;br /&gt;&lt;em&gt;/*&lt;br /&gt;** based on source code at&lt;br /&gt;** http://people.via.ecp.fr/~remi/soft/gimp/gimp_plugin_en.php3&lt;br /&gt;*/&lt;/em&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; cx = (&lt;b&gt;double&lt;/b&gt;)abs(x - (image.width + 1)/2 + 1);&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; cy = (&lt;b&gt;double&lt;/b&gt;)abs(y - (image.height + 1)/2 + 1);&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; energy = (sqrt(cx) + sqrt(cy));&lt;br /&gt;&lt;b&gt;return&lt;/b&gt; energy*energy;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;gray doubleToGimpFourierPixel(&lt;b&gt;double&lt;/b&gt; value, PgmImage image, &lt;b&gt;int&lt;/b&gt; x, &lt;b&gt;int&lt;/b&gt; y) {&lt;br /&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; normalized = value * getNormalizationFactor(image, x, y);&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; bounded = fabs( normalized / 160.0 );&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; boosted0 = 128.0 * sqrt (bounded);&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; boosted = (value &amp;gt; 0) ? boosted0 : -boosted0;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;/*&lt;br /&gt;** renormalize&lt;br /&gt;** from range (-128 -&amp;gt; +127),&lt;br /&gt;** to (range 0 -&amp;gt; 255)&lt;br /&gt;*/&lt;/em&gt;&lt;br /&gt;&lt;b&gt;int&lt;/b&gt; answer = (&lt;b&gt;int&lt;/b&gt;)boosted + 128;&lt;br /&gt;&lt;b&gt;if&lt;/b&gt; (answer &amp;gt;= 255) &lt;b&gt;return&lt;/b&gt; 255;&lt;br /&gt;&lt;b&gt;if&lt;/b&gt; (answer &amp;lt;= 0) &lt;b&gt;return&lt;/b&gt; 0;&lt;br /&gt;&lt;b&gt;return&lt;/b&gt; answer;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;PgmImage convertFourierToPhaseMagnitude(PgmImage inputImage) {&lt;br /&gt;PgmImage answer;&lt;br /&gt;&lt;b&gt;int&lt;/b&gt; outRows = inputImage.height;&lt;br /&gt;&lt;b&gt;int&lt;/b&gt; outCols = inputImage.width;&lt;br /&gt;&lt;b&gt;int&lt;/b&gt; row, col;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; realDouble, imaginaryDouble;&lt;br /&gt;&lt;b&gt;double&lt;/b&gt; magnitudeDouble, phaseDouble;&lt;br /&gt;gray realPixel, imaginaryPixel;&lt;br /&gt;gray magnitudePixel, phasePixel;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;int&lt;/b&gt; doUsePhase = 0;&lt;br /&gt;&lt;br /&gt;answer.height = outRows;&lt;br /&gt;answer.width = outCols;&lt;br /&gt;answer.maximumValue = inputImage.maximumValue;&lt;br /&gt;answer.data = pgm_allocarray( outCols, outRows );&lt;br /&gt;&lt;br /&gt;&lt;b&gt;for&lt;/b&gt; ( row = 0; row &amp;lt; outRows; ++row ) {&lt;br /&gt;  &lt;b&gt;for&lt;/b&gt; ( col = 0; col &amp;lt; outCols; col += 2) {&lt;br /&gt;        &lt;em&gt;/* get pixel values from image */&lt;/em&gt;&lt;br /&gt;        realPixel = inputImage.data[row][col];&lt;br /&gt;        imaginaryPixel = inputImage.data[row][col + 1];&lt;br /&gt;&lt;br /&gt;        &lt;em&gt;/* convert to doubles */&lt;/em&gt;&lt;br /&gt;        realDouble = gimpFourierPixelToDouble(inputImage, row, col);&lt;br /&gt;        imaginaryDouble = gimpFourierPixelToDouble(inputImage, row, col);&lt;br /&gt;&lt;br /&gt;        &lt;em&gt;/* convert real/imaginary to magnitude/phase */&lt;/em&gt;&lt;br /&gt;        magnitudeDouble = sqrt(&lt;br /&gt;            realDouble * realDouble +&lt;br /&gt;            imaginaryDouble * imaginaryDouble&lt;br /&gt;            );&lt;br /&gt;&lt;br /&gt;        &lt;em&gt;/* convert to pixel values */&lt;/em&gt;&lt;br /&gt;        magnitudePixel = doubleToGimpFourierPixel(&lt;br /&gt;            magnitudeDouble,&lt;br /&gt;            inputImage, row, col&lt;br /&gt;            );&lt;br /&gt;&lt;br /&gt;        &lt;b&gt;if&lt;/b&gt; (doUsePhase) {&lt;br /&gt;            phaseDouble = atan2(imaginaryDouble, realDouble);&lt;br /&gt;&lt;br /&gt;            phasePixel = (&lt;b&gt;int&lt;/b&gt;)(256.0 * phaseDouble / (2.0 * 3.14159));&lt;br /&gt;            &lt;b&gt;while&lt;/b&gt; (phasePixel &amp;gt; 255) phasePixel -= 256;&lt;br /&gt;            &lt;b&gt;while&lt;/b&gt; (phasePixel &amp;lt; 0) phasePixel += 256;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;em&gt;/*&lt;br /&gt;        i1 = inputImage.data[row][col];&lt;br /&gt;        v = gimpFourierPixelToDouble(inputImage, row, col);&lt;br /&gt;        i2 = doubleToGimpFourierPixel(v, inputImage, row, col);&lt;br /&gt;        printf("%.3g\t%.3g\t%.3g\t%.3g\n",&lt;br /&gt;            realDouble, imaginaryDouble, magnitudeDouble, phaseDouble);&lt;br /&gt;        */&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;      answer.data[row][col] = magnitudePixel;&lt;br /&gt;&lt;br /&gt;        &lt;b&gt;if&lt;/b&gt; (doUsePhase)&lt;br /&gt;          answer.data[row][col + 1] = phasePixel;&lt;br /&gt;        &lt;b&gt;else&lt;/b&gt;&lt;br /&gt;          answer.data[row][col + 1] = magnitudePixel;&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;return&lt;/b&gt; answer;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;void&lt;/b&gt; writeImageAndQuit(PgmImage outputImage) {&lt;br /&gt;&lt;em&gt;/* Write resulting image */&lt;/em&gt;&lt;br /&gt;pgm_writepgm(&lt;br /&gt;    stdout,&lt;br /&gt;    outputImage.data,&lt;br /&gt;    outputImage.width,&lt;br /&gt;    outputImage.height,&lt;br /&gt;    outputImage.maximumValue,&lt;br /&gt;    0&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;&lt;em&gt;/* and clean up */&lt;/em&gt;&lt;br /&gt;pm_close( stdout );&lt;br /&gt;pgm_freearray(&lt;br /&gt;    outputImage.data,&lt;br /&gt;    outputImage.height&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;exit( 0 );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;Original vs. translated images in Fourier magnitude space:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Phew! After writing this filter, I created the following "magnitude only" versions of the test images:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RivUI1PpxBI/AAAAAAAAADk/UlGf3ifVKCI/s1600-h/mag_four_mask_gray_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RivUI1PpxBI/AAAAAAAAADk/UlGf3ifVKCI/s200/mag_four_mask_gray_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5056368254850286610" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Original: Magnitude component of Fourier transform of original image&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RivUI1PpxCI/AAAAAAAAADs/UfbIvsNEaBs/s1600-h/mag_four_mask_gray_trans_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RivUI1PpxCI/AAAAAAAAADs/UfbIvsNEaBs/s200/mag_four_mask_gray_trans_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5056368254850286626" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Translated: Magnitude component of Fourier transform of translated image&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;A superficial look suggests that the magnitude component is in fact very similar between the two images.  But for automation, I need a quantitative measure to decide how similar two images are.  More next time...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-402973903706305387?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/402973903706305387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=402973903706305387' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/402973903706305387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/402973903706305387'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/04/extracting-magnitude-component-of-image.html' title='Extracting the magnitude component of an image Fourier transform'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_zfTsYEB4J6A/RivaiVPpxDI/AAAAAAAAAD0/jBBecYKN3dQ/s72-c/mag_four_mask_gray_scale1L.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-5049321363095076921</id><published>2007-04-19T15:58:00.000-07:00</published><updated>2007-04-23T10:40:40.201-07:00</updated><title type='text'>Testing my Fourier transform hypothesis</title><content type='html'>In the past few posts I have repeatedly assumed that the magnitude component of the Fourier transform of an image will be relatively unchanged when the original image is translated vertically and/or horizontally.  My next task should be either prove or disprove this hypothesis before going much further.&lt;br /&gt;&lt;br /&gt;Let's start with two gray-scale images that differ only in horizontal alignment for testing.  If my intuition is correct, the magnitude portion of the Fourier transform should differ only slightly between the two images.&lt;br /&gt;&lt;br /&gt;I downloaded and installed &lt;a href="http://netpbm.sourceforge.net/"&gt;NetPBM&lt;/a&gt;, to facilitate command line processing of images.  I suspect that it will be easier for me to write new pbm filters than to write GIMP plug-ins.&lt;br /&gt;&lt;br /&gt;One infuriating thing about NetPBM is that one of the maintainers has destroyed many of the original man pages in an effort to "simplify" the distribution.  I genuinely appreciate this dude taking on the responsibility to maintain the code, but this one horrible documentation decision has caused me to curse out loud many times in the past several years.  My feelings are neatly summed up by the &lt;a href="http://mail-index.netbsd.org/tech-pkg/2004/07/24/0029.html"&gt;observations of another user&lt;/a&gt; on the netbsd packaging discussion list:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;"...I want the manual as released with the code I'm using, no changes after the fact.  Release your manuals, don't blog them.  it is *IMPOSSIBLE* for me to get that manual, no matter how many hoops I jump through, because you cannot (as they suggest) 'wget' an old version of the manual, one which still has manual pages instead of links to other non-Netpbm projects featured on the top page, one which has actual documentation for pnmscale rather than a three-page rant about why I should switch to Netpam..."&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Hear hear.&lt;br /&gt;&lt;br /&gt;In any case, here is a visual overview of the experiment set-up:&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_zfTsYEB4J6A/Rigy9VPpw5I/AAAAAAAAACk/IbtoZp241Uw/s1600-h/scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_zfTsYEB4J6A/Rigy9VPpw5I/AAAAAAAAACk/IbtoZp241Uw/s200/scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346610979586962" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Original image&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;One thing I will need is a method to compare how similar two images are.  As a control, I will be comparing the original image to itself.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/Rigy9lPpw6I/AAAAAAAAACs/Lskj7G6sLf4/s1600-h/trans_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/Rigy9lPpw6I/AAAAAAAAACs/Lskj7G6sLf4/s200/trans_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346615274554274" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Translated version of the original image, for testing my hypothesis.&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;If I am right about the Fourier transform, the magnitudes of the Fourier transform will be almost the same between the original image and the translated one.  This will simulate the comparison of stereo pairs that do not perfectly line up.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/Rigy9lPpw7I/AAAAAAAAAC0/neM3mesf-is/s1600-h/gray_trans_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/Rigy9lPpw7I/AAAAAAAAAC0/neM3mesf-is/s200/gray_trans_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346615274554290" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Gray version of the translated image&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;To simplify the analysis, I created a gray-scale version of the images, so the issue of the color channels does not complicate the analysis.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/Rigy9lPpw8I/AAAAAAAAAC8/mCshT-N6fOA/s1600-h/circle_mask.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/Rigy9lPpw8I/AAAAAAAAAC8/mCshT-N6fOA/s200/circle_mask.png" alt="" id="BLOGGER_PHOTO_ID_5055346615274554306" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The mask I used to "remove" the edges of the images&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;Recall from my earlier posting that the blurry circle mask is used to reduce edge artifacts in the Fourier transform.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_zfTsYEB4J6A/Rigy91Ppw9I/AAAAAAAAADE/hA62YYVA_Zg/s1600-h/mask_gray_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_zfTsYEB4J6A/Rigy91Ppw9I/AAAAAAAAADE/hA62YYVA_Zg/s200/mask_gray_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346619569521618" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Apply circle mask to untranslated image&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_zfTsYEB4J6A/RigzPVPpw-I/AAAAAAAAADM/o6Fqmexf3Z0/s1600-h/mask_gray_trans_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_zfTsYEB4J6A/RigzPVPpw-I/AAAAAAAAADM/o6Fqmexf3Z0/s200/mask_gray_trans_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346920217232354" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Masked version of translated image&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Finally, create the two Fourier transforms, one for the untranslated image and one for the translated image:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RigzPlPpw_I/AAAAAAAAADU/juoI4TY1lLk/s1600-h/four_mask_gray_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RigzPlPpw_I/AAAAAAAAADU/juoI4TY1lLk/s200/four_mask_gray_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346924512199666" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Fourier transform of original, masked image.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RigzPlPpxAI/AAAAAAAAADc/8wX9uE3LRak/s1600-h/four_mask_gray_trans_scale1L.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RigzPlPpxAI/AAAAAAAAADc/8wX9uE3LRak/s200/four_mask_gray_trans_scale1L.png" alt="" id="BLOGGER_PHOTO_ID_5055346924512199682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Fourier transform of translated, masked image&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;Next I need to extract the magnitudes of the Fourier transforms and compute the similarities between the images.  I have some ideas of how to do this, but it will require more work.  I expect that the PBM tools will come in handy here.  More next time...&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-5049321363095076921?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/5049321363095076921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=5049321363095076921' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5049321363095076921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5049321363095076921'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/04/testing-my-fourier-transform-hypothesis.html' title='Testing my Fourier transform hypothesis'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_zfTsYEB4J6A/Rigy9VPpw5I/AAAAAAAAACk/IbtoZp241Uw/s72-c/scale1L.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-8990414964274113190</id><published>2007-04-15T17:16:00.000-07:00</published><updated>2007-04-19T15:57:06.998-07:00</updated><title type='text'>Investigating the GIMP Fourier transform</title><content type='html'>In my &lt;a href="http://biospud.blogspot.com/2007/04/use-of-fourier-transform-in-aligning.html"&gt;previous post&lt;/a&gt; I began to work up how we might use the Fourier transform to help align two images that form a 3D stereoscopic image pair.&lt;br /&gt;&lt;br /&gt;A more detailed investigation reveals that we need to ask a few more questions.&lt;br /&gt;&lt;br /&gt;I sort of understand what the Fourier transform means for scalar data. But in an image, there are three &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;different&lt;/span&gt; channels of color information, usually decomposed in one of two ways.&lt;br /&gt;&lt;br /&gt;Two different representations of three-dimensional color data in an image pixel:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;red, green, and blue (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;RGB&lt;/span&gt;&lt;/span&gt;), or alternatively as&lt;br /&gt;&lt;/li&gt;&lt;li&gt;hue, saturation, and brightness.  (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;HSV&lt;/span&gt;&lt;/span&gt;)&lt;/li&gt;&lt;/ol&gt;For any ONE of these channels (&lt;span style="font-style: italic;"&gt;e.g.&lt;/span&gt; "red"), I can kind of understand what the Fourier transform is.  The transform for any single channel should result in a complex number in each pixel of the transform.  Complex numbers have two components.  These two components of a complex number can be represented in at least two different ways.&lt;br /&gt;&lt;br /&gt;Two different representations of a two dimensional complex number:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Real component and Imaginary component&lt;/li&gt;&lt;li&gt;Magnitude and phase&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RiLJcrPjLuI/AAAAAAAAACc/NUAAnzMHiOs/s1600-h/complex.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RiLJcrPjLuI/AAAAAAAAACc/NUAAnzMHiOs/s320/complex.png" alt="" id="BLOGGER_PHOTO_ID_5053823226344582882" border="0" /&gt;&lt;/a&gt;Two ways of representing a complex number: magnitude/phase and real/imaginary&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The bottom line here is that is seems to me that the Fourier transform should have twice as much data as the original image, since the Fourier transform takes regular real numbers, and generates complex numbers.  So a regular 3-channel image should create a Fourier transform with 6 channels.  So what exactly is in the Fourier transform generated by the &lt;a href="http://people.via.ecp.fr/%7Eremi/soft/gimp/gimp_plugin_en.php3"&gt;GIMP plug-in&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;Unfortunately the &lt;a href="http://people.via.ecp.fr/%7Eremi/sitewrapper.php3?src=ecp/tpi/rapport/fourier.html"&gt;documentation for the plug-in&lt;/a&gt; is in French, and I have not studied French since the mid-1970s.&lt;br /&gt;&lt;br /&gt;Understanding how the transform data are represented is especially important at this point for two reasons:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The whole trick of using the Fourier transform to ignore the horizontal/vertical translation component requires that we use only the magnitude of the complex numbers (which does not depend upon the image translation), and &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;ignore&lt;/span&gt; the phase &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;component&lt;/span&gt; (which depends exquisitely upon the image translation).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Where are the six channels of data that should be coming from the Fourier transform?&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;So we need to determine whether the complex Fourier transform is stored as real/imaginary components, or if it is stored as magnitude/phase components.  More fundamentally, we need to know how six channels of information are being stored in the seemingly 3 or 4 channeled image data (transparency can provide an additional channel).&lt;br /&gt;&lt;br /&gt;I did some experimentation and determined that the red channel of the Fourier transform corresponds to the red channel of the original image, etc.  Excellent.&lt;br /&gt;&lt;br /&gt;Further, the &lt;a href="http://people.via.ecp.fr/%7Eremi/sitewrapper.php3?src=ecp/tpi/rapport/fourier.html"&gt;French documentation&lt;/a&gt; is surprisingly intelligible when filtered through &lt;a href="http://babelfish.altavista.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;AltaVista&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;babelfish&lt;/span&gt;&lt;/a&gt;.  I still don't quite understand all of the details, but it appears that the complex values are stored in pairs of subsequent pixels, representing the logarithm of the real component, followed by the logarithm of the imaginary component.  This is bad news.  I want the magnitude of the complex number, which is equal to the square root of the sum of the squares of the real and imaginary components (using Pythagoras' theorem).  It will be hairy to extract that information.  So I need to either a) find another Fourier transform image filter, b) write a GIMP plug-in that further processes these Fourier transform images, c) think of some other trick, or d) abandon this project.&lt;br /&gt;&lt;br /&gt;By the way, if you read the English translation of the French documentation, there is a good explanation of why, near the end of the article, he compares his simulated image to a "moose".  It turns out that the French word for "moose" is "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;orignal&lt;/span&gt;", while the French word for "original" is "original".  The author made a typo, misspelling "original" to accidentally type another actual French word.  Thus his spell-checker did not catch it.  I believe he meant to say that the simulated image resembles the original image, not that it resembles a moose.  Or not.  Who knows?&lt;br /&gt;&lt;br /&gt;I will cogitate some more on what to do next.  More next time...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-8990414964274113190?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/8990414964274113190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=8990414964274113190' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/8990414964274113190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/8990414964274113190'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/04/investigating-gimp-fourier-transform.html' title='Investigating the GIMP Fourier transform'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_zfTsYEB4J6A/RiLJcrPjLuI/AAAAAAAAACc/NUAAnzMHiOs/s72-c/complex.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-7771564642466562505</id><published>2007-04-15T15:38:00.000-07:00</published><updated>2007-04-17T07:59:56.206-07:00</updated><title type='text'>Use of Fourier transform in aligning stereoscopic image pairs</title><content type='html'>In my &lt;a href="http://biospud.blogspot.com/2007/04/toward-automatic-alignment-of.html"&gt;previous post&lt;/a&gt;, I wondered how to begin to determine parameters for aligning two images, when no other parameters have yet been determined.&lt;br /&gt;&lt;br /&gt;One concept that can help is the Fourier transform.  The Fourier transform can be used to eliminate the vertical and horizontal alignment components from the analysis.  Thus we should be able to determine certain parameters, such as scale and rotation, without having to first solve the vertical and horizontal alignment problem.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.gimp.org/"&gt;GIMP&lt;/a&gt; image tool has a &lt;a href="http://people.via.ecp.fr/%7Eremi/soft/gimp/gimp_plugin_en.php3"&gt;plug-in&lt;/a&gt; that permits computation of the Fourier transform of an image.  (Presumably &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Photoshop&lt;/span&gt; has a similar tool).&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_zfTsYEB4J6A/RiKnGLPjLpI/AAAAAAAAAB0/SHUUdwyGUJc/s320/scale1L.png" alt="Left bird image" /&gt;&lt;br /&gt;The unmodified left-eye view from yesterday&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RiKs6rPjLrI/AAAAAAAAACE/gYIEruhB58Y/s1600-h/four1scale1L.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RiKs6rPjLrI/AAAAAAAAACE/gYIEruhB58Y/s320/four1scale1L.png" alt="Fourier transform of left eye bird image" id="BLOGGER_PHOTO_ID_5053791855903452850" border="0" /&gt;&lt;/a&gt;Fourier transform of the same bird image, as generated by the GIMP plug in.&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;Believe it or not, the Fourier transform contains all of the information necessary to reconstruct the original image.&lt;br /&gt;&lt;br /&gt;It is difficult for the human eye to make sense of the Fourier transform image.  The two largest features are a big vertical stripe down the middle, and a horizontal stripe across the center.  Unfortunately, these features are a BAD thing.  They show that the Fourier transform is dominated by something I don't care about.&lt;br /&gt;&lt;br /&gt;What features of the original image have strong horizontal and vertical components, causing the primary features of the Fourier transform?  This is perhaps a subtle point: the &lt;span style="font-style: italic;"&gt;edges&lt;/span&gt; of the image cause these features.  This is a problem.  If we want to use the Fourier transform to detect the relative rotation between two images, we cannot have the edges of the image dominating the Fourier transform.  The vertical and horizontal edges of the images will be used to form the rotational alignment, and no rotation will occur.&lt;br /&gt;&lt;br /&gt;The solution is to remove the edges of the image before taking the Fourier transform.  But how do you remove the edges of an image?  Like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RiK3_rPjLsI/AAAAAAAAACM/QnkMDpmVeFw/s1600-h/maskscale1R.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RiK3_rPjLsI/AAAAAAAAACM/QnkMDpmVeFw/s320/maskscale1R.png" alt="" id="BLOGGER_PHOTO_ID_5053804036430704322" border="0" /&gt;&lt;/a&gt;Bird image with "edges removed"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I created a circular mask for the imtage, so that it would be radially symmetric, thus minimizing image shape artifacts in lining up the relative rotation of two images.  Further, I made the mask a blurry circle, figuring that a blurry edge would have more localized effects on only the low-resolution region of the Fourier transform.  The new Fourier transform of the "edge-removed" version of the bird is much smoother:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RiK3_rPjLtI/AAAAAAAAACU/31uUXleIXQ8/s1600-h/fourmaskscale1R.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RiK3_rPjLtI/AAAAAAAAACU/31uUXleIXQ8/s320/fourmaskscale1R.png" alt="" id="BLOGGER_PHOTO_ID_5053804036430704338" border="0" /&gt;&lt;/a&gt;Fourier transform of edge-removed bird image&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;It now becomes clear that many of the other primary features of that initial Fourier transform were also "ringing" artifacts related to the edge effect.  To sum up the results so far:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The Fourier transform looks like it might theoretically be a useful tool for determining the scale and/or rotation relationship between two images, without needing to first determine the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;translational&lt;/span&gt; components.&lt;/li&gt;&lt;li&gt;If we end up using the Fourier transform in this way, we should include a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;pre-processing&lt;/span&gt; step in which we make a blurry-edged circular version of the two images to be compared.&lt;/li&gt;&lt;/ol&gt;This is a small amount of progress, but I feel it will probably pay off.  More next time...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-7771564642466562505?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/7771564642466562505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=7771564642466562505' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/7771564642466562505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/7771564642466562505'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/04/use-of-fourier-transform-in-aligning.html' title='Use of Fourier transform in aligning stereoscopic image pairs'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_zfTsYEB4J6A/RiKnGLPjLpI/AAAAAAAAAB0/SHUUdwyGUJc/s72-c/scale1L.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-5510950255164329891</id><published>2007-04-15T14:07:00.000-07:00</published><updated>2007-04-15T17:15:43.804-07:00</updated><title type='text'>Toward automatic alignment of stereoscopic image pairs</title><content type='html'>When aligning the two images of a stereoscopic pair, we wish to determine the following parameters:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Scale: The relative scale between the two images.  Usually close to 1.0, but might vary if two cameras were used with slightly different zoom or distance.&lt;/li&gt;&lt;li&gt;Rotation: There may be a small relative rotation between the two images, either clockwise or counterclockwise.  This can be tedious to determine manually.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Eye axis:  The direction relating the left eye to the right eye is usually left to right, but might be off by a small angle.  For various special &lt;span style="font-style: italic;"&gt;ad &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;hoc&lt;/span&gt;&lt;/span&gt; stereoscopic techniques, such as 3D photos of the moon, determining this direction is very important.  It is tedious and imprecise to determine this axis manually.  Most folks just assume that the eye axis is perfectly horizontal and move on.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Translation: Alignment in the left/right direction and in the up/down direction.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Up/down: There is a single clear value for the correct alignment in the up/down direction, perpendicular to the eye axis.  This value can be determined manually, but should be amenable to automatic determination as well.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Left/right: Alignment along the eye-axis varies from pixel to pixel depending upon the depth of the subject.  This is how 3D photos work.  Determining left/right alignment may be the hardest part to automate.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Brightness and color balance:  Especially when the two images are taken with two cameras, as in my set-up, the two images may differ in brightness and color balance.  These differences should be corrected before generating a final stereo pair.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;How can you determine any of these relationships between two images when you don't know the values of the other parameters?  This can be a tricky problem.  And it probably requires some tricky solutions.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_zfTsYEB4J6A/RiKnGLPjLpI/AAAAAAAAAB0/SHUUdwyGUJc/s320/scale1L.png" alt="Left bird image" /&gt;&lt;img src="http://4.bp.blogspot.com/_zfTsYEB4J6A/RiKnGLPjLqI/AAAAAAAAAB8/42G7qYciWgE/s320/scale1R.png" alt="Right bird image" /&gt;&lt;br /&gt;&lt;/center&gt;&lt;div style="text-align: center;"&gt;The images above are a typical example of a raw stereoscopic pair.  The two images obviously differ in color balance, vertical alignment, and horizontal alignment.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I will attempt to attack the problem of determining each parameter in turn, in subsequent posts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-5510950255164329891?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/5510950255164329891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=5510950255164329891' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5510950255164329891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5510950255164329891'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/04/toward-automatic-alignment-of.html' title='Toward automatic alignment of stereoscopic image pairs'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_zfTsYEB4J6A/RiKnGLPjLpI/AAAAAAAAAB0/SHUUdwyGUJc/s72-c/scale1L.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-2258922336278046984</id><published>2007-04-07T09:56:00.000-07:00</published><updated>2007-04-07T10:08:21.815-07:00</updated><title type='text'>Hummingbird with tongue hanging out</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_zfTsYEB4J6A/RhfNhDS5siI/AAAAAAAAABU/E3rCDG_XfWc/s1600-h/DSC06787tongue.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_zfTsYEB4J6A/RhfNhDS5siI/AAAAAAAAABU/E3rCDG_XfWc/s320/DSC06787tongue.png" alt="" id="BLOGGER_PHOTO_ID_5050731474823262754" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Juvenile male Anna's hummingbird &lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-family:Geneva,Arial,sans-serif;font-size:100%;"  &gt;&lt;i&gt;(Calypte          anna) &lt;/i&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;tasting the air&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Just now I got a nice photo of a hummingbird sticking his tongue out (click bird for larger image).  Notice the fine silvery tongue extending beyond the tip of the beak.  This photo represents about the limit of image resolution I will be able to acheive with my current optical set-up.  I am pretty happy with this resolution.  Unfortunately, in this particular shot the companion camera image was out of focus, so there will be no stereoscopic version of this tongue shot forthcoming.  (Not that I have yet created &lt;span style="font-style: italic;"&gt;any&lt;/span&gt; 3D photos good enough to post!)&lt;br /&gt;&lt;br /&gt;Today's shoot was my first success at getting decent photos using mirrors.  Previously my mirror photos were too blurry and displayed second reflection artifacts.  Today I used first surface mirrors mounted more securely.  That seems to have done the trick!  Now perhaps I will be able to get stereoscopic photos with a smaller interpupilary separation.  With today's mirror setup, the separation is about 50 mm, which is still sort of big at this 400 mm distance.  I don't know how I can get it smaller though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-2258922336278046984?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/2258922336278046984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=2258922336278046984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/2258922336278046984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/2258922336278046984'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/04/hummingbird-with-tongue-hanging-out.html' title='Hummingbird with tongue hanging out'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_zfTsYEB4J6A/RhfNhDS5siI/AAAAAAAAABU/E3rCDG_XfWc/s72-c/DSC06787tongue.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-5181965410372297858</id><published>2007-04-04T18:46:00.000-07:00</published><updated>2007-04-04T18:52:56.256-07:00</updated><title type='text'>What a coincidence! Here's one with a full purple head now!</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_zfTsYEB4J6A/RhRVoTS5shI/AAAAAAAAABM/RpjXvPTmeWM/s1600-h/DSC06542.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_zfTsYEB4J6A/RhRVoTS5shI/AAAAAAAAABM/RpjXvPTmeWM/s320/DSC06542.png" alt="" id="BLOGGER_PHOTO_ID_5049755233051849234" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Deep magenta throat and crown of male Anna's hummingbird (&lt;/span&gt;&lt;i style="font-weight: bold;"&gt;Calypte anna&lt;/i&gt;&lt;span style="font-weight: bold;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;(click bird for larger image)&lt;br /&gt;&lt;br /&gt;Yesterday I said that the male Anna's hummingbird can have a completely magenta head.  On cue, my charming bride captured this image of a male in full display.  I guess the male in the earlier pictures is either a hybrid species, a juvenile, or just a mutant.  Perhaps it helps that the sky was overcast today.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-5181965410372297858?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/5181965410372297858/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=5181965410372297858' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5181965410372297858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5181965410372297858'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/04/what-coincidence-heres-one-with-full.html' title='What a coincidence! Here&apos;s one with a full purple head now!'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_zfTsYEB4J6A/RhRVoTS5shI/AAAAAAAAABM/RpjXvPTmeWM/s72-c/DSC06542.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-5064017176812725143</id><published>2007-04-03T17:20:00.000-07:00</published><updated>2007-04-03T17:46:13.038-07:00</updated><title type='text'>Male Anna's hummingbird at even higher resolution.</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_zfTsYEB4J6A/RhLvtdLWM0I/AAAAAAAAABE/3D6tRPDze14/s1600-h/DSC06513_enhance.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_zfTsYEB4J6A/RhLvtdLWM0I/AAAAAAAAABE/3D6tRPDze14/s320/DSC06513_enhance.png" alt="" id="BLOGGER_PHOTO_ID_5049361696441119554" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Male Anna's Hummingbird (&lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Calypte anna&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;) in repose at feeder&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;  My beautiful wife captured our best hummingbird pictures yet this morning (click bird for higher resolution view).  Notice the fine detail in the feathers.  This male Anna's hummingbird, like many male hummingbirds, has a bright red neck when viewed from certain angles.  I am uncertain whether this depends upon the orientation of the feathers, the orientation of the sun, the orientation of the person viewing, or some combination of those three.  In any case, the geometry of this bird was right to show the red throat.  From other angles, the throat of the male appears dark or black.  (The throat of the female is much paler.  See some of our previous photos in older posts).&lt;br /&gt;&lt;br /&gt;This species, Anna's hummingbird (&lt;span style="font-style: italic;"&gt;Calypte anna&lt;/span&gt;), is the only hummingbird species in which the crown (top of the head) of the male can also appear crimson (in addition to the throat).  If you look carefully at the photo above, you can see a few reddish feathers on the head.  Google image search for "Anna's Hummingbird" and you will find many images of male birds in which the entire head glows with a brilliant magenta color.  You have to view the bird from just the right angle to get that effect.&lt;br /&gt;&lt;br /&gt;On the lower left of this bird's throat is a region that is yellow-green, almost the exact complementary (opposite) color to the red-magenta seen on the rest of the throat.  I suspect that the complementary color viewed from a different angle is no coincidence.  It reminds me of the cytological stain eosin, which is colored red-magenta when you view light through the solution, but is yellow-olive when you view light reflected off of the solution's surface.  Eosin is one of the important stains used in Pap smears, and many other important microscopic tissue staining methods.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-5064017176812725143?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/5064017176812725143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=5064017176812725143' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5064017176812725143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5064017176812725143'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/04/male-annas-hummingbird-at-even-higher.html' title='Male Anna&apos;s hummingbird at even higher resolution.'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_zfTsYEB4J6A/RhLvtdLWM0I/AAAAAAAAABE/3D6tRPDze14/s72-c/DSC06513_enhance.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-5562287604375565954</id><published>2007-04-02T19:33:00.000-07:00</published><updated>2007-04-02T19:39:06.627-07:00</updated><title type='text'>Today's hummingbird pictures</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_zfTsYEB4J6A/RhG-CdLWMyI/AAAAAAAAAA0/gezorLOuHFE/s1600-h/DSC04674crop.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_zfTsYEB4J6A/RhG-CdLWMyI/AAAAAAAAAA0/gezorLOuHFE/s400/DSC04674crop.png" alt="" id="BLOGGER_PHOTO_ID_5049025606660272930" border="0" /&gt;&lt;/a&gt;What is that yellow material on the male hummingbird's beak?  Pollen?&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RhG9QNLWMwI/AAAAAAAAAAk/7DTxjW59KW8/s1600-h/DSC04680crop.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_zfTsYEB4J6A/RhG9QNLWMwI/AAAAAAAAAAk/7DTxjW59KW8/s400/DSC04680crop.png" alt="" id="BLOGGER_PHOTO_ID_5049024743371846402" border="0" /&gt;&lt;/a&gt;Notice the fluffy feathers on this male hummingbird's underside&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zfTsYEB4J6A/RhG9QNLWMwI/AAAAAAAAAAk/7DTxjW59KW8/s1600-h/DSC04680crop.png"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-5562287604375565954?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/5562287604375565954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=5562287604375565954' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5562287604375565954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/5562287604375565954'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/04/todays-hummingbird-pictures.html' title='Today&apos;s hummingbird pictures'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_zfTsYEB4J6A/RhG-CdLWMyI/AAAAAAAAAA0/gezorLOuHFE/s72-c/DSC04674crop.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-1933179209912848035</id><published>2007-03-24T17:11:00.000-07:00</published><updated>2007-03-24T17:16:00.526-07:00</updated><title type='text'>First clear Danio photo</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_zfTsYEB4J6A/RgW-omEbEUI/AAAAAAAAAAc/_tvnw_JCldg/s1600-h/danio1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_zfTsYEB4J6A/RgW-omEbEUI/AAAAAAAAAAc/_tvnw_JCldg/s400/danio1.png" alt="" id="BLOGGER_PHOTO_ID_5045648562161652034" border="0" /&gt;&lt;/a&gt;&lt;br /&gt; I just took this picture of a Danio (zebrafish) in our fish tank.  I used a flash, so I had to take the picture from an angle so that I didn't just take a picture of the reflection of the flash.  As with the hummingbird pictures, I took this with a two camera set up, so that I can create stereoscopic pictures.  Once I get better at composing the stereo pairs, I will start posting 3D pictures.  It is possible that I will make 3D versions of these same pictures that I am posting now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-1933179209912848035?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/1933179209912848035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=1933179209912848035' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/1933179209912848035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/1933179209912848035'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/03/first-clear-danio-photo.html' title='First clear Danio photo'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_zfTsYEB4J6A/RgW-omEbEUI/AAAAAAAAAAc/_tvnw_JCldg/s72-c/danio1.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-3476851083734343411</id><published>2007-03-18T15:56:00.000-07:00</published><updated>2007-03-29T16:59:34.716-07:00</updated><title type='text'>New hummingbird pictures.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_zfTsYEB4J6A/Rf3I9HjVzdI/AAAAAAAAAAU/G0C93iYAfwQ/s1600-h/crispbirdmono001.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_zfTsYEB4J6A/Rf3I9HjVzdI/AAAAAAAAAAU/G0C93iYAfwQ/s400/crispbirdmono001.jpg" alt="" id="BLOGGER_PHOTO_ID_5043408110049676754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;We started filling our hummingbird feeder about two weeks ago.  I think we already have a nesting pair settling down nearby.  I got some nice pictures this morning when the sun was shining on the feeder.  Shown here is a female.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-3476851083734343411?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/3476851083734343411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=3476851083734343411' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/3476851083734343411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/3476851083734343411'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2007/03/new-hummingbird-pictures.html' title='New hummingbird pictures.'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_zfTsYEB4J6A/Rf3I9HjVzdI/AAAAAAAAAAU/G0C93iYAfwQ/s72-c/crispbirdmono001.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-115457246013306156</id><published>2006-08-02T19:17:00.000-07:00</published><updated>2006-08-02T19:46:27.486-07:00</updated><title type='text'>Selenastrum capricornutum algae in our aquarium</title><content type='html'>&lt;a href="http://protist.i.hosei.ac.jp/PDB/Galleries/Uruguay1999/Selenastrum/gracile.jpg"&gt;&lt;img alt="Selenastrum" src="http://protist.i.hosei.ac.jp/PDB/Galleries/Uruguay1999/Selenastrum/gracile.jpg" align="right" border="0" width="200" /&gt;&lt;/a&gt;We started a ten gallon fish tank in our apartment four weeks ago.&lt;br /&gt;&lt;br /&gt;For the first three weeks, our aquarium went through the standard series of nitrogen compound crises that a new tank experiences before it is "cycled", as the fish tank enthusiasts say.  During those three weeks, our tank water was crystal clear.&lt;br /&gt;&lt;br /&gt;About one week ago, our nitrite levels fell abruptly to zero, indicating that our "biological filter" was now colonized by all of the bacteria needed to complete the nitrogen cycle.  As soon as the nitrite levels fell, algae began to grow.  The water in our tank is quite green.&lt;br /&gt;&lt;br /&gt;I placed a drop of our tank water on a microscope slide and viewed the contents at 150X with an inexpensive microscope I obtained in the 1970s.  There I found green U-shaped algae with pointy ends.  After a bit of google image searching, I conclude that the species of algae is &lt;span style="font-style: italic;"&gt;Selenastrum capricornutum&lt;/span&gt;, or &lt;span style="font-style: italic;"&gt;Selenastrum gracile&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;It's fun to identify the organisms in your home.  I recommend it.&lt;br /&gt;&lt;br /&gt;Other species I have identified in my home:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Homo sapiens notsosapiensis&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Danio rerio&lt;/span&gt; (zebra danios)&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;Palaemonetes kadakensis (ghost shrimp)&lt;/cite&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-115457246013306156?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/115457246013306156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=115457246013306156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/115457246013306156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/115457246013306156'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2006/08/selenastrum-capricornutum-algae-in-our.html' title='&lt;I&gt;Selenastrum capricornutum&lt;/I&gt; algae in our aquarium'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-114410059351749324</id><published>2006-04-03T14:43:00.000-07:00</published><updated>2006-04-03T14:43:14.760-07:00</updated><title type='text'>Const correctness and duck typing</title><content type='html'>I am a big fan of "const correctness" when programming in C++. It permits me to be a lazier programmer, but this is a good thing. It permits me to be a lazier programmer in the same way that these other language features do:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Using local variables instead of global variables&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Using formal loop constructs like "for", "while", and "do", instead of "GOTO"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Using iterators instead of looping with "for", "while", and "do"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Program to interfaces instead of implementations&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt; It is possible to write robust computer programs using only global variables, while branching using only GOTO statements. It simply requires more discipline on the part of the programmer. I am grateful that modern languages have features that permit me to be less disciplined while still writing maintainable code. The application of "const correctness" is one such language feature that make programs easier to write and maintain. I am amazed that it does not appear in other languages that I use, such as Java and Ruby.&lt;br /&gt;&lt;br /&gt;Sometimes Java and Ruby fanboys who do not understand what const-correctness is will assert that one can get the effect of the const keyword with "final" in Java or "freeze" in Ruby. That is utter nonsense.&lt;br /&gt;&lt;br /&gt;On the other hand, it is possible to get some of the const effect in Java by creating separate "ConstInterfaces" for each class. Unfortunately, such interfaces do not already exist for the standard library, and I believe that it is not possible to retroactively declare existing classes to conform to a particular Interface, even if they (syntactically) already do conform. The only alternative is to create derived wrapper classes for each standard class, explicitly declaring ConstInterfaces. Even this Herculean approach will fail with the many "final" classes in the standard library.  In keeping with the general ultra-wordiness of Java, the reams of additional source files and lines of code required to emulate const-correctness in Java make this approach essentially extinct in the wild.&lt;br /&gt;&lt;br /&gt;Ruby fanboys make a big deal about "duck typing", which is a fancy way of describing a lack of static typing.  Static typing means that something about the type of each variable can be determined in the local source code context.  "Duck typing" is more flexible than static typing in the same way that GOTO statements are more flexible than formal loops.  The one big advantage of lack-of-static-typing is that it permits languages like PERL and Ruby to have essentially zero compile time.  I love the possibilities that zero-compile-time languages create.  But please do not overextend this tradeoff and pretend that "we meant to do that" and that "duck typing" is somehow a desirable language feature.  Put the kool aid down.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-114410059351749324?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/114410059351749324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=114410059351749324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/114410059351749324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/114410059351749324'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2006/04/const-correctness-and-duck-typing.html' title='Const correctness and duck typing'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-114167687729005223</id><published>2006-03-06T12:27:00.000-08:00</published><updated>2006-03-06T12:27:57.340-08:00</updated><title type='text'>Eclipse IDE not updating to the latest version?</title><content type='html'>I just discovered that my Eclipse programming environment has not been updating itself to the latest version.  I have been stuck at Eclipse version 3.1.0 for the past year.  This is apparently due to a URL bug in the 3.1.0 release of Eclipse.  See Ed Burnette's site for details.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://eburnette.blogspot.com/2006/02/eclipse-updates-still-lag-behind.html"&gt;Ed Burnette's view from the asylum: Eclipse updates still lag behind&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(In short, add the site http://update.eclipse.org/updates/3.1 to your list of update sites under Help-&gt;Software Updates-&gt;Manage Configuration-&gt;Scan for Updates-&gt;Search for new features to install-&gt;New Remote Site...)&lt;br /&gt;&lt;br /&gt;I discovered this problem when trying to create two editor windows for one source file.  In Eclipse 3.1.0 editing two parts of the same file at the same time is not possible.  In 3.1.2, select "New Editor" from the Window menu to create a second Editor pane with the same file you are currently editing.  I am amazed that Eclipse lasted this long without such a feature designed into the original implementation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-114167687729005223?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/114167687729005223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=114167687729005223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/114167687729005223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/114167687729005223'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2006/03/eclipse-ide-not-updating-to-latest.html' title='Eclipse IDE not updating to the latest version?'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-114123752783130162</id><published>2006-03-01T10:25:00.000-08:00</published><updated>2006-03-01T10:55:41.196-08:00</updated><title type='text'>Unconventional telemarketing tactics : latest telephone harrassment</title><content type='html'>Last night I got a strange phone call. At about 7:45 pm PST Tuesday Feb 28, 2006 I was having supper with my wife when the phone rang. I suspect the caller was a telemarketer. You be the judge:&lt;br /&gt;&lt;br /&gt;&lt;begin&gt;&lt;br /&gt;&lt;br /&gt;Me: *picks up phone* Hello? *start counting seconds until response*&lt;br /&gt;&lt;br /&gt;Troubled gentleman: *five second pause* *click* Hello?&lt;br /&gt;&lt;br /&gt;Me: Why did you take so long to answer?&lt;br /&gt;&lt;br /&gt;Troubled gentleman: Why did it take YOU so long to answer? It must have taken five or six rings for you to pick up the phone! Like I have time for this shit!&lt;br /&gt;&lt;br /&gt;Me: Who is this?&lt;br /&gt;&lt;br /&gt;Troubled gentleman: You are being childish, sir.  *click*&lt;br /&gt;&lt;br /&gt;&lt;end&gt;&lt;br /&gt;&lt;br /&gt;It is difficult to figure out what his goal was from this short conversation. It is especially interesting that his final word was "sir". I guess some of his training must have sunk in...&lt;br /&gt;&lt;br /&gt;It is hard for me not to feel agitated after an attack like this. Even though its importance is so small. I understand that there is no point in seething after such a random encounter, but I cannot help but obsess a little over it. But don't worry about me. I have moved on now.&lt;/end&gt;&lt;/begin&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-114123752783130162?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/114123752783130162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=114123752783130162' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/114123752783130162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/114123752783130162'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2006/03/unconventional-telemarketing-tactics.html' title='Unconventional telemarketing tactics : latest telephone harrassment'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-114080251648424257</id><published>2006-02-24T09:35:00.000-08:00</published><updated>2006-02-24T09:35:16.526-08:00</updated><title type='text'>SBC still owes me ten dollars</title><content type='html'>But that is not the worst of it.  Not by a long shot.  Agents of SBC are continuing their mission to make my life miserable. &lt;br /&gt;&lt;br /&gt;Today, February 24, 2006, at 8:55 am, a well labeled SBC truck with license number California 5Y78601 illegally went straight from the right turn lane at Arastradero and Miranda streets in Los Altos, California, to get onto Foothill expressway.  To his left was a bicyclist in the bike lane who also wanted to get onto Foothill.  The retarded SBC guy made this very dangerous for the bicyclist.  And also for those of us trying to legally enter Foothill from the correct lane.&lt;br /&gt;&lt;br /&gt;I wouldn't bring this up were it not just one more episode of what must be a systematic effort by SBC to drive me insane with their obnoxious behavior.  Remind me to post my essay on the horrible ordeal of trying to get DSL installed from SBC.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-114080251648424257?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/114080251648424257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=114080251648424257' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/114080251648424257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/114080251648424257'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2006/02/sbc-still-owes-me-ten-dollars.html' title='SBC still owes me ten dollars'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-113900032037743383</id><published>2006-02-03T12:58:00.000-08:00</published><updated>2006-02-03T13:34:37.550-08:00</updated><title type='text'>Getting a good "Leaf" staff in Diablo II</title><content type='html'>In the computer game Diablo II, a sorceress who specializes in the skill "enchant" is a useful support character. One of the best items for an enchant sorceress is a staff with the runeword "Leaf". You can get one by shopping at the Act II normal vendor Drognan. "Leaf" uses the runes "Tir Ral", so you need a 2 socket staff.  And you want bonuses to the skill Enchant to be present on the staff.&lt;br /&gt;&lt;br /&gt;What follows are the details of how I shop for such a staff.&lt;br /&gt;&lt;br /&gt;You will not have to read (much) during your repeated trips to the shop.  Most of the visual scanning required consists of "is it a staff?", "is it red?", and "does it have 2 circles on it?".  This relieves some of the tedium of repeated shopping.&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Create or join a normal difficulty game, using a character that has reached Act 2, but which is no higher than level 17.&lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;Make sure that no other players are in the Act 2 town area.  Otherwise you will be unable to reset the shop contents.&lt;/li&gt;   &lt;li&gt;Make sure that Drognan's shop is next to a gate to the rocky waste.  This will make shopping much faster.&lt;/li&gt;   &lt;li&gt;Having faster run/walk is helpful here. Make sure you are always running (use the "R" key to toggle).&lt;/li&gt;   &lt;li&gt;Open Drognan's shop window.&lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;In each of the two "weapons" tabs, mouse over each staff that has a red background.  Because Enchant is a level 18 skill, and your shopper is level 17 or lower, every staff that has the Enchant skill must be red, indicating that it is above your current level.&lt;/li&gt;   &lt;li&gt;As you mouse over each red staff, look for ones that have exactly two sockets.  A staff must have exactly two sockets to hold the Leaf rune word.&lt;/li&gt;   &lt;li&gt;If no staves are both red and have two sockets, skip ahead to the "close shop window" step.  None of the staves in the shop are the one you are looking for.&lt;/li&gt;   &lt;li&gt;Ignore staves with a blue name (magic).  The name must be grey for the staff to hold a rune word.&lt;/li&gt;   &lt;li&gt;If the staff has "+3 Enchant" (and grey name and two sockets), this is exactly the staff you are looking for!  Buy it and rejoice.  Your shopping task is done.&lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;In the meantime, you may want to buy 2-socket staves with only +1 or +2 to enchant, in case you get too bored with the repeated shopping.&lt;/li&gt;   &lt;li&gt;Close the shop window.&lt;/li&gt;   &lt;li&gt;Run a short distance into the Rocky Waste, and then run back to Drognan.  The shop contents will  have magically reset.&lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;Go back to step 5 (open shop window), and repeat the process until you have a 2-socketed +3 enchant grey-named staff.&lt;/li&gt; &lt;/ol&gt; I have gotten about 5 leaf staves this way.  You can usually get one in less than an hour if you don't waste time.&lt;br /&gt;&lt;br /&gt;You won't be able to use the enchant skill on the staff until your character is level 18.  You won't be able to use the Leaf rune word until you are level 19.  So wait until you are level 19 before adding the runes.  This way you will be able to use the +3 to the enchant skill while your character is level 18.&lt;br /&gt;&lt;br /&gt;It is not possible to get a white or grey-named staff with both Enchant and Fire Mastery skills on it from a town vendor.  Such a staff can only be found in normal gameplay and is extremely valuable.  Keep your eyes open for a staff with these characteristics:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Enchant plus Fire Mastery bonuses combined are +4 or more. (e.g. +2 Enchant, +2 Fire Mastery)&lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;Staff has exactly zero, two, or four sockets.  (for Leaf or Memory rune words)&lt;/li&gt;   &lt;li&gt;Staff name is white or grey (i.e. non-magical)&lt;br /&gt;  &lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-113900032037743383?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/113900032037743383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=113900032037743383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113900032037743383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113900032037743383'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2006/02/getting-good-leaf-staff-in-diablo-ii.html' title='Getting a good &quot;Leaf&quot; staff in Diablo II'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-113890564863618973</id><published>2006-02-02T10:40:00.000-08:00</published><updated>2006-02-02T17:13:28.520-08:00</updated><title type='text'>Gmail is a terrible pop server</title><content type='html'>I have put my trust in Google and forwarded most of my mail accounts to my gmail account. As part of this I wanted to use gmail as my focus of mail reading.&lt;br /&gt;&lt;br /&gt;But I want to be able to read and compose email offline on my laptop, so I want to use a rich email client. And I want to use multiple clients on multiple computers. Gmail's feeble support for the POP protocol makes this difficult.&lt;br /&gt;&lt;br /&gt;Here are the problems:&lt;br /&gt;&lt;br /&gt;Gmail wants you to never delete your old mail. This is part of their "new way" of handling e-mail, and I can understand the justification. Unfortunately many POP email clients are usually configured to delete old messages from the POP server after they are downloaded. Perhaps reasonably, Gmail has decided to ignore this aspect of the POP protocol, so your messages on the Gmail server are not deleted by your POP email client. So far this is all justifiable. Somehow this has led Gmail to ignore other POP functionality in annoyingly useless ways.&lt;br /&gt;&lt;br /&gt;I like to read my email from multiple computers, each with a current and complete archive of my mails. Using decent and reasonable POP servers such as that provided by Comcast or other large ISPs, each client is able to sychronize with the POP server, downloading only those emails which that particular client has not yet seen before. This makes me happy.&lt;br /&gt;&lt;br /&gt;When I tried to get this same behavior from Gmail's POP server I could not.  My choices seem to be as follows:&lt;br /&gt;&lt;br /&gt;1) Each client can download every mail I have ever received at gmail at one time, including duplicates of any messages I got on that client before. This results in multiple copies of every email. This is so far beyond unacceptable that I will not discuss this further.&lt;br /&gt;&lt;br /&gt;2) Each client can download only those messages newer than those last downloaded by ANY email client of mine. This process puts distinct subsets of my email on each client, depending upon when I connect with each one. This too sucks very very very badly.&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/944/2000/1600/gmail_topology.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/944/2000/320/gmail_topology.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Use a real POP server. I created another special purpose email account at Comcast. The purpose of this account is to provide a decent POP interface to Gmail. I never use this special account to send, nor to directly receive any mails. A copy of every mail that comes to my gmail account is forwarded to this special comcast mail account. My email clients now sync with the special comcast email account and all is joy and happiness.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-113890564863618973?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/113890564863618973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=113890564863618973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113890564863618973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113890564863618973'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2006/02/gmail-is-terrible-pop-server.html' title='Gmail is a terrible pop server'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-113562871449479664</id><published>2005-12-26T12:20:00.000-08:00</published><updated>2006-02-02T17:50:54.576-08:00</updated><title type='text'>Rune rushing in Diablo II Lord of Destruction</title><content type='html'>&lt;h2&gt;Using Classic mode to accelerate Hellforge rune farming&lt;/h2&gt;What follows is a set of instructions for accumulating runes in the online game Diablo II: Lord of Destruction. Certain runes are the rarest and most valuable items in the game. This guide gives step by step instructions for gathering runes by repeatedly creating characters and performing the hellforge quest in each of three difficulties for each character.&lt;br /&gt;&lt;h3&gt;Definitions:&lt;/h3&gt; &lt;ul&gt;&lt;li&gt;"Rusher" - a character powerful enough to quickly clear areas and kill bosses&lt;/li&gt;&lt;li&gt;"Rushee" - a character created for the sole purpose of snagging their hellforge treasure&lt;/li&gt;&lt;li&gt;"New Rushee" - a rushee that has not completed the Andariel quest&lt;/li&gt;&lt;li&gt;"Andariel Rushee" - a rushee that has completed the Andariel quest, but no Act 2 quests&lt;/li&gt;&lt;li&gt;"Amulet Rushee" - a rushee that has completed the Viper Amulet quest, but has not completed the Summoner quest&lt;/li&gt;&lt;li&gt;"Summoner Rushee" - a rushee that has completed the Summoner Quest, but has not completed the Duriel quest&lt;/li&gt;&lt;li&gt;"Duriel Mule" - a character that has touched the Summoner's book, and inserted the staff into the orifice, but done no other Act 2 quest activities.&lt;/li&gt;&lt;li&gt;"N" - the number of computers available for the rushing operation&lt;/li&gt;&lt;/ul&gt;&lt;hr /&gt;&lt;h3&gt;General Rules&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;The rush steps repeat for each difficulty (Normal, Nightmare, Hell) (except that the Classic Hell rush phase ends at the beginning of Hell Act 3)&lt;/li&gt;&lt;li&gt;A rushee who completes one difficulty becomes a "New" rushee for the next difficulty&lt;/li&gt;&lt;li&gt;A rush through one difficulty requires one (1) Summoner Rushee, one (1) Duriel Mule, and (N-2) Andariel Rushees. (if these rushees already exist, proceed directly to DURIEL TO END instructions. Otherwise, create the necessary rushees using the recipes below&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Maggot lair only needs to be completed once per difficulty&lt;/li&gt;&lt;li&gt;Viper amulet quest only needs to be completed once per difficulty for every &lt;span style="font-family:courier new;"&gt;N&lt;/span&gt;&lt;sup style="font-family: courier new;"&gt;3&lt;/sup&gt;&lt;span style="font-family:courier new;"&gt; - 2N&lt;/span&gt;&lt;sup style="font-family: courier new;"&gt;2&lt;/sup&gt;&lt;span style="font-family:courier new;"&gt; + N&lt;/span&gt; rushees (80 rushees for N=5)&lt;/li&gt;&lt;li&gt;Summoner quest only needs to be completed once per difficulty for every &lt;span style="font-family:courier new;"&gt;N&lt;/span&gt;&lt;sup style="font-family: courier new;"&gt;2&lt;/sup&gt;&lt;span style="font-family:courier new;"&gt; - 2N + 1&lt;/span&gt; rushees (16 rushees for N=5)&lt;/li&gt;&lt;li&gt;Most other required quests are run once per difficulty for every N-1 rushees&lt;/li&gt;&lt;li&gt;Instructions for a second simultaneous rusher (Rusher B) are given in parentheses&lt;/li&gt;&lt;li&gt;If a rushee dies in a quest area, remain dead (i.e. don't hit escape) until the quest is completed. You will get credit for the quest.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;hr /&gt;&lt;h3&gt;CREATING NEW RUSHEES&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;For Normal difficulty, select "create new character" from the character screen.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;create 1 at a time&lt;/li&gt;&lt;li&gt;UNCHECK expansion (required)&lt;/li&gt;&lt;li&gt;UNCHECK hardcore (if option is present) (optional, be consistent)&lt;/li&gt;&lt;li&gt;CHECK ladder (optional, be consistent)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;For Nightmare and Hell difficulties, complete the previous difficulties&lt;br /&gt;&lt;ul&gt;&lt;li&gt;(create (N - 1) rushees at at time)&lt;/li&gt;    &lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;hr /&gt;&lt;h3&gt;&lt;a name="andariel_rushees"&gt;CREATING ANDARIEL RUSHEES&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;requires N-1 New rushees&lt;/li&gt;&lt;li&gt;creates N-1 Andariel rushees at a time&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Rush steps:&lt;/h4&gt;&lt;h5&gt;Act 1:&lt;/h5&gt;&lt;ol&gt;&lt;li&gt;Primary rushee (New) creates new game&lt;/li&gt;&lt;li&gt;Rusher enters game&lt;/li&gt;&lt;li&gt;Rusher fills up on town portals&lt;/li&gt;&lt;li&gt;Rusher saves screen shots of maps of paths from Cat2 to Cat3, and from Cat3 to Cat4&lt;/li&gt;&lt;li&gt;Rusher finds Catacombs level 4, and clears first two rooms&lt;/li&gt;&lt;li&gt;Rusher creates town portal to first room of Catacombs 4&lt;/li&gt;&lt;li&gt;Primary rushee waits in upper left corner of first room of Catacombs 4&lt;/li&gt;&lt;li&gt;N-2 additional New rushees enter game and join party&lt;/li&gt;&lt;li&gt;Make sure all rushees are in the game and in the party&lt;/li&gt;&lt;li&gt;Rusher kills Andariel&lt;/li&gt;&lt;li&gt;Primary rushee makes sure he got the quest before returning to town&lt;/li&gt;&lt;li&gt;Rushees each talk to Warriv and go to Act 2&lt;/li&gt;&lt;li&gt;All N-1 rushees in the game have now been converted from "New" to "Andariel"&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;hr /&gt;&lt;h3&gt;CREATING AMULET RUSHEES&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;requires N &lt;a href="http://www.blogger.com/post-edit.g?blogID=20076457&amp;postID=113562871449479664&amp;amp;quickEdit=true#andariel_rushees"&gt;Andariel Rushees&lt;/a&gt;&lt;/li&gt;&lt;li&gt;creates N Amulet Rushees at a time&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;Act 2:&lt;/h5&gt;&lt;ol&gt;&lt;li&gt;Game created by Duriel Mule, or by New or &lt;a href="http://www.blogger.com/post-edit.g?blogID=20076457&amp;postID=113562871449479664&amp;amp;quickEdit=true#andariel_rushees"&gt;Andariel rushee&lt;/a&gt;&lt;/li&gt;&lt;li&gt;One primary Andariel rushee enters the game&lt;/li&gt;&lt;li&gt;Ensure that rusher and rushee both have full town portal tomes&lt;/li&gt;&lt;li&gt;Rusher creates town portal to Lost City [not needed?]&lt;/li&gt;&lt;li&gt;Primary rushee goes to lost city, causing darkness [not needed?]&lt;/li&gt;&lt;li&gt;Rusher saves screen shot of path from Lost City WP to Valley of the snakes&lt;/li&gt;&lt;li&gt;Rusher finds the Claw Viper Temple level 2, and kills all of the monsters there&lt;/li&gt;&lt;li&gt;(Rusher B finds summoner)&lt;/li&gt;&lt;li&gt;Rusher makes a portal to the Claw Viper Temple level 2&lt;/li&gt;&lt;li&gt;Primary rushee enters portal and makes a portal to Claw Viper Temple level 2&lt;/li&gt;&lt;li&gt;All rushers leaves game&lt;/li&gt;&lt;li&gt;N-1 additional Andariel rushees join game and join party&lt;/li&gt;&lt;li&gt;Primary rushee gets viper amulet. Do not leave the Altar Room until the Altar animation finishes. Otherwise the quest might be botched.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If a Duriel Mule needs to be created for this difficulty, save the amulet.&lt;/li&gt;&lt;li&gt;All rushees talk to Drognan&lt;/li&gt;&lt;li&gt;Verify that all rushees have the amulet quest&lt;/li&gt;&lt;li&gt;All N rushees have now become Amulet rushees&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;hr /&gt;&lt;h3&gt;CREATING SUMMONER RUSHEES&lt;br /&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Requires 1 Amulet rushee, and N-2 &lt;a href="http://www.blogger.com/post-edit.g?blogID=20076457&amp;postID=113562871449479664&amp;amp;quickEdit=true#andariel_rushees"&gt;Andariel rushees&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Creates N-1 Summoner rushees&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;Game created by Duriel Mule, or by New, &lt;a href="http://www.blogger.com/post-edit.g?blogID=20076457&amp;postID=113562871449479664&amp;amp;quickEdit=true#andariel_rushees"&gt;Andariel&lt;/a&gt;, or Amulet rushee&lt;/li&gt;&lt;li&gt;Primary Amulet rushee enters game&lt;/li&gt;&lt;li&gt;Rusher enters game&lt;/li&gt;&lt;li&gt;Rusher finds summoner platform in Arcane Sanctuary (but does not kill Summoner yet)&lt;/li&gt;&lt;li&gt;(Rusher B finds Mephisto)&lt;/li&gt;&lt;li&gt;Rusher creates town portal to area near summoner (about 1.5 screens away)&lt;/li&gt;&lt;li&gt;Rushee enters portal, and remains just out of range of the summoner&lt;/li&gt;&lt;li&gt;(Rusher B leaves game)&lt;/li&gt;&lt;li&gt;N-2 additional Andariel rushees enter game and join party&lt;/li&gt;&lt;li&gt;Rusher kills summoner&lt;/li&gt;&lt;li&gt;Rusher creates town portal to Canyon of the Magi&lt;/li&gt;&lt;li&gt;Rusher saves screen shot of Arcane Sanctuary waypoint, with map positioned to show summoner location.&lt;/li&gt;&lt;li&gt;All rushees talk to Cain&lt;/li&gt;&lt;li&gt;All rushees verify that they can take the portal to the Canyon of the Magi waypoint.&lt;/li&gt;&lt;li&gt;All N-1 rushees have now become Summoner rushees&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;hr /&gt;&lt;h3&gt;CREATING DURIEL MULE&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Requires 1 Amulet rushee WITH AMULET, and one &lt;a href="http://www.blogger.com/post-edit.g?blogID=20076457&amp;postID=113562871449479664&amp;amp;quickEdit=true#andariel_rushees"&gt;Andariel rushee&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Creates one Duriel Mule (from Andariel rushee)&lt;/li&gt;&lt;li&gt;One Duriel Mule can be used ever after, for one difficulty level&lt;/li&gt;&lt;li&gt;(Amulet rushee is only needed as a source of the amulet, the staff, and the tomb location)&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;Amulet rushee creates game&lt;/li&gt;&lt;li&gt;Rusher enters game&lt;/li&gt;&lt;li&gt;Make sure both have full town portals&lt;/li&gt;&lt;li&gt;Andariel rushee DOES NOT ENTER GAME YET!&lt;/li&gt;&lt;li&gt;Rusher clears chest area of Maggot Lair level 3 (this is the only time that Maggot Lair must be completed). &lt;/li&gt;&lt;li&gt;Rusher creates town portal to Maggot 3&lt;/li&gt;&lt;li&gt;Amulet rushee gets staff from Maggot 3&lt;/li&gt;&lt;li&gt;Rusher clears walking path from palace in Lut Golein to the summoner&lt;/li&gt;&lt;li&gt;Rusher kills the summoner, but does not touch the book&lt;/li&gt;&lt;li&gt;Andariel rushee enters game (but does not party with the others)&lt;/li&gt;&lt;li&gt;Everyone avoids talking to townspeople and any other quest triggers while this character is in game.&lt;/li&gt;&lt;li&gt;Andariel rushee walks to the summoner area, and touches the book&lt;/li&gt;&lt;li&gt;Andariel rushee enters canyon of the magi and gets waypoint&lt;/li&gt;&lt;li&gt;Note symbol of true tomb&lt;/li&gt;&lt;li&gt;Andariel rushee leaves the game&lt;/li&gt;&lt;li&gt;Rusher clears walking path from canyon to orifice in the true tomb&lt;/li&gt;&lt;li&gt;Andariel rushee enters the game (but does not party with the others)&lt;/li&gt;&lt;li&gt;Everyone avoids talking to townspeople and any other quest triggers while this character is in game.&lt;/li&gt;&lt;li&gt;Andariel rushee walks from the Canyon of the Magi to the orifice&lt;/li&gt;&lt;li&gt;Amulet rushee gives cube, amulet, and staff to Andariel rushee&lt;/li&gt;&lt;li&gt;Andariel rushee transmutes staff&lt;/li&gt;&lt;li&gt;Andariel rushee places staff into orifice&lt;/li&gt;&lt;li&gt;Andariel rushee returns cube to rightful owner&lt;/li&gt;&lt;li&gt;Andariel rushee leaves game&lt;/li&gt;&lt;li&gt;Andariel rushee has become a duriel mule for this difficulty.  Only one is needed per difficulty&lt;/li&gt;&lt;li&gt;Duriel Mule must never get more quests in Act2, just create games and leave as soon as possible&lt;/li&gt;&lt;/ol&gt;&lt;hr /&gt;&lt;h3&gt;DURIEL TO DIABLO INSTRUCTIONS&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Requires 1 duriel mule, 1 Summoner rushee, and N-2 or N-1 &lt;a href="http://www.blogger.com/post-edit.g?blogID=20076457&amp;postID=113562871449479664&amp;amp;quickEdit=true#andariel_rushees"&gt;Andariel rushees&lt;/a&gt;&lt;/li&gt;&lt;li&gt;N-1 rushees complete this difficulty.&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;Act 2:&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;N rushees can complete Act 2 in one pass, compared to N-1 rushees for most other acts.&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;"Duriel Mule" creates new game&lt;/li&gt;&lt;li&gt;Rusher enters game&lt;/li&gt;&lt;li&gt;Duriel Mule leaves game&lt;/li&gt;&lt;li&gt;Summoner rushee enters game, and identifies true tomb symbol. If symbol does not show in the quest log, talk to Cain and visit the Canyon of the Magi waypoint.&lt;/li&gt;&lt;li&gt;If Jerhyn cannot be seen in town, send everyone back to Act 1 temporarily to reset the Act 2 town. Jerhyn must be available in town.&lt;/li&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/944/2000/1600/a2-tomb-symbols_mdaabil.0.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/944/2000/200/a2-tomb-symbols_mdaabil.0.jpg" alt="Arrangement of tomb symbols in the Canyon of the Magi" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;li&gt;Rusher finds Tal Rasha's chamber (bear left in the chamber)&lt;/li&gt;&lt;li&gt;Rusher saves screen shot of path from stairs to orifice&lt;/li&gt;&lt;li&gt;(Rusher B clears area near Travincal temple, but does not kill all council members)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/944/2000/1600/tomb_symbols2.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/944/2000/320/tomb_symbols2.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;li&gt;(Rusher B clears beginning and right side of Durance of Hate level 3)&lt;/li&gt;(bear left in Durance level 2)&lt;br /&gt;&lt;li&gt;(Rusher B creates town portal near stairs in Durance level 3)&lt;/li&gt;&lt;li&gt;(Rusher B clears seals in Chaos Sanctuary)&lt;/li&gt;&lt;li&gt;Summoner rushee waits in orifice room&lt;/li&gt;&lt;li&gt;Rusher kills Duriel&lt;/li&gt;&lt;li&gt;Rusher(s) leave game.&lt;/li&gt;&lt;li&gt;N-1 Andariel rushees enter game and join party.&lt;/li&gt;&lt;li&gt;(Even though the quest log says that you cannot complete the quest, you actually can.)&lt;/li&gt;&lt;li&gt;Summoner rushee walks through chamber and talks to Tyrael.&lt;/li&gt;&lt;li&gt;Each rushee talks to Jerhyn, then Meshif, and goes to Act 3&lt;/li&gt;&lt;li&gt;N Rushees have now completed Act 2&lt;/li&gt;&lt;li&gt;If this is HELL difficulty, STOP here, and go to EXPANSION instructions&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h5&gt;Act 3:&lt;/h5&gt;&lt;ol&gt;&lt;li&gt;Rusher clears area near Blackened temple, but does not kill Council members&lt;/li&gt;&lt;li&gt;Primary rushee stands near Blackened temple&lt;/li&gt;&lt;li&gt;Make sure N-1 rushees are in the game and in the party&lt;/li&gt;&lt;li&gt;Rusher kills high council&lt;/li&gt;&lt;li&gt;All Rushees pick up their Horadric Cubes near the dead council, if they need one.&lt;/li&gt;&lt;li&gt;All Rushees talk to Cain&lt;/li&gt;&lt;li&gt;Rusher saves screen shot of path from Durance 2 WP to Durance 3&lt;/li&gt;&lt;li&gt;Primary rushee waits by stairs in Durance 3&lt;/li&gt;&lt;li&gt;Make sure N-1 rushees are in the game and in the party&lt;/li&gt;&lt;li&gt;Rusher A kills Mephisto&lt;/li&gt;&lt;li&gt;Rusher A creates town portal near red portal&lt;/li&gt;&lt;li&gt;Each rushee goes to Act 4 through red portal&lt;/li&gt;&lt;/ol&gt;&lt;h5&gt;Act 4:&lt;/h5&gt;&lt;ol&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/944/2000/1600/hot10.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/944/2000/200/hot10.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;li&gt;Rushers clear all seals in Chaos Sanctuary (except one cold one)&lt;/li&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/944/2000/1600/RusheeNook.0.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/944/2000/200/RusheeNook.0.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;li&gt;Primary rushee enters the safe nook&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Make sure N-1 rushees are in the game and in the party&lt;/li&gt;&lt;li&gt;Rusher A pops the final seal and quickly returns to the Diablo area&lt;/li&gt;&lt;li&gt;Rusher A kills Diablo, avoiding wandering too far from spawning spot.&lt;/li&gt;&lt;li&gt;All rushees move to next difficulty, where they are now "NEW"&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;hr /&gt;&lt;h3&gt;EXPANSION INSTRUCTIONS&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;After completing Hell Act 2 and entering Hell Act 3 in Classic mode, convert rushees to Expansion&lt;/li&gt;&lt;li&gt;Bring the Expansion rushees from Act 3 Hell to the begining of Act 4 Hell, using same rushing methods described for Classic&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;EXPANSION HELLFORGE&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;Requires one expansion rushee in Act 4 Hell difficulty&lt;/li&gt;&lt;li&gt;Make one game per rushee&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;Rushee creates game&lt;/li&gt;&lt;li&gt;Rusher kills monsters in region of hellforge&lt;/li&gt;&lt;li&gt;Rusher creates portal to hellforge&lt;/li&gt;&lt;li&gt;Make sure rushee is not partied with anyone who needs the hellforge quest.&lt;/li&gt;&lt;li&gt;Rushee collects hammer and smashes soulstone&lt;/li&gt;&lt;li&gt;Store runes and gems in a safe place&lt;/li&gt;&lt;li&gt;Complete hellforge quest in both Hell and Nightmare difficulty&lt;/li&gt;&lt;li&gt;Complete Shenk/socket quest in both normal and Nightmare difficulty&lt;/li&gt;&lt;li&gt;Save socket quests for a special occasion&lt;/li&gt;&lt;/ol&gt;Possible hellforge runes by difficulty.  There is an equal chance (1/11) of each listed rune dropping at each hellforge quest.&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;Normal: El, Eld, Tir, Nef, Eth, Ith, Tal, Ral, Ort, Thul, Amn&lt;br /&gt;&lt;/li&gt;   &lt;li&gt;Nightmare: Sol, Shael, Dol, Hel, Io, Lum, Ko, Fal, Lem, Pul, Um&lt;br /&gt;&lt;/li&gt;   &lt;li&gt;Hell: Hel, Io, Lum, Ko, Fal, Lem, Pul, Um, Mal, Ist, Gul&lt;/li&gt; &lt;/ul&gt;Runes that cannot be obtained from hellforge rune drop: Vex, Ohm, Lo, Sur, Ber, Jah, Cham, Zod. It would take 256 Gul runes (and some gems) to cube up one Zod rune.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-113562871449479664?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/113562871449479664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=113562871449479664' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113562871449479664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113562871449479664'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2005/12/rune-rushing-in-diablo-ii-lord-of.html' title='Rune rushing in Diablo II Lord of Destruction'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-113546468988250520</id><published>2005-12-24T14:51:00.000-08:00</published><updated>2005-12-27T12:46:27.113-08:00</updated><title type='text'>Raxco t-shirt charlatanism</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/944/2000/1600/kloon.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 207px; height: 198px;" src="http://photos1.blogger.com/blogger/944/2000/320/kloon.jpg" alt="" border="0" /&gt;&lt;/a&gt;This rant is reawakened from the early 1990s. Back in about 1991 one of my responsibilities was the maintanance of some &lt;a href="http://en.wikipedia.org/wiki/Digital_Equipment_Corporation"&gt;Digital Equipment Corporation&lt;/a&gt; VAX workstations, running the operating system VMS. One fringe benefit of this activity was a free subscription to a publication called DEC Professional. One frequent advertiser in DEC Professional was a company called &lt;a href="http://www.raxco.com/"&gt;Raxco&lt;/a&gt;. &lt;a href="http://www.raxco.com/"&gt;Raxco&lt;/a&gt; placed one ad that they later regretted. The ad copy proclaimed that simply by filling out and returning a card requesting more information about some of their products, you could get a free t-shirt. This t-shirt featured a cartoon by &lt;a href="http://www.geocities.com/donmartinweb/"&gt;Don Martin&lt;/a&gt;, best know for his work at &lt;a href="http://www.dccomics.com/mad/"&gt;Mad Magazine&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The cartoon is captioned "Fragmentation happens", and features a Don Martin version of a computer engineer with computer parts flying about with sound effects like "Kloon", "Ping", "PA-Tween" and "Sproing".&lt;br /&gt;&lt;br /&gt;I filled out the card and waited for my t-shirt. This was now about fourteen years ago. One of &lt;a href="http://www.raxco.com/"&gt;Raxco&lt;/a&gt;'s representatives informed me that the response to the ad had been larger than anticipated, so I might need to wait longer before getting my shirt. I have now waited fourteen years.&lt;br /&gt;&lt;br /&gt;Later I got another business reply card with which I could request product information from &lt;a href="http://www.raxco.com/"&gt;Raxco&lt;/a&gt;. This time, no shirt was offered. But there was some additional white-space below the check box options on the card. Being careful not to mark any of the preprinted check boxes, I wrote in a new one of my own. It simply said "Where is my t-shirt, you deceitful charlatans?" I placed a large check mark in the box I had created next to this question and dropped the card in the mail. All I received in response to this was some product information that I had not asked for.&lt;br /&gt;&lt;br /&gt;Why am I bringing this up now? My loving wife found an image of the aforementioned t-shirt and made me a t-shirt using special iron-on paper for inkjet printers. Is this copyright infringement? Perhaps. I would so love to have someone from &lt;a href="http://www.raxco.com/"&gt;Raxco&lt;/a&gt; try to take the moral high ground on this one. They still owe me a t-shirt. After fourteen years, the interest should run to at least two t-shirts by now.&lt;br /&gt;&lt;br /&gt;Where is my shirt &lt;a href="http://www.raxco.com/"&gt;Raxco&lt;/a&gt;?  I am still waiting.  Jerks.&lt;br /&gt;&lt;br /&gt;And thank you honey for the beautiful t-shirt.  I have wanted something like this for so long.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-113546468988250520?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/113546468988250520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=113546468988250520' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113546468988250520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113546468988250520'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2005/12/raxco-t-shirt-charlatanism.html' title='Raxco t-shirt charlatanism'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076457.post-113519912519539669</id><published>2005-12-21T12:59:00.000-08:00</published><updated>2005-12-21T13:27:14.096-08:00</updated><title type='text'>Slip up at Mountain View Optometry</title><content type='html'>Back in mid November I got a prescription for new glasses at &lt;a href="http://www.mvo.com/index.asp"&gt;Mountain View Optometry&lt;/a&gt;. That was five weeks ago and I was promised that they would call when the glasses were ready. I finally got too impatient and called them today. Apparently their computer indicates that some useless and apparently anonymous retard contacted me by phone two weeks ago. Their computer is a liar. Useless retard. There I said it again.&lt;br /&gt;&lt;br /&gt;To be fair, my optometrist, Dr. Bell, is excellent. The problem is that they take your payment before they have delivered their product. Many organizations that do this have neither concern nor accountability for the customer experience after the cash register has rung its chime. I am left with a very nasty feeling. The feeling is compounded by an unrelated blunder at &lt;a href="http://fenderscollision.com/mpc/docs/Site/Home.html"&gt;Fenders Collision Center&lt;/a&gt; that I had this morning.&lt;br /&gt;&lt;br /&gt;Rant rant rant rant rant rant.  There, that does feel better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076457-113519912519539669?l=biospud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biospud.blogspot.com/feeds/113519912519539669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076457&amp;postID=113519912519539669' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113519912519539669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076457/posts/default/113519912519539669'/><link rel='alternate' type='text/html' href='http://biospud.blogspot.com/2005/12/slip-up-at-mountain-view-optometry.html' title='Slip up at Mountain View Optometry'/><author><name>Biospud</name><uri>http://www.blogger.com/profile/13304428707742568072</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
