Tuesday 11 February 2014

Irregular shapes and Bezier curves


Following on from the post at the weekend on Weird Faces I had a look at generating some hand-drawn shapes myself using Silverlight. First I had a look at Paper.js and noticed that there was some advice on hand-drawn rendering from the earlier Scriptographer references hereHåkan Lundgren put together some code to split a path into a number of segments. These can then be nudged around randomly and then smoothed to create a hand-drawn look like below:

Håkan advises that the sprinkles could be generated with a Halton Sequence-function. I need to take a look into that.







I had a bit of noodling around taking lines, breaking them apart into segments and then adjusting the points on the sequence, which was quite fun:



Random r = new Random();

PointCollection GetLine(Point p1, Point p2)
{
    int N = 10;

    double l = Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + 
               Math.Pow(p1.Y - p2.Y, 2));
 
    double dx = (p2.X - p1.X) / (N - 1);
    double dy = (p2.Y - p1.Y) / (N - 1);

    PointCollection points = new PointCollection();

    double a = 15;

    for (int i = 0; i < N; i++)
    {
        Point p = new Point();
        p.X = p1.X + (dx * i);
        p.Y = p1.Y + (dy * i);

        // wobble, not the ends
        if (i > 0 && i < N-1)
        {
            p.X += (r.NextDouble() * a) - (a / 2);
            p.Y += (r.NextDouble() * a) - (a / 2);
        }
        points.Add(p);
    }

    return points;
}

void DrawLine(PointCollection points, Color c)
{
    for (int i = 0; i < points.Count - 1; i++)
    {
        DrawLine(points[i], points[i + 1], c);
    }
}


This gave me some nice, but a bit jaggedy lines.

I then thought I could do the same with a circle, so had a go at that:



PointCollection GetCircle(Point p1, double rad)
{
    int N = 15;

    PointCollection points = new PointCollection();

    Point p0 = new Point();
    p0.X = (rad * Math.Cos(2 * Math.PI * N / (N + 1))) + p1.X;
    p0.Y = (rad * Math.Sin(2 * Math.PI * N / (N + 1))) + p1.Y;

    double a = 20;

    points.Add(p0);

    for (int i = 0; i < N; i++)
    {
        Point p = new Point();
        p.X = (rad * Math.Cos(2 * Math.PI * i / (N + 1))) + p1.X;
        p.Y = (rad * Math.Sin(2 * Math.PI * i / (N + 1))) + p1.Y;

        // wobble
        p.X += (r.NextDouble() * a) - (a / 2);
        p.Y += (r.NextDouble() * a) - (a / 2);
                
        points.Add(p);
    }

    points.Add(p0);

    return points;
}

Again, pretty neat and made some nice shapes, but I had the hunkering for some more and some smoothness, so dug into Bezier lines. When I get a chance this will be ideal for a little Gem, for now, I dug up some excellent posts:

  • This one goes through the basic WPF shapes as a good summary that can be easily referenced.
  • This one for a great run through of creating smooth curves.
I had a bit of play with the second article using the final example of a smooth curve, which I modified to create some bumpy circles which I then displayed in a pattern.


private PointCollection GetBumpyCircle(Point p)
{
    double dA = 8;
    double dR = 28;      // Radius of inside circle. 
    int iDegrees = 10;    // Step degrees.
    double dAngle;        // Step radians.

    // Total number of points (must be even).
    int iN = 360 / iDegrees;

    // Get points.
    double X = 0.0;
    double Y = 0.0;
    PointCollection pointsCurve = new PointCollection();
            
    for (int i = 0; i < 360; i += iDegrees)
    {
        dAngle = Math.PI * i / 180.0;
        // On outside circle.
        X = dR * Math.Cos(dAngle) + ((r.NextDouble() - 0.5) * dA) + p.X;
        Y = dR * Math.Sin(dAngle) + ((r.NextDouble() - 0.5) * dA) + p.Y;
        pointsCurve.Add(new Point(X, Y));
    }

    return pointsCurve;
}

The result is some fun little irregular shapes:

Certainly the basis for some more fun later on.... the Bezier article is definately worth a little more investigation for some future ideas.

Monday 10 February 2014

Gem #3: Background Workers

Last one for tonight. It goes sort of hand-in-hand with the XML resources. I wanted to show in the application some background algorithmic processing as I was working through some of the data in the Resource files (see Gem#2). The thing for this is a background worker thread:

Code examples everywhere, but again, as a placeholder for me:


BackgroundWorker bw = new BackgroundWorker();

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    InitializeComponent();

    bw.WorkerReportsProgress = true;
    bw.WorkerSupportsCancellation = true;
    bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    bw.RunWorkerCompleted += new 
           RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

    bw.RunWorkerAsync();
}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    
    // do the time consuming operation 
    
}

using System.ComponentModel; needs to be included;

Now, the usual way to report progress in the time-consuming process is to use the following little snippet:


