Message Boards Message Boards

0
|
791 Views
|
2 Replies
|
2 Total Likes
View groups...
Share
Share this post:

RegionImage gives weird 3D shapes

Hello all,

I am trying to generate a 3D Raster Image from Shapes that I place in 3D. I started with some random spheres but I obtain a result that I do not understand:

d0 = Table[{RandomReal[{-50, 50}, 3], RandomReal[{5, 8}]}, {20}];
d1 = Ball @@@ d0;
img = RegionImage[RegionUnion[d1], RasterSize -> 400]
ListAnimate[Image3DSlices[img]]

What I see are polygons instead of circles.
Can anyone explain what is happening and how to fix it?

Thanks!
Max

Attachment

Attachments:
2 Replies
Posted 7 months ago

When I need precision for "basic" shapes (like ball), I usually use CSRegion. Combine that with DiscretizeRegion. It takes more time.

reg1 = CSGRegion["Union", d1];
img1 = RegionImage[DiscretizeRegion[reg1], RasterSize -> 400];
ListAnimate[Image3DSlices[img1]]
POSTED BY: Eric Rimbey

Hello Eric,

thanks for the hint. But yes, this works even slower... :|

So I was using this as an opportunity to try including some C code into my Mathematica projects. I have to say that the help function is usually very good, but for the C code interfacing it would benefit from more examples and a comprehensive tutorial.

Finally I managed to get it working though. And it's fast :)

Needs["CCompilerDriver`"];
Needs["SymbolicC`"];

(* generate a table with many random balls *)
sz = {{-200, 200}, {-200, 200}, {0, 50}, {10, 20}};
n0 = 200;
d0 = Table[RandomReal /@ sz, {n0}];

mylib1src = "
#include \"WolframLibrary.h\"
DLLEXPORT mint WolframLibrary_getVersion(){return WolframLibraryVersion;}
DLLEXPORT int WolframLibrary_initialize( WolframLibraryData libData) {return 0;}
DLLEXPORT void WolframLibrary_uninitialize( WolframLibraryData libData) {}

DLLEXPORT int myFunction(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res){

 int err; // error code

 // input tensor
 // data of the input tensor: 2-dim array with ball coordinates and diameter (x, y, z, d)
 MTensor m1 = MArgument_getMTensor(Args[0]);
 mreal *a;
 a = libData->MTensor_getRealData(m1);
 mint const* dimsi = libData->MTensor_getDimensions(m1);  // dimensions of a

 // start and end points and step of image, z coordinate
 mreal x1 = MArgument_getReal(Args[1]);
 mreal x2 = MArgument_getReal(Args[2]);
 mreal dx = MArgument_getReal(Args[3]);
 mreal y1 = MArgument_getReal(Args[4]);
 mreal y2 = MArgument_getReal(Args[5]);
 mreal dy = MArgument_getReal(Args[6]);
 mreal z = MArgument_getReal(Args[7]);

 mint nx = (int) (x2-x1)/dx;    // size of the output tensor
 mint ny = (int) (y2-y1)/dy;
 mint dimso[2];
 dimso[0]=nx;
 dimso[1]=ny;

 // output tensor
 // data for the output tensor:
 // x-y section at position z
 MTensor m2;
 mint *img;
 err = libData->MTensor_new(MType_Integer, 2, dimso, &m2);     //definition of the output tensor
 img = libData->MTensor_getIntegerData(m2);

 mreal x, y;           // current x, y position in the image
 mreal d2, r2;         // squared distance from a ball center, squared radius of the ball
 mint nb;              // ball counter
 mint i, j, k;         // counters for x, y position

 for(i = 0; i < nx; i++) {              // loop through x and y coordinates
  for(j = 0; j < ny; j++) {
   nb = 0;                              // initialize ball counter
   x = x1+i*dx;                         // calcualte actual x and y
   y = y1+j*dy;
   for (k = 0; k < dimsi[0]; k++) {     // loop through all balls
    d2 = (a[k*4+0]-x)*(a[k*4+0]-x) + (a[k*4+1]-y)*(a[k*4+1]-y) + (a[k*4+2]-z)*(a[k*4+2]-z);
    r2 = a[k*4+3]*a[k*4+3];
    if (d2<r2) { nb++; }                // if distance < ball radius increase ball counter
   }
   img[i*ny+j] = nb;
  }
 }

 MArgument_setMTensor(Res, m2);
 return LIBRARY_NO_ERROR;
}
";

(* Create library with the C function *)
(* syntax of the function: *)
(* input:  d0, x1, x2, dx, x1, y2, dy, z*) 
(*  d0: array n0 x 4 of x, y, z coordinates of balls *)
(*  x1, x2, dx, x1, y2, dy: start, end and step of the x and y coordinates for the image *)
(*  z: z coordinate of the slice *)

mylib1 = CreateLibrary[mylib1src, "mylib1"]
myFunction = 
 LibraryFunctionLoad[mylib1, 
  "myFunction", {{Real, 2}, Real, Real, Real, Real, Real, Real, Real}, {Integer, 2}]

Manipulate[Image[0.3*myFunction[d0, -200, 200, 1, -200, 200, 1, z]], {z, 0, 50, 1}]

If anyone has advice for improving my C code, please let me know!

Max

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract