Archive for October, 2007

Fenisoft Scanline Renderer

Wednesday, October 31st, 2007

This is one of those projects that seems much cooler to the maker than the observer. Here I have a biplane. What makes it special is that it was rendered using Carson Fenimore’s 3D renderer. If you have never heard of it, that’s ok – that probably won’t change, even after I finalize things with Pixar. It will probably remain anonymous, just as my stock and pay on the deal will be kept secret, leaving me superficially the same, as always, a humble man unwilling to brag.

This renderer was implemented entirely in c++ under Mac OS X and makes use of no external libraries, other than the STL for data containers and OpenGL for drawing 2D points (really 3D points with a Z value of 0). This means this renderer does the following:

  • Polygon rasterization – quads and triangles
  • Z Buffering – using patented hidden secret technology
  • Geometric transformations (scale, translate, rotate)
  • Arbitrary view (camera can be anywhere; specify view angle along with up, look at, and look from vectors
  • Phong shading

The lesson I learned from this is: Don’t be deceived: simple things are often not easy to do. This was not easy to implement – there’s no “cookie-cutter” way to do your own renderer, especially if you have a weak background in linear algebra.

Biplane – in all its magesty
Biplane 1

Biplane 2

Apple – Notice the Shiny spot thanks to Mr. Phong
Apple

Bike
Bike

General – Very large and complex model
General

Carson Recipe: Teriyaki Potato

Saturday, October 20th, 2007

This is a new classic in my book: Combine stir fried chicken on a well boiled set of potatoes. Scrum-didily-upmtious!

Potato Teryaki

The Incredible Hough

Friday, October 19th, 2007

A the Hough, now there’s an amazingly simple method for finding circles, lines, and other shapes. Lest this sounds too narrow an application, consider the wild possibility of finding a pool ball. The hough can find these in almost linear time. Amazing!

The idea is this: build an “accumulator”, which is really a voting array for parameters describing the object you wish to find. In the case of circles, you could have one accumulator for each approximate radius. Your task is then to go through the source image and find features which “might” be parts of a pool ball; in this case, edges might work. For each point on an edge, we “vote” in a radius around the point. If we do this for all points around a ball, the locus of the ball will have a high number of votes.

Here’s an example image with some pictures of the accumulator for circles of radius 32 and 48.

Source Image:
Circles

Paramater Space at radius 48
Hough48

Paramater Space at radius 32
Hough32

Shown below, is the final result of my Hough Transform for radius 32. Note that it missed one, but had no false positives. Not bad, especially considering I use a general approach that isn’t “hand tuned” to this image.
Huff32Labeled

Sobel

Monday, October 15th, 2007

This is a classic blunder – posting a hideous picture simply because it was cool to make. This is an image I generated by running a Sobel kernel to calculate the gradient of an image. I then rendered the gradient direction by mapping angles between [-pi, pi] to [0, 255].

Sobel

Servo Tips

Friday, October 12th, 2007

The Lion is scratching in smooth motions now, thanks to a servo from Expert Electronics (supplied by the local HobbyTown) and a Rabbit 4000. A few items were learned in the process of trying to get this to work with a Rabbit 4000 processor.

First, an overview of the rabbit. The Rabbit 4100 I own has four PWM channels. Frequency is set on the whole PWM subsystem (not on a per-channel basis) through the pwm_init(int hertz) call. Out of the box, the lowest frequency the rabbit will go on the PWM system is 112Hz. There is also a pwm_set(int channel, int duty, int options) function that lets you set the duty cycle and options for a particular channel.

Now a brief servo overview. From seeing all the attention given to servos I had yet to find what made them so special. The magic of the servo, it turns out, is two fold: 1) they have a great amount of power output for their size (thanks to gearing), and 2) they can be positioned precisely almost without effort from the user. The positioning magic is handeled by some circuitry within the servo. Typically servos make use of a potentiometer and hence have a fixed range – typically 180 degrees. The user selects the servo position by sending a pulse, where the width of the pulse varies from 1ms to 2ms. Most sites I found said to allow for at least 20ms between pulses.

Ok, now to mix the two: servos and pwm controllers. Given that servos want a pulse from 1 to 2 ms, we can calculate the maximum frequency as 1/period = 1/.002 = 500Hz. Assuming we use this frequency, we now need to vary our duty cycle between 100 and 50%. Then, the trick comes in: how to wait after a pulse. Turns out the rabbit has a cycle suppression option as part of the pwm_set function. With this, one can supress 7/8, 3/4, or 1/2 cycles. Since we want about 20 ms, it makes since to use the highest setting – 7/8 – yielding 14 ms of dead time between cycles.

Turns out this is about all you need to know. Just make sure, that if you are using two separate supplies (one for rabbit, one for servo) that their grounds are tied together. Also, we chose initially to operate at 112Hz… then we also decided to wait 7/8 cycles. The result is that our line shook like a crack addict – really jerky movement. Why? A helpful site told us that if we let the servo wait more than, say, 45 or 50 ms, the control circuit in it would go to sleep. In other words, the off time between cycles should be from 10 ms to about 30 ms – within those bounds. Because of our frequency, we were waiting 50ms. When we switched the suppression to one in two, everything worked smooth as silk! Going to a higher frequency should allow for finer grained control, since the duty cycle field is an int going from 0 to 1024 (100%).

Building of a Shield

Tuesday, October 9th, 2007

I live in a house with nine to ten other guys and we all get along. We just finished an apartment photo and shortly thereafter contemplated a new name for the house. This was not easy. In the absence of a unanimous decision, it was suggested that we go with the “Lion House.” Finding this not altogether too repugnant, we all agreed. We then contemplated what insignia might designate our house thusly, and one member decided a gaudy lion on a shield. I was contracted to find a way to project an image of a lion onto some wood and then extract the lion using a cutting implement. I agreed, volunteering to additionally mechanize the lions arm movements; in other words, I agreed on the condition that I could embellish.

Step one is shown below, with the lion cut out of a piece of board using my newly acquired pawn-shop jigsaw. What a tool! Rowr!

Lion Silhouette

Uniform Cost Search

Friday, October 5th, 2007

Interesting thing about Uniform cost search.  This simply “expands” nodes from the fringe list by selecting the one with the least cost from root.  This works, because as nodes are added, they are sorted.  As you progress towards one spot, your total path cost keeps increasing.  The fringe nodes added around this high-cost path may soon sink to the bottom of your priority queue, exposing nodes that may have been from near the start position.  Thus, you cannot just shoot down a dead end because it seemed initially to be a shorter path – eventually the start nodes will return with a vengence!

One thing I learned is that the c++ STL priority_queue keeps the biggest thing on top.  So, since we are interested in the “smallest” thing, we must define some kind of comparator, such as

struct less_NodePtr : public binary_function<NodePtr, NodePtr, bool>
{
bool operator()(NodePtr p1, NodePtr p2)
{
return p1->costFromRoot > p2->costFromRoot;
}
};

Where the comparison returns false if the second node is greater than the 1st – reverse of standard less-than logic.

priority_queue Visual Studio 2005

Monday, October 1st, 2007

Weirdest error I have experienced of late, compliments (of course) to Visual Studio 2005. The error given is:

error C2143: syntax error : missing ‘;’ before ‘<’

This error is generated because of a perfectly good typedef:

typedef priority_queue<NodePtr, NodePtrList, less_NodePtr> PriorityQueue;

Alone, in a separate project, this line compiles as it should. So, what could it be? It smells like something project-specific.

And following your nose, you would be right: the project included a “Queue.h” header in another part of the source. Nowhere is the contents of this file referenced. So I removed it and…well, all is well.