// in the time-consuming process, 
// where percent is a double with percentage complete
worker.ReportProgress(percent);


private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
}

Which is all well and good if you're just showing a progress bar or similar, but in my case I wanted to show an update of the components that had been processed, which was a text message. As the long-running thread is not on the GUI thread none of the GUI components can be directly touched as they go cross-thread so some alternatives are needed. The usual Silverlight route out of this is to use the dispatcher which works quite nicely:


// in the time-consuming process
this.Dispatcher.BeginInvoke(delegate()
{
    // do the GUI stuff in here
}
// back the time-consuming worker thread

And for the sake of completeness the usual way to enable cancellation of this thread is as follows:


// in the time-consuming process
// periodically check if the thread has been
// cancelled and break out, seeting e.Cancel
if ((worker.CancellationPending == true))
{
    e.Cancel = true;
}

this would be signalled in the GUI to set bw.CancellationPending = true. and the cancellation status would be passed through to the completion handler.

// and this can be used in the completed 
// handler
if ((e.Cancelled == true))
{
    this.tbProgress.Text = "Canceled!";
}
    e.Cancel = true;
}

Details of this and links to the rest of the BackgroundWorker methods are here.


Gem #2: Getting Silverlight Resources

Posting another little reminder... I had getting resource loading cracked for some images and graphics that I was using in one application with the following little set of code lines:

Image image = new Image();
string[] tmp = Assembly.GetExecutingAssembly().FullName.Split(',');
string path = "/" + tmp[0] + ";component/Graphics/";

image.Source = new BitmapImage(new Uri(path + imagefile, UriKind.Relative));

To access Assembly, System.Reflection; needs to be included.

The app had a set of images (png and jpg files) in a folder Graphics. What I had forgotten and struggled around with for 15mins was that the properties of the file need to have the Build Action set to Resource (see below).






This is all good. However recently I also wanted to use this to bring some XML information into the application. How to do that? After some fun, this seemed to work nicely:


string[] tmp = Assembly.GetExecutingAssembly().FullName.Split(',');
string path = "/" + tmp[0] + ";component/Data/";

Uri u = new Uri(path + "data.xml", UriKind.Relative);
Stream s = Application.GetResourceStream(u).Stream;

XDocument xdoc = XDocument.Load(s);

Remember you'll need to have using System.Xml.Linq; for this to work, which also needs to be added as a reference. In this case the XML files were in the folder Data.





Silverlight Text Language Identification

I thought this might be interesting to post. After the simple "Hello World" Silverlight example a week or so ago I wanted to see if I could start to post up some of the interesting little apps I'd put together over the past few years. This one came to mind. I'll post a couple of reminder notes as gems for the little bits I'd fogotten about getting this working.

Here's a screenshot with some results (the app to play with is at the end of the article). I'm afraid I can't post source for this one, but if you're interested drop me a note and I can explain how I went about it and some more details.


You can see a ranked list of guesstimates of what the algorithm thinks are the most likely languages. In this case German.

I can't quite remember how I stumbled upon this, but I've always had an interest in languages and had a need to be able to distinguish between a set of textual items to find out what the main body of the text is. I'll not go into specific details, but mostly this was focused on transcription of spoken words, so the algorithm probably isn't so good at literary or other specific writing.

The algorithm is based on statistical frequency analysis. I got a leg-up initially from some helpful corpus (I can't remember which, but if it comes to mind I'll update with a reference and due credit). Eventually I processed my own set of word frequencies which I've used here.

The app is a simple version of what I finally used for testing. This never actually got used in anger as things moved on. However, I had tested it with a test corpus of over 40,000 items, it's pretty speedy, and had an accuracy of just over 95%. It did also identify a number of mis-categorised items in the test corpus I used :-)



The languages that were hardest to discrimintate were unsurprisingly the languages with the closest similarity in linguistic terms - so Croatian (HRV) and Serbian (SRP) and Russian (RUS) and Ukranian (UKR). However, to my surprise, it could actually do a reasonable job of distinguishing between Portuguese and Brazilian Portuguese. I guess this might have been more likely from the test corpus, word frequency choices and focus on spoken materials.

Anyway, it's a fun little tool, play away and see how well it does spotting languages. The sample I've put online has the following 34 languages:

Albanian (ALB), Portuguese (Brazilian) (BPT), Bulgarian (BUL), Chinese (CHI), Czech (CZE), Danish (DAN), Dutch (DUT), English (ENG), Estonian (EST), Finnish (FIN), French (FRE), German (GER), Greek (GRE), Hebrew (HEB), Croatian (HRV), Hungarian (HUN), Icelandic (ICE), Indonesian (IND), Italian (ITA), Lithuanian (LIT),  Latvian (LAT), Macedonian (MAC), Norwegian (NOR), Persian (PER), Polish (POL), Portuguese (POR), Romanian (RUM), Russian (RUS), Slovakian (SLO), Slovenian (SLV), Spanish (SPA), Serbian (SRP), Swedish (SWE), Turkish (TUR)

