You know the drill. Programming a graph takes too much time...use a library...or hire an external consultant. But...is it really so?
Imagine you have two coordinate systems. Your physical screen coordinate system spans from 0 to window's width horizontally and from 0 to window's height vertically. And your imaginary world (i.e. a map) spans from -10.000 to 10.000 horizontally and from 0 to 5000 vertically.
Just to make things a bit more complex you also want to:
- zoom everything on the screen by arbitrary zoom factor, and
- show only part of your map on the screen starting from point T(-3.000, 1000) given in map coordinates, where -3000 is left and 1000 is top coordinate of part of map we would like to display on screen.>
Map to Screen
Are you scared yet? Don’t be. Here is the basic formula for converting map coordinate to screen coordinate:

Same formula can be applied to another dimension. For example:

So far ... so trivial. :) Since you start at point T(x,y) you need to put x and y to point to 0,0 on the screen. Afterwards you simply multiply by zoom factor. If factor is 1 then 1 point on the map is converted to 1 point on the screen. If the factor is 1:2 then 1 point on the map is only ½ point on the screen. And so on.
If the axis is a reverse axis then your equation is:

Screen to Map
What if somebody clicks on the screen and we need to find map coordinate of the click? Let us derive this scenario from the above equation:

Deriving same formula for the reverse axis is a good exercise for you, don’t you agree? :)
Fit to Screen
If we want to fit our map inside the screen we must start drawing it at its T=T0 point. We calculate T by using:

No big secrets here. So our left, right point T is at map's min x and min y. And if reverse axis is being used we must use max instead.
The apropriate fit to screen zoom is calculated like this:

If you are using same unit for both axes then there will be only one zoom factor. To still fit map to the screen make sure that you fit larger dimension of both - width or height to fit the screen. Then use the same zoom factor for smaller dimension. This way both are guaranteed to fit the screen.
Calculate Distances
Last but not least ... distances are calculated with a little help from previous calculations. If you have a distance in screen units and you would like to convert to map distance you subtract it from point zero and derive the formula like this:

The distance obviously depends on the zoom factor alone. For better understanding derive the opposite formula and get screen distance from map distance yourself. :)
Coming Next...
So there you have it. Most of these formulas are -in fact- just simplified 4 x 4 matrix translation, usually performed for you by modern 2D graphics engines such as GDI+ or Cairo.
Observing simplicity of graph math one realizes that graphs aren't really such a terrible development effort. It's drawing points, lines and polygons using these formulas to translate coordinates. Zooming is changing the zoom factor, and scrolling is changing the T point. We will take a closer look at these operations in part two of this series.
A picture is worth a thousand words.
Source: Dr. Dobb's Journal
Coming from Windows background I was a bit worried about the complexity of accessing Postgres databases from C++. I'm still having nightmares of early ODBC programming back in the 90ties. But as a mature developer I quickly overcame Microsoft's fixation on building the mother of all DBMS access technologies; that is - a common database mechanism to access various DBMSes.
Seriously, how many times in life have you ported a database from MS SQL Server to Oracle? There is a brilliang library for accessing Postgres (and only Postgres!) from C++ available. It is pqxx. It comes with a tutorial to help you getting started.
Here is Hello World of libpqxx. It doesn't get any simpler then that. Following code executes a query on a database.
#include <pqxx/pqxx>
using namespace pqxx;
void execute_query() {
connection cn("dbname=my_database");
work w(cn, "mytransaction");
w.exec("INSERT INTO city(city_name) VALUES ('Ljubljana');");
w.commit();
}
When in Unix you should really do as Unixans do. They store application configuration to the /etc folder and user preferences to user's home folder using dot (.) for first name of file.
So if your application is called maestro then it should store its' configuration to /etc/maestro.conf (or /etc/maestro/config.xml or /etc/maestro/app.ini - it doesn't matter as long as it is in the /etc). And it should store its' user preferences to ~/.maestro file (or to ~/.maestro/.profile.txt - as long as it is in users' folder, starts with a dot and the filename hints about its origin).
Even Gnomes' GConf (you may run it from cmd line using gconf-editor) follows this convention by creating a ~/.gconf file in your home folder.

