Question #696923 on Yade changed: https://answers.launchpad.net/yade/+question/696923
Karol Brzezinski proposed the following answer: Hi, please find my script below. It takes about 7 minutes on my computer to take 10 slices with 0.6 Mpx resolution (pixel size 0.000005 m), but obviously you need more slices for your reconstruction. Cheers, KB ####################### import numpy as np from PIL import Image n_slices = 50 x_s = np.array([]) y_s = np.array([]) z_s = np.array([]) radii = np.array([]) for b in O.bodies: if isinstance(b.shape, Sphere): pos = b.state.pos x_s = np.append(x_s,pos[0]) y_s = np.append(y_s,pos[1]) z_s = np.append(z_s,pos[2]) radii = np.append(radii,b.shape.radius) px_size = 0.000005 # pixel size (m) (x_min,y_min,z_min),(x_max,y_max,z_max) = aabbExtrema() real_h = z_max-z_min real_w = x_max - x_min # I assume here that slices will be perpendicular to y-axis img_h = ceil(real_h/px_size) # image height in px img_w = ceil(real_w/px_size) # image height in px """ The idea is as follows: - divide the cross section into squares (representing circles) - for the center of every square (pixel) check whether any center of the sphere is closer than its radius - if True color the pixel white, otherwise black One could probabily optimize this. I only took adance on the vectorisation in numpy. I have made a "manual" decision for this algorithm: since the number of pixels is greater than number of bodies I loop over spheres and do vectorized operation on the "pixel" array. """ x_px = np.tile(np.arange(x_min+px_size/2,x_min+px_size*img_w,px_size),img_h) z_px = np.repeat(np.arange(z_min+px_size/2,z_min+px_size*img_h,px_size),img_w) for y_slice in np.linspace(y_min,y_max,n_slices+2)[1:-1]:# take n_slices slices (linspace prepares n_slices+2, but I ommit first and last since it is not interesting) y_px = np.repeat(y_slice,img_h*img_w)# pixels_state = np.zeros(img_h*img_w).astype(bool) count = 0 for i in range(len(radii)): radius = radii[i] x = x_s[i] y = y_s[i] z = z_s[i] if abs(y-y_slice)<=radius:# I make use of simplified assumption, I only check pixels for the spheres that are close enough to my plane. pixels_state_tmp = np.sqrt((x-x_px)**2+(y-y_px)**2+(z-z_px)**2)<radius pixels_state = pixels_state + pixels_state_tmp img_array = 256*pixels_state.reshape(img_h,img_w).astype(np.uint8) img = Image.fromarray(img_array) img.save('slice_y_{:.5f}.gif'.format(y_slice)) -- You received this question notification because your team yade-users is an answer contact for Yade. _______________________________________________ Mailing list: https://launchpad.net/~yade-users Post to : yade-users@lists.launchpad.net Unsubscribe : https://launchpad.net/~yade-users More help : https://help.launchpad.net/ListHelp