I have got an addtional 26 languages to add to this list but not all discriminate as well due to the size of the test corpus I had, so let me know if you're interested in others. Obviously Korean and Japanese discrimitate well without frequency analysis due to their scripts.

Have fun!!

Saturday 8 February 2014

Hook Theory

This is another great piece of creativity and technology working together that I stumbled across earlier in the year and came to mind again today.

Hook Theory has a number of interesting flash apps looking at Music Theory. I was particularly interested in the chord progression analysis in the Music Editor application.


http://www.hooktheory.com/blog/chord-progression-search-patterns-and-trends/

Weird Faces - Algorithm Drawing

I was amazed by this last Christmas after seeing this referenced in a magazine and was reminded of it again drawing with the children this morning:
















Created by Matthias Dörfelt aka mokafolio, Weird Faces Study uses PaperJS library to produce computer generated faces that have a certain aesthetics and are immediately recognisable.

"Weird Faces Study is an attempt to combine my old interest in illustration with programing, to create something procedural that has a truly individual artistic touch to it and is not instantly recognisable as a generative art piece. Even though, the faces look hand-drawn, they are entirely expressed by algorithmic rules. Each face is random, each face is unique. Still, they look similar to my actual hand drawn faces."
















The faces are generated in a similar way as potato head (the toy). As seen on the right in the image below, Matthias thought about different presets for the different facial features that could then be mixed in arbitrary ways to compose the final face. The presets are expressed entirely algorithmically, so that each preset potentially has an infinite number of variations. Noise is applied to the outlines to suggest a hand drawn and natural gesture.


The order of the face generation is:

1. draw head shape.
2. draw fold inside the head shape.
2. find shape center, draw nose.
3. draw eyes based on the nose position and radius to make sure that they don’t overlap.
4. draw eyebrows based on the eye positions and radii.
5. draw mouth based on eyes and nose to make sure they don’t overlap.
6. draw cheeks based on head outline and head radius.
7. draw ears on the head outline.
8. draw hair on the head outline.

Weird Faces Study has been programed in Java Script using the great PaperJS library. The library includes useful functions built in to simplify a lot of the operations described above (i.e. to find the closest point on a path and to find the normal of a point on a path).

Quoted from Creative Applications

Mokafolio's project site for Weird faces is here.

The JSPaper showcase also has some other interesting projects worth looking at.

Wednesday 5 February 2014

Gem #1: Parsing Enums

I came across this little line today which I didn't know of before or had forgotten, it's pretty neat so I wanted to start capturing these little gems as I come across them so I have a reference for myself:

Waveform waveform = 
(Waveform)Enum.Parse(typeof(Waveform), radio.Tag as string, true);

What this does is it takes a string in (in this case radio.Tag) and converts it to an Enum. Great for GUI code.

References / Follow-up:

Tuesday 4 February 2014

Concertina deconstructed

The damaged Schoeler concertina that I won on eBay came at the weekend and with a brief 30mins between family activities I had a chance to take it apart and have a good look inside. It's a nice little beast and looks to be suitable for my initial project ideas.



The nice thing about the concertina is that it comes apart pretty easily. No need for bellows pins to be removed, just three screws on one size and then the middle plate containing the reeds and buttons is easily prized apart. All in all a simple and neat design.


The concept, like so many posts online is to have a go at converting this to a MIDI device.

This initial idea to try wiring the keys in place and put some kind on contacts on the levers. Unfortunately as many of the keys are damaged my first idea now is to replace the keys altogether with switches. As a first experiment the bellows air release buttons will need to be ignored.



To preserve the buttons and mechanism for a potential future project my first idea is to cut a completely new wooden plate to attach to the end box. The reeds are attached to this on one side, where the electronics will go and the buttons + holes on the other side.


I think it will be possible to make some kind of mounting to enable switches to reach through the existing holes. The new plate will need some smaller air-holes to enable some kind of pressure to be retained and some thinking of how to handle the bellows air release.

The Teensy 3.1s have arrived

Finally they've come in the post from PJRC today. Very excited, but slightly marred by the excess excise charges, so beware if you're in the UK.















I've also ordered the SD card adapter, which apparently can be mounted on top of the Teensy.

So, this import duty thing:

It says I've been levied with excise duty of £8.02 and then a further admin charge of £8 because this is over £16 in value. Shame as the cost of the Teensy 3.1 comes out about £12, but when you add the shipping in this almost doubles. That means that the Teensy's get excise duty based on their value (and the unfortunate admin charge), but the shipping seems to be excluded. By my calculations then, it's a sting, but it still seems cheaper to pay excise on one big order rather than multiple costly shippings even if this would make each package under the excise charge.

Any thoughts???

Really looking forward to playing with these boards. I have some ideas with pin A14 and the DAC with 12bits to see what kind of audio could be synthesized.