It seems like blogger does not support code snippets, and that its not as easy as I thought it will be to find some converters that will be able to convert my code into nice, colorful HTML syntax I can paste.
Time to write something that does just that, I guess.
Will probably build something generic, and base on the GOLD parser. It have good base code generators for various languages, including C#, so it seems like a good place to start.
Sunday, March 29, 2009
Creating customizable WPF drop-down menus (1)
In this series of articles I'll explain the process of creating a drop-down menu that can be customized using drag-and-drop.
Enough preface, now on to the job!
Fortunately, WPF has a built-in Drag-and-Drop assistance class, that does the hard parts for us. All we need to do is to detect when we want to begin dragging, then pass it on to the Drag-and-Drop helper. Oh, and we also need to handle the drop :-)
Related Posts:
Enough preface, now on to the job!
Step 1: A simple drop-down menu
A simple drop down menu can be built in WPF using the Menu and MenuItem classes. This can be done is XAML of course, and would look like this:<Menu> <MenuItem Header = "MenuItem1"> <MenuItem Header = "MenuItem1.1"/> <MenuItem Header = "MenuItem1.2"/> <Separator Margin = "0,0,0,0" Height = "Auto"/> <MenuItem Header = "MenuItem1.3"> <MenuItem Header = "MenuItem1.3.1"/> </MenuItem> <MenuItem Header = "MenuItem1.4"> <MenuItem Header = "MenuItem1.4.1"/> </MenuItem> </MenuItem> <MenuItem Header = "MenuItem2"/> <MenuItem Header = "MenuItem3" HorizontalAlignment = "Right"> <MenuItem Header = "MenuItem3.1"/> <MenuItem Header = "MenuItem3.2"/> <Separator Margin = "0,0,0,0"/> <MenuItem Header = "MenuItem3.3"> <MenuItem Header = "MenuItem3.3.1"/> </MenuItem> </MenuItem> </Menu>This menu, however, cannot be customized using Drag-and-Drop by the end-user at runtime. In order to do that, we need to implement a dragging mechanism.
Fortunately, WPF has a built-in Drag-and-Drop assistance class, that does the hard parts for us. All we need to do is to detect when we want to begin dragging, then pass it on to the Drag-and-Drop helper. Oh, and we also need to handle the drop :-)
Important Note: |
---|
The MenuItem class is limited in its behavior. In order to prepare to some of the more advanced steps, I'll need to inherit MenuItem to my own class, that will allow me to do the needed operations.I'll call this class DraggableMenuItem , and let it implement internally everything the draggable menu items does. |
Thursday, March 26, 2009
Floating Point
A friend asked me today why a cast from double to int in C# would take a whole microsecond.
To answer that, we have to understand how cast between those two primitive types work, and how each of them is represented in memory.
So, how an integer is represented in memory? Quite straight forwards: simple run of bits (8, 16, 32 or 64, depending on the actual type - byte, short, int and long respectively)
The single and double data types are more complex. These are floating point types, and as such, they represent a number which decimal point isn't in a fixed position, but may change according to the represented number.
This leads to a situation where we can represent either really small and very accurate numbers, or very large and inaccurate numbers.
How is this done? By separating the given memory to 3: one bit for sign, 11 bits for exponent, and the rest 52 bits for the mantissa (the significant value, representing a fraction or an integer depending on the interpretation of the exponent).
This structure also allows to define values that are not numbers, such as NaNs (Not a Number, which is returned when you try to divide a double by a zero double), Infinity (positive and negative), and denormal numbers.
As I mentioned before, the integer data type simply store bits, straight forwards. So, simply renaming the type won't work. A computation need to be performed to resolve the represented value from the floating point number, then round the result to the nearest whole number. In addition, several tests need to be performed to handle NaNs, denormal numbers and infinities correctly. All of those operations take quite some time, so no wonder this simple, so common cast, takes a whole microsecond.
So if you have a tidious, tight loop that performs thousands of double-to-int casts, try to avoid casting. It might help improve performance.
To answer that, we have to understand how cast between those two primitive types work, and how each of them is represented in memory.
So, how an integer is represented in memory? Quite straight forwards: simple run of bits (8, 16, 32 or 64, depending on the actual type - byte, short, int and long respectively)
The single and double data types are more complex. These are floating point types, and as such, they represent a number which decimal point isn't in a fixed position, but may change according to the represented number.
This leads to a situation where we can represent either really small and very accurate numbers, or very large and inaccurate numbers.
How is this done? By separating the given memory to 3: one bit for sign, 11 bits for exponent, and the rest 52 bits for the mantissa (the significant value, representing a fraction or an integer depending on the interpretation of the exponent).
This structure also allows to define values that are not numbers, such as NaNs (Not a Number, which is returned when you try to divide a double by a zero double), Infinity (positive and negative), and denormal numbers.
As I mentioned before, the integer data type simply store bits, straight forwards. So, simply renaming the type won't work. A computation need to be performed to resolve the represented value from the floating point number, then round the result to the nearest whole number. In addition, several tests need to be performed to handle NaNs, denormal numbers and infinities correctly. All of those operations take quite some time, so no wonder this simple, so common cast, takes a whole microsecond.
So if you have a tidious, tight loop that performs thousands of double-to-int casts, try to avoid casting. It might help improve performance.
Wednesday, March 25, 2009
Grid Computing and Charity
I bought my quad-core computer about a year ago, since I planned to use it for massive programming and/or editing (video/image) work.
However, I started to work in a 2 hours distance from home (at least with public transportation), so for a long time the computer was simply shut-down, collecting dust.
Until I decided that if I spent so much money to buy such a strong computer, at least let it do something useful. I didn't have anything useful for it, so I decided to find something online.
I remembered SETI@Home was a good way to share my computer free cycles to do something useful, but Searching for Extra Terrestrial Intelligence really didn't sound like something worth investing in.
So I looked for similar programs that I can relate to, and found World Community Grid, which is a project dealing with finding cures for cancer and AIDS, helping solve hunger problems by finding more nutritious foods, finding cleaner energy sources, etc.
Another thing I have found was, that the entire grid computing for science and personal usage subject was reformed, and the main computation management client software used is BOINC.
With BOINC you can connect to your favorite grid computing project and share your computer resources. BOINC will download work parts to run on your computer, then upload the results when they are ready. The project server than add them to one large computational task until a result is achieved. Some servers grant points for time spent on computing and results that are returned, making things a bit more competitive.
Anyone can use BOINC to perform very long computations. Scientists can apply to volunteer computing, while companies can set up a BOINC server to run grid computing within the organization.
I, anyway, is using my BOINC client at home and at work, giving all those unused cycles to help solve those important issues. The next time I'll read in the newspaper that scientists has found a new cure, and used grid computing technology, I'll know I gave my share :-)
However, I started to work in a 2 hours distance from home (at least with public transportation), so for a long time the computer was simply shut-down, collecting dust.
Until I decided that if I spent so much money to buy such a strong computer, at least let it do something useful. I didn't have anything useful for it, so I decided to find something online.
I remembered SETI@Home was a good way to share my computer free cycles to do something useful, but Searching for Extra Terrestrial Intelligence really didn't sound like something worth investing in.
So I looked for similar programs that I can relate to, and found World Community Grid, which is a project dealing with finding cures for cancer and AIDS, helping solve hunger problems by finding more nutritious foods, finding cleaner energy sources, etc.
Another thing I have found was, that the entire grid computing for science and personal usage subject was reformed, and the main computation management client software used is BOINC.
With BOINC you can connect to your favorite grid computing project and share your computer resources. BOINC will download work parts to run on your computer, then upload the results when they are ready. The project server than add them to one large computational task until a result is achieved. Some servers grant points for time spent on computing and results that are returned, making things a bit more competitive.
Anyone can use BOINC to perform very long computations. Scientists can apply to volunteer computing, while companies can set up a BOINC server to run grid computing within the organization.
I, anyway, is using my BOINC client at home and at work, giving all those unused cycles to help solve those important issues. The next time I'll read in the newspaper that scientists has found a new cure, and used grid computing technology, I'll know I gave my share :-)
Milk
In the last couple of days we were out of milk at home. I forgot to buy some last time I went shopping for groceries, and the milk we still had left was running out.
This of course caused a severe inconvenience as I had to choose between having a bowl of cereals or saving some milk for tomorrow morning's coffee.
Since dinners for me are usually based on cereals as I am usually too tired (lazy?) to make something decent to eat (like a fried egg with some toasted bread and some salad), having to choose between cereals and coffee is really inconvenient. Problem gets worst when I don't have to choose anymore when there is not enough milk for a bowl of cereals :-S
So, the conclusion is not to forget the milk next time. And always buy enough. Not sure it's good for me, but hey, it makes my life easier :-)
This of course caused a severe inconvenience as I had to choose between having a bowl of cereals or saving some milk for tomorrow morning's coffee.
Since dinners for me are usually based on cereals as I am usually too tired (lazy?) to make something decent to eat (like a fried egg with some toasted bread and some salad), having to choose between cereals and coffee is really inconvenient. Problem gets worst when I don't have to choose anymore when there is not enough milk for a bowl of cereals :-S
So, the conclusion is not to forget the milk next time. And always buy enough. Not sure it's good for me, but hey, it makes my life easier :-)
Tuesday, March 24, 2009
Broken Glasses
My glasses got broken the other day, while I was cleaning them.
The part that holds the little plastic thingies that holds the glasses on the nose got detached.
Luckily I have a relatively low glasses number, so I can see fine without them for short distance (especially the screen), but driving is more problematic.
Anyways, I made a quick temporary fix using sellotape until I get them fixed or replaced.
The blurry thing on the bridge between the lenses is the sellotape.
The part that holds the little plastic thingies that holds the glasses on the nose got detached.
Luckily I have a relatively low glasses number, so I can see fine without them for short distance (especially the screen), but driving is more problematic.
Anyways, I made a quick temporary fix using sellotape until I get them fixed or replaced.
The blurry thing on the bridge between the lenses is the sellotape.
Multitouch Tables
I've been messing around on and off in the past year or so, learning about multipoint input techniques, and trying to implement some in .Net.
Aspired by Microsoft Surface and NUI Group, I tried to build my own test-bed. So far, the success is, to say the least, limited :-)
It is made of a carton box used to accommodate my vacuum cleaner, a 5mm clear perspex board I bought for too much money (these things really are expensive), a web camera I once bought (I tend to buy a new one for experiments every few months or so, usually in the local supermarket) and a 48 LEDs infrared projector I bought on eBay.
Problem was I could never set it up right, although I had some success doing fiducial recognition and tracking completely in .Net. The only problem was performance, mainly of the filters: I tired to implement a Constant Time Median Filter, but even though this is the most efficient method to implement Median Filter, it still runs too slow (about 1 FPS), even on my computer (Intel QuadCore Q6600).
Then I tried to change the implementation to use Mono SIMD, but the camera code (COM) didn't work and the program didn't run, and then I put it aside.
Funny thing is, that the thing I really want to do is to develop controls and infrastructure for such a device, but I don't want not to be able to experiment with it myself, so I just don't get there.
I did write some demos to see I can get the basics to work (two markers that I can drag around with the mouse, representing two fingers), and using touchlib I also managed to play around with some more complex techniques, and finally got a nice picture scaling and rotating on screen. But setting up the environment was such a pain, plus I wanted to see if I can do it all purely in .Net.
To sum things up - I do think it is possible, but it will require some more work. I would either get the camera working in mono one day, or maybe microsoft will release a service pack for .net that implements SIMD, I'll learn to use my GPU for that task (CUDA vision, perhaps?), or try to do all that magic directly on Linux.
Subscribe to:
Posts (Atom)