Your application should also be configurable via environment variables and command line parameters. But what if a collision of settings occur? Then you should use following priorities - low) read config file, mid) check the environment variables, high) check command line parameters.
Configuration source with highest priority should prevail. For example - if an option is defined in config file and is also passed as a command line parameter the one passed at the command line should be used.
Easiest way to implement all this is to try to read each settings from config file, then from environment vars and then from cmd line overwriting it each time a new value is available. This way the last read setting will prevail. There are multiple libraries available to assist you with reading config files and parsing command line parameters. Though options are many for C++ I recommend using Boost.Program_options. It will provide the user of your command line tool with experience he is familiar with including command line script files. I explained my preference for the Boost library here.
In the old days one called g++ compiler with a lot of command line switches to tell it where to find all include files and libraries. Nowadays civilized libraries register themselves with a tool called pkg-config. This tool knows how to generate all command line switches for you if you provide library name.
To list all libraries registered with the tool call
pkg-config –list-allTo see which libraries need to be linked with openssl library use
pkg-config –libs opensslThe tool will output: -lssl -lcrypto which are exactly the command switches you should provide to compiler. So if you wanted to link your sample with the openssl library you could write:
g++ -o sample sample.cpp `pkg-config --libs --cflags openssl`It really is that simple. Of course you immediately became interested in how exactly pkg-config does its magic, right? After all if you produce a library of your own you want it to be civilized and to register with pkg-config.
Here's how it's done. When you call pkg-config with a library name (for eample libpqxx) it first examines the contents of the /usr/lib/pkgconfig folder seeking for a file named libpqxx.pc. If it can't find it there it examines PKG_CONFIG_PATH variable repeating the search for libpqx.pc in each folder in this path.
After finding a match it extracts required library data. Here is the contents of libpqxx.pc file to get a feeling of how this works.
prefix=/usr/localAs you can see data in this description file is abundant. So after matching .pc file with the library pkg-config can easily generate output for command switches.
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libpqxx
Description: a C++ API to the PostgreSQL database management system.
Version: 3.0
Libs: -L${libdir} -L/usr/lib -lpqxx
Cflags: -I${includedir} -I/usr/include/postgresql
So there. With tiny bit of new knowledge your library can now register itself properly with the system. You can also create .pc files for libraries that don't behave as good citizens to simplify compilation. Or even debug foreign make files that fail.
.NET spoiled us all. The Framework's Standard Library contains answers to numerous programming challenges. From implementing http client to reading from a database – a plethora of classes speeds up the development and unifies programming experience.
Nothing quite as complete exists for C++. The open source world offers many libraries but without consistency of .NET. Except for two - the C++ Standard Library and the Boost. The latter will soon become part of the former.
Thus start your C++/Unix programming voyage by reading about Boost. Install it on your system. You do not need to compile it on Ubuntu. Just use Synaptic Package Manager to download and install. Then...whenever you identify a programming problem first consult the C++ Standard Library and the Boost. Only if solution can't be found there continue your search elsewhere.
Because the C programming language played such a pivotal role in history of Unix and open source many libraries are written in it. It is quite common to find a pair - a high quality C library to fulfill some task and a C++ wrapper to provide more modern interface.
For example - you might want to implementing http protocol in C++/Unix environment by using the Neon library as underlying technology and the Neon++ wrapper as an actual interface.
Sometimes instead of adding two pluses to wrapper library names an extension mm or xx is used. For example for C library libgtk the C++ wrappers is called libgtkmm. libpango - libpangomm. libcairo - libcairomm. libpg - libpgxx. This convention makes it easier to search for a wrapper when finding a C library to perform a task.
If not too much of a compromise try to keep your code consistent with C++ Coding Convention by selecting libraries that only use combination of lowercase letters and underscores for all program identifiers (except for template parameters, which start with capital letter).