Visualizing the Mandelbrot Set with SFML: C Style

I use fractals as my “Hello World” when I want to explore graphics libraries. Since I’m learning SFML at the same time I’m learning C++ I figured it would be a good idea to explore different ways of doing the same thing.

I’m going to go into it in detail, but here’s a C-style implementation. Over the next few days I’ll see if I can implement a proper C++ class-based approach that achieves the same result.

#include <SFML/Graphics.hpp>

void CalcMandelbrotSet(int screenHoriz, int screenVert);
float PixelCoordToGraphCoord(int pixelCoord, float graphWidth, int imageWidth, float graphMin);
int CalcMandelbrotEscapeValueForComplexNum(float real, float imaginary, int escapeMax);

int horizontalResolution = 200;
int verticalResolution = 200;
int escapeMax = 500;
float graphXMax = 2;
float graphXMin = -0.5;
float graphYMax = 1;
float graphYMin = -1;
sf::VertexArray varray;

int main()
{
    sf::RenderWindow window(sf::VideoMode(horizontalResolution, verticalResolution), "Mandelbrot");
    CalcMandelbrotSet(horizontalResolution, verticalResolution);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        window.clear();
        window.draw(varray);
        window.display();
    }

    return 0;
}

void CalcMandelbrotSet(int screenHoriz, int screenVert)
{
	varray.clear();
	float graphX;
	float graphY;
	int x, y, escape;
	sf::Vertex vertex;
	for (y = 0; y < screenVert; y++)
	{
		graphY = PixelCoordToGraphCoord(y, graphYMax - graphYMin, screenVert, graphYMin);

		for (x = 0; x < screenHoriz; x++)
		{
			vertex.position = sf::Vector2f(x, y);
			graphX = PixelCoordToGraphCoord(x, graphXMax - graphXMin, screenHoriz, graphXMin);
			escape = CalcMandelbrotEscapeValueForComplexNum(graphX, graphY, escapeMax);
			
			if (escape == escapeMax)
			{
				vertex.color = sf::Color::Green;
			}
			else
			{
				vertex.color = sf::Color::White;
			}

			varray.append(vertex);
		}
	}
}

float PixelCoordToGraphCoord(int pixelCoord, float graphWidth, int imageWidth, float graphMin)
{
	return ((float)pixelCoord * (graphWidth / (float)imageWidth)) + graphMin;
}

int CalcMandelbrotEscapeValueForComplexNum(float real, float imaginary, int escapeMax)
{
	float zReal, zImag;
	float z0Real, z0Imag;
	int n, escape;
	zReal = zImag = 0;
	z0Real = z0Imag = 0;

	for (n = 0; n <= escapeMax; n++)
	{
		z0Real = ((zReal * zReal) - (zImag * zImag) - real);
		z0Imag = (2 * (zReal * zImag)) + imaginary;

		if (((z0Real * z0Real) + (z0Imag * z0Imag)) >= 4)
		{
			escape = n;
			return escape;
		}

		zReal = z0Real;
		zImag = z0Imag;
		escape = escapeMax;
	}
	
	return escape;
}

Nothing too terribly elaborate. I split out some of the more interesting calculations into their own functions for readability.

Posted in Uncategorized | Leave a comment

C++ Parent Class and Member Initialization

This is a small bit of code to remind me of what I learned today about how to pass values to a parent class, as well as initialize member variables in the child class constructor.


class ParentClass
{
public:
	ParentClass(int x)
	{
		printf("ParentClass was passed: %i\n", x);
	}
};

class ChildClass : ParentClass
{
private:
	int y;
public:
	ChildClass(int x)
		: ParentClass(x), y(x)
	{
		printf("In ChildClass, y is: %i\n", x);
	}
};

int main(int argc, char* argv[])
{
	ChildClass childclass(42);
	return 0;
}

The output is:
ParentClass was passed: 42
In ChildClass, y is: 42

It’s not obvious to me how to split out the implementation from the interface in this case, however. Err… is “interface” and “implementation” the correct C++ lingo? That’s what it’s called in Objective-C. Hmm.

