Since the iPhone tocuhscreen is quite small and has great support for interactivity a 3D tag cloud looks an ideal choice for an iPhone application user interface. Neither iPhone SDK classes nor 3rd party libraries have 3D tag cloud classes, at least no libraries I heard of, so I implemented it from scratch.
You can see the final result in the Toneaphone Ringtones iPhone App we developed last year.
Tag clouds became increasingly popular these days as an amazing way of data representation. A tag cloud is basically a set of text labels which vary by size reflecting more or less popularity for that particular keyword. Tag clouds can be flat and 3D. Flat tag clouds are most often used on web sites as they can be easily implemented with standard HTML and some back end coding. 3D tag clouds are more difficult to program but they are much more compact, interactive and amazing for users to play with.
You can think of this tag cloud as of a set of labels on the surface of a virtual sphere. It is good to be familiar with spheric coordinates and their transformtion formulae for this implementation. Wikipedia is a good reference.
First some algorithm is needed to evenly distribute the lables on the surface of the virtual sphere. The best technique may vary depending on the expected number of labels. To keep it simple enough it’s possible to loop through elevation and azimuth angles and evenly distribute lables alongside them. I just played with loop increment until I liked how it looks. It’s really a freedom for mind here because an optimal algorithm is quite complex and one may find that some simplified version is good enough for paticular task (additional information is available).
To display labels on the screen it is necessary to transform elevation and azimuth into screen coordinates which are basically X and Y. As for Z coordinate which is depth coordinate it can be visualized by font size. The closer is the label to the user the bigger font size is assigned to it.
Once tag cloud is displayed rotation needs to be handled. Here the hard part comes. I figured out that to rotate «naturally» for users it shoud use the following coordinate transformations. Assuming psi and phi are rotation angles around OX and OY respectively the formulae look like this:
Step 1:
X = X * cos(psi) + Z * sin(psi)
Y = Y
Z = -X * sin(psi) + Z * cos(psi)
Step 2:
X = X
Y = Y * cos(phi) – Z * sin(phi)
Z = Y * sin(phi) + Z * cos(phi)
So the way to make it rotate is to catch swipe gestures as Apple Programming Guide recommends and apply these transformations.
During rotation it may happen that some labels overlap. To provide realistic view of the tag cloud labels should be Z-sorted when displayed (farthest labels drawn first). When a tag label is selected it is also critical for tap gesture handling that the closest label responds in case they overlap. Z-sort helps here as well.
The described implementation method should work in both standard UI and OpenGL environments. I used standard UI with UILabels since that was a requirement, however I would expect better performance from OpenGL implementation.
If you find any classes nor 3rd party libraries that support 3D tag clouds please let me know, I will be very interested to compare implementations… Happy coding!