Tuesday, December 13, 2011

3D models: the sphere



When working in 3D, there is always a need of 3D basic models to try new algorithms or to use them as building blocks. In this post, we'll see how to build a sphere and how we can move it in 3D without any additional plugins.

Creating a sphere

A sphere of center C (xc,yc,zc) and of radius R is easily built from the function Process > Math > Macro... by using the formula:
(x - xc)2 +(y - yc)2 +(z - zc)2 <= R2


Here is a small IJ script creating a 8-bit stack of 101x101x101 voxels containing a white sphere of radius 50.

radius=50;
newImage("sphere", "8-bit Black", radius*2+1, radius*2+1, radius*2+1);
code="code=[if (pow((x-50),2)+pow((y-50),2)+pow((z-50),2)<=50*50) v=255]";
options=" stack";
run("Macro...", code+options);

Translating spheres
Imagine that we want to display several spheres of variable radii and locations as shown in Fig. 1.
Fig.1: Random spheres visualized with Plugins > 3D > Volume Viewer

A naive implementation would use the Process > Math > Macro... function to display the spheres, but the Macro... scans the entire volume to display (or not) the voxels and if you work with a large volume, your script 'll be really slow.
It's better to create a single sphere which 'll be used as a template. Then, the only operations for translating a sphere into a large target volume consists of a copy (clone) and paste at the right location that can be done in 2D.
In the following script, the template is a 101x101x101 8-bit stack containing a sphere of radius 50 (lines 11-13) created by the function initSphere(...) (lines 32-38).
Then, the core of the script (lines 15-28) consists of defining the radius and center of the new sphere by using the random() IJ built-in function and applying these parameters thanks to the functions setRadius(...) and translate(...) to a temporary sphere before pasting it in the target volume.
More precisely, the setRadius(...) rescales the sphere template (Image > Scale...) and creates a new temporary sphere. Then, the function translate(...) copies each slice into the large target volume using setSlice(...) for the Z-translation and makeRectangle(...) for the X- and Y-translations.

+++ IJ snippet +++ +++ End of IJ snippet +++
Conclusion
The above script is really useful to draw 3D curves and this is the subject of this post [Link].

When working in 3D, a "must" to have is the plugin TransformJ because it implemented all the 3D geometrical transformations (rotation, translation, scale,etc.).

2 comments:

  1. Thanks for the nice script sniplets on your page.
    I found that I had to rename the variable "sin" in the

    function setRadius(sin,sout,rad)

    to something else, because its a reseved expression (sinus). I use Fiji (IJ1.46j).

    ReplyDelete