Posted in Uncategorized | Leave a comment

Order Matters Inside of C++ Classes

Confession time: I’ve been putting some effort into learning C++, after years of swearing I’d stick with straight C. The push to C++ has been driven by SFML, which I’d really like to play with. The SFML documentation and samples are really good, and have convinced me that maybe C++ isn’t all bad. I’m having some success, but I’ve run into tons of obvious-in-hindsight rules.

It’s common to see C++ classes declare all of the public members first, and the private members second, but you can’t always do that. Order matters. This won’t work:


class StructDemo
{
public:
 StructDemo(void);
 struct example FillStruct();

private:
 struct example
 {
  int x;
  float y;
  bool z;
 } example;
};

struct StructDemo::example StructDemo::FillStruct()
{
 struct StructDemo::example test;
 test.x = 1; test.y = 2; test.z = 1;
 return test;
}

Visual Studio gives me a heads up that my definition of StructDemo::FillStruct() doesn’t match the function prototype in the class, and it won’t compile without error.

structerror

After some Googling I found a relevant Stack Overflow question about it: http://stackoverflow.com/questions/5523109/c-define-class-member-struct-and-return-it-in-a-member-function

Ah – of course order matters! My problem came from thinking that public variables/methods had to come before private. It’s not the case. This is valid, and makes complete sense in hindsight. You have to declare variables before you can use them. Obviously!


class StructDemo
{
private:
 struct example
 {
  int x;
  float y;
  bool z;
 } example;

public:
 StructDemo(void);
 struct example FillStruct();
};

I can see many more posts coming up about the bonehead things I do out of superstitious cargo cult thinking.

Posted in Uncategorized | Leave a comment

Problems Re-sizing SFML RenderWindow

I’ve been using the newly-released SFML 2.0 as an excuse to learn C++. It’s been quite interesting.

While messing around with the SFML graphics capabilities I found that I can’t seem to reliably re-size the SFML render window without the contents getting completely scrambled.

Here is a very simple example (forgive how WordPress mangles it):


#include <SFML/Graphics.hpp>

int width = 200;
int height = 200;

sf::VertexArray varray(sf::Points);
sf::Vertex vertex;

void stripes()
{
 varray.clear();
 varray.resize(width * height);
 for (int y = 0; y < height; y++)
 {
 for (int x = 0; x < width; x++)
 {
 vertex.position = sf::Vector2f(x, y);
 vertex.color = sf::Color::White;
 if ((x % 10) == 0){vertex.color = sf::Color::Red;}
 varray.append(vertex);
 }
 }
}

int main()
{
 sf::RenderWindow window(sf::VideoMode(width, height), "Resize Test");
 stripes();

while (window.isOpen())
 {
 sf::Event event;
 while (window.pollEvent(event))
 {
 if (event.type == sf::Event::Closed)
 window.close();
 }
 window.clear();
 window.draw(varray);
 window.display();
 }
 return 0;
}

This produces a striped image.

resizetest1Neat. Ok, now I’ll re-size my window.

resizetest2Oof, not so neat. But, it kind of looks like it’s taking my 200 x 200 array of data and stretching it across the window equally. That makes sense, I suppose. Well, the RenderWindow class can detect when it’s resized, so what I’ll do is capture that event and re-calculate what I’m displaying to be correct to the new size.

Here’s main() with some re-size detection code that re-runs the function that generates the array of points that gets plotted.


int main()
{
 sf::Vector2u windowsize;
 sf::RenderWindow window(sf::VideoMode(width, height), "Resize Test");
 stripes();

while (window.isOpen())
 {
 sf::Event event;
 while (window.pollEvent(event))
 {
 if (event.type == sf::Event::Closed)
 window.close();

if (event.type == sf::Event::Resized)
 {
 windowsize = window.getSize();
 width = windowsize.x;
 height = windowsize.y;
 stripes();
 }
 }
 window.clear();
 window.draw(varray);
 window.display();
 }
 return 0;
}

