Data Visualization sounds hard, but it’s actually easy to build in C++ IDE. C++ is an immensely powerful programming language allowing you to develop fully native and super-fast applications, games, and utilities with rich graphics. You can use OpenGL or Direct3D libraries or some other 3rd party 3D Engines. In C++ Builder you can directly create your own 3D objects; you can animate them at runtime. Viewport3D (TViewportd3D) component in C++ Builder FireMonkey projects is good to display many basic 3D Objects like Plane, Cube, Sphere, Cone, Plane, Ellipse3D, etc. Please see this post about Working With 3D In Modern Windows C++ Development for creating these 3D objects. You can also easily load your 3D objects into Viewport3D by using Model3D (TModel3D).
Table of Contents
What do we mean when we say data visualization?
As we’ve said elsewhere on this blog; visualization is the art of making the useful, beautiful. We humans consume large numbers of facts and figures much more readily if we have that stream of data converted into something graphical like a pie chart, bar, line or scatter plot. It allows us to mentally process and understand that information more easily than we could if we had it, for example, in a series of rows and columns on a spreadsheet.
How do we create a 3D object in C++?
To create a 3D object to be used in Viewport3D we need to use TMesh classes. TMesh is a custom 3D shape that can be customized by drawing 3D shapes. It is a class publishes a set of properties from its ancestor, TCustomMesh, in order to let you design new 3D shapes at design time from within the IDE, through the Object Inspector. Use the Data property to specify the points, normals and textures for each point, and the order in which the resulting triangles are drawn. The designed shape is filled with the material specified through MaterialSource property. If no material is specified, then the shape is filled with red color.
How to use a TCylinder to create a 3D data visualization
The TCylinder is used in Viewport3D component, it is a 3D cylinder, a class implements a 3D cylinder shape built on a 3D wireframe, that can be placed on a 3D FireMonkey form. TCylinder is a visual object that can be added from the Tool Palette. To change the color or add texture to the sphere, use the MaterialSource property. Set SubdivisionsAxes and SubdivisionsHeight to specify how smooth the sphere’s surfaces are. We can drag a TCylinder from palette to a TViewport3D on the form and we can update its properties as below.
In this post we will use this TCylinder (as a cylindrical bar) to display our 2D data in a 3D space. We can also use other 3D objects in C++ Builder. For example you can use TCube or TCone to display 2D data in a 3D view, values at 2D nodes in X and Y directions. For more details about 3D objects in C++ Builder, please read more about Learn To Quickly Create Specific 3D Objects In Modern C++ Applications For Windows
We can create a 3D cylinders as below,
For example we can define it as a global variable or as a public variable of TForm1 as below,
Or we can set dragged TCylinder features of this cube as given example below,
How to generate random 2D test data
Let’s assume that we have data in 2D form, that means we have values in each X and Y coordinates. So, as an example, we can generate a random 2D data as below,
Simply we can print this 2D data to TMemo component as given example below,
What you need to create a visualization of 2D data with 3D cylindrical bars
We have 3D data grid from the calculations or from the obtained values of sensor about a 3D environment or about a 3D object. We can use cylinders as cylindrical bars to visualize these kind of 3D data. Idea here, to display magnitudes in every node we will use color gradient (i.e gradient from yellow to red and to blue ) and we will display these colors with our 3D cylinders. Using TViewport3D to display cylinders has some advantages: easy to visualize in nodal form, easy to color, easy to rotate and zoom all, one of the most important part is we can easily slice this 3D form in X Y or Z directions so we can visualize every layer. Disadvantages are bigger grids may take a lot of memory and slower display time and slower animations.
Let’s start to create our 2D data with cylinders,
1. Create a new C++ Builder Console FMX application, save all project and unit files to a folder. And modify code lines as below;
2. Drag a Viewport3D from Tool Palette on to Form. We will use this to display our 3D map space. Add a Dummy Object, Small Cube and Camera, 2 Lights to our ViewPort3D by dragging from the Tools Palette. Let’s modify these from design and
– Dummy1 will be our rigid object which will be composed with a lot of cylinders, thus we can easily move or rotate this Dummy object and all other 3D objects attached to this.
– Small cube will be used to see center of this Dummy1 object in design, we will use it on our test runs and we will make it invisible on run time.
– Set both Light Types to Point and, put Lights to upper left and right corners, one light could be gray.
– Set Camera in a good position for example z=-20, position where the small cube (origin of Dummy1) is centered.
– Select Viewport3D, set Use Design Camera property to false
If we combine these two examples we can create a function which creates cylinders in radiusX, raidusY andDX,DY and DZ sized cube in a given x, y, z with origin displacement
Adding some rotation to add a professional look to our data visualization
We can rotate all 3D cubes by rotating their parent Dummy1. Select ViewPort3D1 and double click its OnMouseDown(), OnMouseMove(), OnMouseUp() events and modify them as below,
When we close the form we should free all cube material sources and cubes as given example below,
When done we must free all the bars which were allocated in the memory with new command. We can do this as below,
We must make sure we free the data when we are finished with it
When we close the form we should free all cube material sources and cubes as given example below,
Finally we should add all these above to our Button OnClick() events (Button1 , Button2)
How to update the 3D view with new data
We can update data and update the view by changing height of all bars as below,
An example of a beautiful, professional 3D data visualization
As a result application should be as below, doesn’t it look spectacular?
Final Words
From now, you can advance this example, by adding a plane object and a texture that shows directions and grids, or this texture can be a natural texture. You can light when a the bar is selected or when the mouse is on it, you can also show its value with coordinates and percentage. Firemonkey has Opacity features in graphics so you can make bars semitransparent to see their behind or to make them like glass. You can also apply different textures and colors to each of them.
Post and method look long but if you try these in C++ Builder, you will see it is really easy and simple to do these kinds of graphics. In our previous post we explained how we can solve heat transfer equations or other 3D equations on those kind of 3D problems. C++
We hope you like this example and method. In this method, we choose to use Viewport3D and 3D cylinders, you can do these kinds of graphics with OpenGL or other 3D engines, components, etc. You can also directly draw to Canvas or to Canvas of a Bitmap by calculating projections of objects with 3D Rotation Matrix as given example here.
RAD Studio, C++ Builder is a great programming language to calculate these kinds of problems in C++ and is also powerful enough for all your development needs. If you are new to C++ Builder, why not download and try C++ builder today?