However, once again after I re-size the window…

resizetest3

Bleh.

I’ve done this several ways, but no dice.

EDIT: I figured out a solution. I don’t know if it’s THE solution, however. I realized that I’m initializing the RenderWindow at a specific resolution, and that re-sizing the window might not be telling it to re-size the video mode. At the end of my if-statement where I regenerate the vertex array, I put:


window.create(sf::VideoMode(width, height), "Resize Test");

So it starts of like this:

resizetest1

And re-sizes into this:
resizetest4There is one lingering problem. After I release the edge the window, the whole window “jumps” to a slightly different location. This must be the result of re-creating the window. It’s first closing it, and then re-creating it.

I wonder if there is a way to put it back right where it was, or if there is a more graceful solution.

Here is a gist of the functional program: https://gist.github.com/anonymous/5709180

Posted in Hobbies, Programming | Leave a comment

Hello, Kerbal!

The tutorials on the official Kerbal Space Program wiki for setting up Visual Studio and making a simple mod are a bit vague in some areas. Here’s my take on making a mod in Kerbal Space Program. Anyone that knows how to edit the official wiki tutorial is more than welcome to steal anything below.

Acquire and Install Visual Studio 2012 Express

If you’re running Windows 7 and don’t have Visual Studio installed yet, go here: http://www.microsoft.com/visualstudio/eng/downloads#d-express-windows-desktop

Click on “Install Now”. It will install and ask for a reboot. You can run it in trial mode for some amount of time (30 days?) but it’s super easy to just register an account and get a license key. The Express version of Visual Studio is free for personal/student use. It has a few restrictions, like you can’t compile 64-bit applications, so catch up on that if you care to. There have been past versions of Visual Studio Express, but not all of them had the ability to create programs in C#, so if you’re using an existing install, check to make sure you can create C# programs.

Create a New Visual C# Class Library Project

Open Visual Studio and go to File->New Project and create a new Visual C# project. I named mine HelloKerbal.

New C# ProjectIf all goes well, you’ll have a new project ready with a default class called class1.

New Project

Add References to the Project

This mod requires us to be able to reference the Kerbal API (and some parts of the Unity API, too, I think). To do this, you need to add two .dll files as references in Visual Studio. There’s a pane called “Solution Explorer” that’s (by default) on the right. Right-click on “HelloKerbal” and click on “Add Reference”.

addreference1

When the Reference Manager pops up, click on “Browse” on the bottom.

addreference2-clickbrowse

Navigate to your Kerbal Space Program install directory, and go to the “KSP_Data” directory, and then the “Managed” directory. I bought Kerbal Space Program through Steam, so the .dlls are in “C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program\KSP_Data\Managed”.

addreference3-dlllocation

Add “Assembly-CSharp.dll” and “UnityEngine.dll” as references. You can control-right-click both .dll files to add them both at the same time.

addreference4-adddlls

Click “Add”, verify in the Reference Manager they’re both there, then click “Ok”.

addreference5-dllsadded

Create a Subclass of PartModule and Say Hello

Alight, it’s time to modify the default code that Visual Studio created for us. Change the default Class1 to HelloKerbal, and set it to be a subclass of the PartModule class that’s defined in one of the .dll files that we’re referencing.

modifyclass

It’s a good idea (sometimes but not always) to rename the source code file to the name of the class that’s being defined in it. In the “Solution Explorer”, right click on “Class1.cs” and rename it to “HelloKerbal.cs”.

renamecsfileThis is a convenient thing to do, since it will result in the .dll being built to be called HelloKerbal.dll instead of Class1.dll. You should see something like this after renaming.

renamedcsfileThe HelloKerbal class inherits from the PartModule class, which has a method called OnStart that we’ll redefine (override) to suite our nefarious purposes. As far as I can tell, OnStart is a method that’s called when a part is added to your spacecraft. So, we want to redefine the OnStart method to include a print statement that will output “Hello, Kerbal!” to the debug log.

overridefunctionprintI’m not super familiar with C#, but I think that this is the correct way to go about this.

Compile the Class Library and Copy to Plugins Directory

Hit F7, or go to “Build->Build Solution”. The “Output” pane will show that you’ve built a .dll in the “Debug” folder under your project folder.

f7tobuildoutputNavigate to this directory in Windows Explorer, copy the HelloKerbal.dll file, and place it in the Kerbal Space Program plugins directory. Mine is here: “C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program\Plugins”.

Create a Copy of an Existing Part to Use New Behavior

This mod creates a simple behavior for a rocket part. It’s beyond the scope of this tutorial to create a brand new part, so we’re going to make a copy of an existing one and point it towards this mod as its defined behavior (just like the Wiki tutorial does). Hopefully the original creator of this part won’t mind.

Go to the “Parts” directory in your Kerbal Space Program install location. Mine is in “C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program\Parts”.

Scroll down to the “RCS block” directory, select it, and hit Ctrl-C, and then Ctrl-V. You should see a copy of the “RCS block” directory called “RCS block – Copy”.

copyRCSblockGo into the “RCS block – Copy” directory and open “part.cfg” in Notepad. There is really only one part of the config file that needs to be edited so that it points to the function in HelloKerbal.dll, but for convenience we’ll edit the title of the part, too, so that it’s obvious which one it is in the rocket building interface.

Edit the “rcs module parameters” section at the bottom of the config file to say “name = HelloKerbal”.

configfile1-modulenameEdit the “editor parameters” section of the config file to say “title = RV-105 COPY”.

configfile2-titleSave the config file.

Activating and Observing the Mod Behavior

Start Kerbal Space Program, and get into the Vehicle Assembly Building. Pop open the debug console by pressing alt-F2. This is where we’ll see the mod behavior in a moment.

KSPdebugconsole1

The copied part is under the “Control” category of parts, so you’ll need to plop down a cockpit or load an existing rocket to get access to it. Go to the Control category and observe that there are two identical looking parts, and that one of them named “RV-105 COPY”.

RCSduplicatesAll that’s needed to initiate the behavior we defined is to click on the modified part. Click it, and you’ll see “Hello, Kerbal!” printed out in the debug console.

KSPdebugconsole2Discussion and Some Questions

I’m not at all familiar with the Unity framework, so I don’t know if the OnStart function is a Unity thing, or something unique to Kerbal Space Program. I could only get the OnStart function to fire off when I clicked on the part in the editor. There is some documentation on the class methods here: http://wiki.kerbalspaceprogram.com/wiki/API:PartModule

Much of my confusion with the tutorial on the wiki stemmed from not understanding that the mod would be tied to a part. Is this always the case that a mod has to be tied to a part?

There seems to be a lot of discussion on the official forums, so I guess I’ll have to keep digging for some answers. I’d like to also try creating my own part model so that I don’t have to borrow someone else’s existing work, but I’m not sure if I can do that with just Blender. I keep seeing references to having to do things in Unity (which is a framework AND an editor, I guess?).

When I edited the config file’s Module name field to say “HelloKerbal”, did that point it to the .dll file itself, or the class inside the .dll? I assume the latter. What implication does this have for mod code organization?

Well, whatever I learn I’ll try to write about. I can see myself taking a break from Kerbal Space Program after I inevitably burn out, so I’d like to bang out some tutorials so that my future self won’t have a tough time remembering how to do things once I pick it back up!

Posted in Hobbies, Programming | Leave a comment

Binary blunder

Something I was trying to figure out at work resulted in writing a make sure I understood how to write an array of numbers to a file. When I loaded the file for viewing it would (in places) be total garbage, and I couldn’t figure out why. I narrowed it down to what seemed to be specific ranges of numbers that were showing up as garbage, and write a new test program:


#include <stdio.h>
#include <stdlib.h>

int main()
{
  FILE *BINfile;
  char *binfilename = "binfile.bin";
  short int data[20];
  int n;

  BINfile = fopen(binfilename, "w+");

  for (n = 0;n < 20; n++)
  {
    data[n] = n;
  }

  fwrite(data, 2, 20, BINfile);

  fclose(BINfile);

  return 0;
}

All I’m doing is writing an array containing the numbers 0 through 19 to a file. It still didn’t look right when viewing it (in a program that basically just plots these numbers as a line) so I decided to look at the data in a hex viewer.

hexdumpI’m on a machine that stores bytes as little-endian. To borrow Wikipedia’s example, if I have the decimal number 1000 and I write that to a file as binary data, it gets stored as E8 03. So, I’m expecting my sequence of numbers I’m storing (0 through 19) to be 00 00, 01 00, 02 00, 03 00, and so on up to 19 which is 13 00. I can see 00 00 at the start of my hex dump and 13 00 at the end, but something looks funky in the middle.

Here’s 1 through 9…

hexdump1-9But where I thought 0A 00 would be is this…

hexdump-0d0aWhat’s 0D 0A doing there? And why are the next several numbers wrong?

After much puzzling and Googling I found a StackOverflow post that made me realize that when opening the file for writing I had not specified that it should be written to as a binary file, so it defaulted to a text file. ASCII 10 is a line feed character, which appears to translate to 0D 0A when written to a file.

All I had to do is change this line:

BINfile = fopen(binfilename, “w+”);

to

BINfile = fopen(binfilename, “w+b”);

Just one little “b” and everything is better.

Posted in Programming | Leave a comment

Speeding up my Project Euler 10 implementation with threads

My implementation of Project Euler 10 takes almost 25 minutes to complete. It’s a very naive attempt, and there is a great deal of optimization that needs to happen – particularly in the function I use to determine if a number is prime.

I decided to ignore an elegant optimization and see if I could decrease the execution time by solving the problem in several concurrent threads.

Project Euler 10 asks you to find the sum of all prime numbers that are under 2,000,000. It’s easy to see how to parallelize this – calculate (and add together) the primes from 0 to 1,000,000 in on thread, and the primes from 1,000,001 to 2,000,000 in another thread. Add the results from the two threads together and you have the solution. I decided to do it in four threads:

Thread 1: add primes from 0 to 500,000

Thread 2: add primes from 500,001 to 1,000,000

Thread 3: add primes from 1,000,001 to 1,500,000

Thread 4: add primes from 1,500,001 to 2,000,000

I’ve never written any threaded code before, so I hit up Google and found this page. I’m surprised (but quite relieved!) that it’s actually very easy to create and synchronize threads.

Each thread is summing up primes under it’s respective range, and when the thread is finished it adds the calculated total to a variable that all threads can see. I use a mutex to prevent the threads from potentially trying to write to the variable all at the same time, but in my application this really isn’t a risk since each thread takes a considerably different time to complete.

I don’t feel like fighting the code formatting in WordPress, so here’s a Gist of my solution: https://gist.github.com/anonymous/5130987

It’s pretty straightforward and follows much of the conventions in the tutorial I found, so I won’t do a line-by-line breakdown here (unless someone asks).

The end result? Execution time is just over 8 minutes (which is how long it takes for the 4th thread to finish – the other three finish well before then).

Two quick notes. The GCC command I needed to use was:

$gcc -pthread pthreadPE10.c -o pthreadPE10

In the tutorial (and elsewhere online) you see “-lpthread”, but that didn’t work for me – “-pthread” did. This SO question addresses this (see the response by “Employed Russian”).

Also, I wrote this program on my web server, which is a Linux server instance hosted on Digital Ocean. I wasn’t seeing any improvement in execution and after some pondering I realized that the package I’m using is a single-core server, so multi-threading doesn’t have any speed benefit there. Funny though – I’m glad I didn’t get frustrated and decide I didn’t know what I was doing! (EDIT: I should note that the 25 minutes to 8 minutes benchmark was achieved on my 8-core i7 laptop.)

Posted in Hobbies, Programming | 2 Comments