def render(self): """ """ self.apply_render_style() # Create camera and plotter if brainrender.WHOLE_SCREEN: sz = "full" else: sz = "auto" if brainrender.SHOW_AXES: axes = 4 else: axes = 0 mv = Plotter(N=2, axes=axes, size=sz, pos=brainrender.WINDOW_POS, bg=brainrender.BACKGROUND_COLOR, sharecam=True) actors = [] for scene in self.scenes: scene_actors = scene.get_actors() actors.append(scene_actors) mv.add(scene_actors) mv.show(actors[0], at=0, zoom=1.15, axes=axes, roll=180, interactive=False) mv.show(actors[1], at=1, interactive=False) interactive()
def render(self, _interactive=True, **kwargs): """ :param _interactive: (Default value = True) :param **kwargs: """ camera = kwargs.pop("camera", None) for scene in self.scenes: scene.apply_render_style() if camera is None: if scene.atlas.default_camera is None: scene_camera = brainrender.CAMERA else: scene_camera = scene.atlas.default_camera else: if camera: scene_camera = camera else: scene_camera = None if scene_camera is not None: set_camera(scene, scene_camera) if self.N > 4: print("Rendering {} scenes. Might take a few minutes.".format(self.N)) mv = Plotter(N=self.N, axes=4, size="auto", sharecam=True, bg=brainrender.BACKGROUND_COLOR) actors = [] for i, scene in enumerate(self.scenes): scene_actors = scene.get_actors() actors.append(scene_actors) mv.add(scene_actors) for i, scene_actors in enumerate(actors): mv.show(scene_actors, at=i, interactive=False) print("Rendering complete") if _interactive: interactive()
def export_for_web(self, filepath='brexport.html'): """ This function is used to export a brainrender scene for hosting it online. It saves an html file that can be opened in a web browser to show an interactive brainrender scene """ if not filepath.endswith('.html'): raise ValueError("Filepath should point to a .html file") # prepare settings settings.notebookBackend = 'k3d' self.jupyter=True self.render() # Create new plotter and save to file plt = Plotter() plt.add(self.get_actors()) plt = plt.show(interactive=False) plt.camera[-2] = -1 print('Ready for exporting. Exporting scenes with many actors might require a few minutes') try: with open(filepath,'w') as fp: fp.write(plt.get_snapshot()) except: raise ValueError("Failed to export scene for web.\n"+ "Try updating k3d and msgpack: \ "+ "pip install -U k3d\n"+ "pip install -U msgpack") print(f"The brainrender scene has been exported for web. The results are saved at {filepath}") # Reset settings settings.notebookBackend = None self.jupyter = False
nc, n = conc.shape # nc= nr. of time points, n= nr. of vertices # Create the Plotter instance and position the camera. # (values can be copied in the code by pressing C in the rendering window) vp = Plotter(verbose=0, axes=0, interactive=0, size=(700, 700)) vp.camera.SetPosition(962, -239, 1034) vp.camera.SetFocalPoint(0.0, 0.0, 10.0) vp.camera.SetViewUp(-0.693, -0.479, 0.539) pb = ProgressBar(0, nc, c='g') # a green progress bar for t1 in pb.range(): # for each time point t2 = t1 + 1 if t1 == nc - 1: t2 = t1 # avoid index overflow with last time point vp.actors = [] # clean up the list of actors at each iteration vp.add(cylinder([0, 0, -15], r=260, height=10, texture='marble', res=60)) vp.add(cylinder([0, 0, 10], r=260, height=50, wire=1, c='gray', res=60)) pts, cols = [], [] for i, p in enumerate(mesh): # for each vertex in the mesh c1, c2 = conc[t1, i], conc[t2, i] cgrad = abs(c2 - c1) * cgradfac # intensity of variation gx, gy, gz = np.random.randn(3) # make points wiggle a bit pts.append(p + vector(gx / 4, gy / 4, gz + c1 * 20)) cols.append([0., c1, cgrad]) # RGB color vp.points(pts, c=cols, alpha=1.0, r=6) # points actor vp.points(pts, c=cols, alpha=0.1, r=30) # halos actor vp.camera.Azimuth(60 / nc) # rotate camera by a fraction vp.show() # show the four new actors at each iteration pb.print()
""" Make a textured floor, a lamp post, and load a mesh of a car make copies of the car, rotate and move them in a loop. rate=10 limits the speed of the loop to maximum 10 fps """ from __future__ import division, print_function from vtkplotter import Plotter, Plane, Text, datadir vp = Plotter(interactive=0, axes=0) vp.add(Plane(pos=(4, 0, -0.45), sx=12, texture="metalfloor1")) # load and set its position (methods can be concatenated) vp.load(datadir + "lamp.vtk").pos([1.7, -0.4, 2]) a = vp.load(datadir + "porsche.ply", c="r").rotateX(90) a.normalize() # set actor at origin and scale size to 1 for i in range(1, 10): b = a.clone().color("aqua").alpha(0.04 * i) b.rotateX(-20 * i).rotateY(-10 * i).pos([i, i / 2, i / 2]) vp.add(b) # add actor b vp.show(rate=10) # maximum frame rate in hertz print(i, "time:", vp.clock, "s") vp.add(Text(__doc__)) vp.show(interactive=1)
to add a sphere and some info is printed. """ from vtkplotter import Plotter, printc, Sphere, Text, datadir ############################################################################## def myfnc(key): if not vp.clickedActor or key != "c": printc("click an actor and press c.", c="r") return printc("clicked actor :", vp.clickedActor.legend(), c=4) printc("clicked 3D point:", vp.picked3d, c=4) printc("clicked renderer:", [vp.renderer], c=2) vp.add(Sphere(pos=vp.picked3d, r=0.005, c="v")) vp.show() ############################################################################## vp = Plotter(verbose=0) vp.keyPressFunction = myfnc # make it known to Plotter class vp.load(datadir + "bunny.obj") vp.add(Text(__doc__)) printc("\nPress c to execute myfnc()", c=1) vp.show()
Green histogram is the distribution of residuals from the fitting. Red histogram is the distribution of the curvatures (1/r**2). Fitted radius can be accessed from actor.info['radius']. ''' from __future__ import division, print_function from vtkplotter import Plotter, fitSphere, histogram, Points, Line, Text vp = Plotter(verbose=0, axes=0) # load mesh and increase by a lot (N=2) the nr of surface vertices s = vp.load('data/shapes/cow.vtk').alpha(0.3).subdivide(N=2) reds, invr = [], [] for i, p in enumerate(s.coordinates()): if i%1000: continue # skip most points pts = s.closestPoint(p, N=16) # find the N closest points to p sph = fitSphere(pts).alpha(0.05) # find the fitting sphere if sph is None: continue # may fail if all points sit on a plane vp.add(sph) vp.add(Points(pts)) vp.add(Line(sph.info['center'], p, lw=2)) reds.append(sph.info['residue']) invr.append(1/sph.info['radius']**2) vp.add(histogram(reds, title='residue', bins=12, c='g', corner=3)) vp.add(histogram(invr, title='1/r**2', bins=12, c='r', corner=4)) vp.add(Text(__doc__)) vp.show(viewup='z')
''' Draw the PCA (Principal Component Analysis) ellipsoid that contains 50% of a cloud of Points, then check if points are inside the surface. Extra info is stored in actor.info['sphericity'], 'va', 'vb', 'vc'. ''' from vtkplotter import Plotter, pcaEllipsoid, Points, Text import numpy as np vp = Plotter(verbose=0, axes=4) pts = np.random.randn(500, 3) # random gaussian point cloud act = pcaEllipsoid(pts, pvalue=0.5, pcaAxes=1) ipts = act.getActor(0).insidePoints(pts) # act is a vtkAssembly opts = act.getActor(0).insidePoints(pts, invert=True) vp.add(Points(ipts, c='g')) vp.add(Points(opts, c='r')) print('inside points #', len(ipts)) print('outside points #', len(opts)) print('sphericity :', act.info['sphericity']) vp.add([act, Text(__doc__)]) vp.show()
''' Normal jpg/png images can be loaded and rendered as any vtkImageActor ''' from vtkplotter import Plotter, Text vp = Plotter(axes=3, verbose=0) for i in range(5): a = vp.load('data/images/dog.jpg') a.scale(1 - i / 10.).alpha(0.8) # image can be scaled in size a.rotateX(20 * i).pos([0, 0, 30 * i]) # (can concatenate methods) vp.add(Text(__doc__, pos=2)) vp.show()
y_eu, v_eu = euler(y_eu, v_eu, t, dt) y_rk, v_rk = rk4(y_rk, v_rk, t, dt) t += dt positions_eu.append(y_eu) # store result of integration positions_rk.append(y_rk) pb.print("Integrate: RK-4 and Euler") #################################################### # Visualize the result #################################################### vp = Plotter(interactive=0, axes=2, bg="w") # choose axes type nr.2 vp.ytitle = "u(x,t)" vp.ztitle = "" # will not draw z axis for i in x: vp.add(Point([i, 0, 0], c="green", r=6)) pts_actors_eu = vp.actors # save a copy of the actors list pts_actors_eu[0].legend = "Euler method" vp.actors = [] # clean up the list for i in x: vp.add(Point([i, 0, 0], c="red", r=6)) pts_actors_rk = vp.actors # save a copy of the actors list pts_actors_rk[0].legend = "Runge-Kutta4" # merge the two lists and set it as the current vtkPlotter actors vp.actors = pts_actors_eu + pts_actors_rk # let's also add a fancy background image from wikipedia vp.load(datadir + "images/wave_wiki.png",
vp = Plotter(axes=8, bg="w") ambient, diffuse, specular = 0.1, 0., 0. specularPower, specularColor = 20, 'white' for i in range(8): s = vp.load(datadir + 'pumpkin.vtk') #.color(i) s.normalize().pos((i % 4) * 2.2, int(i < 4) * 3, 0) #s.phong() #s.gouraud() s.flat() # modify the default with specific values s.lighting('default', ambient, diffuse, specular, specularPower, specularColor) #ambient += 0.125 diffuse += 0.125 specular += 0.125 vp.add(Text(__doc__)) vp.show() print('Adding a light source..') p = (3, 1.5, 3) f = (3, 1.5, 0) vp.addLight(pos=p, focalPoint=f) vp.add(Arrow(p, f, s=0.01, c='gray', alpha=0.2)) vp.show()
class VirtualKeyboard: def __init__(self, songname=''): self.KB = dict() self.vp = None self.rightHand = None self.leftHand = None self.vpRH = None self.vpLH = None self.playsounds = True self.verbose = True self.songname = songname self.t0 = 0 # keep track of how many seconds to play self.dt = 0.1 self.speedfactor = 1 self.engagedfingersR = [False] * 6 # element 0 is dummy self.engagedfingersL = [False] * 6 self.engagedkeysR = [] self.engagedkeysL = [] self.build_keyboard() ####################################################### def makeHandActor(self, f=1): a1, a2, a3, c = (10 * f, 0, 0), (0, 7 * f, 0), (0, 0, 3 * f), (.7, 0.3, 0.3) palm = Ellipsoid(pos=(0, -3, 0), axis1=a1, axis2=a2, axis3=a3, alpha=0.6, c=c) wrist = Box(pos=(0, -9, 0), length=6 * f, width=5, height=2, alpha=0.4, c=c) arm = Assembly([palm, wrist]) self.vp.actors.append(arm) # add actor to internal list f1 = self.vp.add( Cylinder((-2, 1.5, 0), axis=(0, 1, 0), height=5, r=.8 * f, c=c)) f2 = self.vp.add( Cylinder((-1, 3, 0), axis=(0, 1, 0), height=6, r=.7 * f, c=c)) f3 = self.vp.add( Cylinder((0, 4, 0), axis=(0, 1, 0), height=6.2, r=.75 * f, c=c)) f4 = self.vp.add( Cylinder((1, 3.5, 0), axis=(0, 1, 0), height=6.1, r=.7 * f, c=c)) f5 = self.vp.add( Cylinder((2, 2, 0), axis=(0, 1, 0), height=5, r=.6 * f, c=c)) return [arm, f1, f2, f3, f4, f5] def build_RH(self, hand): if self.verbose: print('Building Right Hand..') self.rightHand = hand f = utils.handSizeFactor(hand.size) self.vpRH = self.makeHandActor(f) for limb in self.vpRH: # initial x positions are superseded later limb.x(limb.x() * 2.5) limb.addPos([16.5 * 5 + 1, -7.5, 3]) # vtkplotter < 8.7.1 was addpos() def build_LH(self, hand): ######################### if self.verbose: print('Building Left Hand..') self.leftHand = hand f = utils.handSizeFactor(hand.size) self.vpLH = self.makeHandActor(f) for limb in self.vpLH: limb.x(limb.x() * 2.5) limb.addPos([16.5 * 3 + 1, -7.5, 3]) # vtkplotter < 8.7.1 was addpos() ####################################################### def build_keyboard(self): if self.verbose: print('Building Keyboard..') nts = ("C", "D", "E", "F", "G", "A", "B") tol = 0.12 keybsize = 16.5 # in cm, span of one octave wb = keybsize / 7 nr_octaves = 7 span = nr_octaves * wb * 7 self.vp = Plotter(title='PianoPlayer ' + __version__, axes=0, size=(700, 1400), bg='lb', verbose=0) #wooden top and base self.vp.add( Box(pos=(span / 2 + keybsize, 6, 1), length=span + 1, height=3, width=5).texture('wood5')) #top self.vp.add( Box(pos=(span / 2 + keybsize, 0, -1), length=span + 1, height=1, width=17).texture('wood5')) self.vp.add( Text('PianoPlayer ' + __version__, pos=(18, 5.5, 2), depth=.7, c='w')) self.vp.add( Text('https://github.com/marcomusy/pianoplayer', pos=(105, 4.8, 2), depth=.7, c='w', s=.8)) leggio = self.vp.add( Box(pos=(span / 1.55, 8, 10), length=span / 2, height=span / 8, width=0.08, c=(1, 1, 0.9))) leggio.rotateX(-20) self.vp.add( Text('Playing\n\n' + self.songname, pos=[0, 0, 0], s=1.2, c='k').rotateX(70).pos([49, 7, 9])) for ioct in range(nr_octaves): for ik in range(7): #white keys x = ik * wb + (ioct + 1) * keybsize + wb / 2 tb = self.vp.add( Box(pos=(x, -2, 0), length=wb - tol, height=1, width=12, c='white')) self.KB.update({nts[ik] + str(ioct + 1): tb}) if not nts[ik] in ("E", "B"): #black keys tn = self.vp.add( Box(pos=(x + wb / 2, 0, 1), length=wb * .6, height=1, width=8, c='black')) self.KB.update({nts[ik] + "#" + str(ioct + 1): tn}) self.vp.show(interactive=0) self.vp.camera.Azimuth(4) self.vp.camera.Elevation(-30) ##################################################################### def play(self): printc('Press [0-9] to proceed by one note or for more seconds', c=1) printc('Press Esc to exit.', c=1) self.vp.keyPressFunction = self.runTime # enable observer if self.rightHand: self.engagedkeysR = [False] * len(self.rightHand.noteseq) self.engagedfingersR = [False] * 6 # element 0 is dummy if self.leftHand: self.engagedkeysL = [False] * len(self.leftHand.noteseq) self.engagedfingersL = [False] * 6 t = 0.0 while True: if self.rightHand: self._moveHand(1, t) if self.leftHand: self._moveHand(-1, t) if t > 1000: break t += self.dt # absolute time flows if self.verbose: printc('End of note sequence reached.') self.vp.keyPressFunction = None # disable observer ################################################################### def _moveHand(self, side, t): ############# runs inside play() loop if side == 1: c1, c2 = 'tomato', 'orange' engagedkeys = self.engagedkeysR engagedfingers = self.engagedfingersR H = self.rightHand vpH = self.vpRH else: c1, c2 = 'purple', 'mediumpurple' engagedkeys = self.engagedkeysL engagedfingers = self.engagedfingersL H = self.leftHand vpH = self.vpLH for i, n in enumerate(H.noteseq): ##################### start, stop, f = n.time, n.time + n.duration, n.fingering if isinstance(f, str): continue if f and stop <= t <= stop + self.dt and engagedkeys[ i]: #release key engagedkeys[i] = False engagedfingers[f] = False name = nameof(n) krelease(self.KB[name]) frelease(vpH[f]) self.vp.interactor.Render() for i, n in enumerate(H.noteseq): ##################### start, stop, f = n.time, n.time + n.duration, n.fingering if isinstance(f, str): print('Warning: cannot understand lyrics:', f, 'skip note', i) continue if f and start <= t < stop and not engagedkeys[ i] and not engagedfingers[f]: #press key if i >= len(H.fingerseq): return engagedkeys[i] = True engagedfingers[f] = True name = nameof(n) if t > self.t0 + self.vp.clock: self.t0 = t self.vp.show(zoom=2, interactive=True) for g in [1, 2, 3, 4, 5]: vpH[g].x(side * H.fingerseq[i][g]) vpH[0].x(vpH[3].x() ) # index 0 is arm, put it where middle finger is fpress(vpH[f], c1) kpress(self.KB[name], c2) self.vp.show(zoom=2, interactive=False) if self.verbose: msg = 'meas.' + str(n.measure) + ' t=' + str(round(t, 2)) if side == 1: printc(msg, '\t\t\t\tRH.finger', f, 'hit', name, c='b') else: printc(msg, '\tLH.finger', f, 'hit', name, c='m') if self.playsounds: playSound(n, self.speedfactor) else: time.sleep(n.duration * self.speedfactor) ########################################## def runTime(self, key): secs = [str(i) for i in range(10)] if key not in secs: return printc('Will execute score for ' + key + ' seconds') self.vp.interactive = False self.vp.clock = int(key) self.vp.interactor.ExitCallback()
''' from scipy.interpolate import Rbf, NearestNDInterpolator as Near import numpy as np # np.random.seed(0) # a small set of points for which the scalar is given x, y, z = np.random.rand(3, 20) scals = z # scalar value is just z component # build the interpolator itr = Rbf(x, y, z, scals) # Radial Basis Function interpolator # itr = Near(list(zip(x,y,z)), scals) # Nearest-neighbour interpolator # generate a new set of points t = np.linspace(0, 7, 100) xi, yi, zi = [np.sin(t)/10+.5, np.cos(t)/5+.5, (t-1)/5] # an helix # interpolate scalar values on the new set scalsi = itr(xi, yi, zi) from vtkplotter import Plotter, Points, Text vp = Plotter(verbose=0, bg='w') vp.add(Points([x, y, z], r=10, alpha=0.5)).pointColors(scals) vp.add(Points([xi, yi, zi])).pointColors(scalsi) vp.add(Text(__doc__, pos=1, c='dr')) vp.show(viewup='z')
# In this example we fit a plane to regions of a surface defined by # N points that are closest to a given point of the surface. # For some of these point we show the fitting plane. # Blue points are the N points used for fitting. # Green histogram is the distribution of residuals from the fitting. # Both plane center and normal can be accessed from the # attribute plane.info['center'] and plane.info['normal']. # from vtkplotter import Plotter, fitPlane, histogram, arrow vp = Plotter(verbose=0, axes=0) s = vp.load('data/shapes/cow.vtk').alpha(0.3).subdivide() # remesh variances = [] for i, p in enumerate(s.coordinates()): if i % 100: continue # skip most points pts = s.closestPoint(p, N=12) # find the N closest points to p plane = fitPlane(pts, bc='r', alpha=0.3) # find the fitting plane vp.add(plane) vp.points(pts) # blue points vp.point(p, c='red 0.2') # mark in red the current point cn, v = plane.info['center'], plane.info['normal'] vp.add(arrow(cn, cn + v / 15., c='g')) variances.append(plane.info['variance']) vp.add(histogram(variances, title='variance', c='g')) vp.show(viewup='z')
ListPos.append(PossiblePos[n]) del PossiblePos[n] Pos = np.array(ListPos) # Create an array with all the radius and a list with all the masses Radius = np.concatenate( (np.array([Rb]), np.array([Rs]*(Nsp-1))) ) Mass=[1.0]+[Ms]*(Nsp-1) # Create the initial array of velocities at random with big sphere at rest ListVel=[(0.,0.)] for s in range(1,Nsp): ListVel.append( (Rb*random.uniform(-1,1), Rb*random.uniform(-1,1)) ) Vel = np.array(ListVel) # Create the spheres Spheres = [vp.add(Sphere(pos=(Pos[0][0],Pos[0][1],0), r=Radius[0], c='red'))] for s in range(1,Nsp): a = vp.add(Sphere(pos=(Pos[s][0],Pos[s][1],0), r=Radius[s], c='blue')) Spheres.append(a) vp.add(Grid(sx=screen_w, sy=screen_w)) # Auxiliary variables Id = np.identity(Nsp) Dij = (Radius+Radius[:, np.newaxis])**2 # Matrix Dij=(Ri+Rj)**2 # The main loop pb = ProgressBar(0,2000, c='r') for i in pb.range(): # Update all positions np.add(Pos,Vel*Dt, Pos) # Fast version of Pos = Pos + Vel*Dt
# Draw the PCA (Principal Component Analysis) ellipsoid that contains 50% of # a cloud of points, then check if points are inside the surface. # Extra info is stored in actor.info['sphericity'], 'va', 'vb', 'vc'. # from vtkplotter import Plotter from vtkplotter.analysis import pcaEllipsoid import numpy as np vp = Plotter(verbose=0, axes=4) pts = np.random.randn(500, 3) # random gaussian point cloud act = vp.add(pcaEllipsoid(pts, pvalue=0.5, pcaAxes=1, legend='PCA ellipsoid')) ipts = act.getActor(0).insidePoints(pts) # act is a vtkAssembly opts = act.getActor(0).insidePoints(pts, invert=True) vp.points(ipts, c='g') vp.points(opts, c='r') print('inside points #', len(ipts)) print('outside points #', len(opts)) print('sphericity :', act.info['sphericity']) vp.show()
######################################### # create the slits as a set of individual coherent point-like sources n = 10 # nr of elementary sources in slit (to control precision). slit1 = list(zip([0] * n, arange(0, n) * width / n, [0] * n)) # source points inside slit 1 slit2 = list(slit1 + array([1e-5, 0, 0])) # a shifted copy of slit 1 slits = slit1 + slit2 #slits += list(slit1 + array([-2e-5, 1e-5, 0])) # add an other copy of slit 1 #slits = [(cos(x)*4e-5, sin(x)*4e-5, 0) for x in arange(0,2*pi, .1)] # Arago spot #slits = grid(sx=1e-4, sy=1e-4, resx=9, resy=9).coordinates() # a square lattice vp = Plotter(title='The Double Slit Experiment', axes=0, verbose=0, bg='black') screen = vp.add(grid(pos=[0, 0, -D], sx=0.1, sy=0.1, resx=200, resy=50)) screen.wire(False) # show it as a solid plane (not as wireframe) k = 0.0 + 1j * 2 * pi / lambda1 # complex wave number norm = len(slits) * 5e+5 amplitudes = [] for i, x in enumerate(screen.coordinates()): psi = 0 for s in slits: r = mag(x - s) psi += exp(k * r) / r psi2 = real(psi * conj(psi)) # psi squared amplitudes.append(psi2) screen.point(i, x + [0, 0, psi2 / norm]) # elevate grid in z
# generate two random sets of points as 2 actors # and align them using the Iterative Closest Point algorithm. # from __future__ import division from random import uniform as u from vtkplotter import Plotter, align, arrow vp = Plotter(shape=[1, 2], verbose=0, axes=2) N1 = 15 # number of points of first set N2 = 15 # number of points of second set x = 1. # add some randomness pts1 = [(u(0, x), u(0, x), u(0, x) + i) for i in range(N1)] pts2 = [(u(0, x) + 3, u(0, x) + i / 2 + 2, u(0, x) + i + 1) for i in range(N2)] act1 = vp.points(pts1, r=8, c='b', legend='source') act2 = vp.points(pts2, r=8, c='r', legend='target') vp.show(at=0) # find best alignment between the 2 sets of points, e.i. find # how to move act1 to best match act2 alpts1 = align(act1, act2).coordinates() vp.points(alpts1, r=8, c='b') for i in range(N1): #draw arrows to see where points end up vp.add(arrow(pts1[i], alpts1[i], c='k', s=0.007, alpha=.1)) vp.show(at=1, interactive=1)
# Create the initial positions and velocitites (0,0) of the bobs bob_x = [0] bob_y = [0] x_dot = [0] * (N + 1) # velocities y_dot = [0] * (N + 1) for k in range(1, N + 1): alpha = np.pi / 5 * k / 10 bob_x.append(bob_x[k - 1] + np.cos(alpha) + np.random.normal(0, 0.1)) bob_y.append(bob_y[k - 1] + np.sin(alpha) + np.random.normal(0, 0.1)) # Create the bobs vp = Plotter(title="Multiple Pendulum", axes=0, interactive=0) vp += Box(pos=(0, -5, 0), length=12, width=12, height=0.7, c="k").wireframe(1) bob = [vp.add(Sphere(pos=(bob_x[0], bob_y[0], 0), r=R / 2, c="gray"))] for k in range(1, N + 1): bob.append( vp.add(Cylinder(pos=(bob_x[k], bob_y[k], 0), r=R, height=0.3, c=k))) # Create the springs out of N links link = [0] * N for k in range(N): p0 = bob[k].pos() p1 = bob[k + 1].pos() link[k] = vp.add(Spring(p0, p1, thickness=0.015, r=R / 3, c="gray")) # Create some auxiliary variables x_dot_m = [0] * (N + 1) y_dot_m = [0] * (N + 1) dij = [0] * (N + 1) # array with distances to previous bob
# from __future__ import division, print_function import numpy as np from vtkplotter import Plotter, fitLine, fitPlane # declare the class instance vp = Plotter(verbose=0, title='linear fitting') # draw 500 fit lines superimposed and very transparent for i in range(500): x = np.linspace(-2, 5, 20) # generate each time 20 points y = np.linspace( 1, 9, 20) z = np.linspace(-5, 3, 20) data = np.array(list(zip(x,y,z))) data+= np.random.normal(size=data.shape)*0.8 # add gauss noise vp.add( fitLine(data, lw=4, alpha=0.03) ) # fit a line # 'data' still contains the last iteration points vp.points(data, r=10, c='red', legend='random points') # the first fitted slope direction is stored # in actor.info['slope] and actor.info['normal] print('Line Fit slope = ', vp.actors[0].info['slope']) plane = vp.add( fitPlane(data, legend='fitting plane') ) # fit a plane print('Plan Fit normal=', plane.info['normal']) vp.show()
vp.ztitle = "" bck = vp.load(datadir+"images/schrod.png", alpha=0.3).scale(0.0255).pos([0, -5, -0.1]) barrier = Line(list(zip(x, V * 15, [0] * len(x))), c="black", lw=2) lines = [] for i in range(0, Nsteps): for j in range(500): Psi += d_dt(Psi) * dt # integrate for a while before showing things A = np.real(Psi * np.conj(Psi)) * 1.5 # psi squared, probability(x) coords = list(zip(x, A, [0] * len(x))) Aline = Line(coords, c="db", lw=3) vp.show([Aline, barrier, bck]) lines.append([Aline, A]) # store objects # now show the same lines along z representing time vp.clear() vp.camera.Elevation(20) vp.camera.Azimuth(20) bck.alpha(1) for i in range(Nsteps): p = [0, 0, size * i / Nsteps] # shift along z l, a = lines[i] # l.pointColors(a, cmap='rainbow') l.pointColors(-a, cmap="gist_earth") # inverted gist_earth vp.add([l.pos(p), barrier.clone().alpha(0.3).pos(p)]) vp.show() vp.show(interactive=1)
# Shrink the triangulation of a mesh to make the inside visible # from vtkplotter import Plotter, sphere vp = Plotter() vp.load('data/shapes/teapot.vtk').shrink(0.75) vp.add(sphere(r=0.2).pos([0,0,-0.5])) vp.show(viewup='z')
RingThickness = 0.3 # thickness of the toroid RingRadius = 1 k = 1.4E-23 # Boltzmann constant T = 300 # room temperature dt = 1.5E-5 ############################################################# def reflection(p, pos): n = norm(pos) return np.dot(np.identity(3) - 2 * n * n[:, np.newaxis], p) vp = Plotter(title='gas in toroid', interactive=0, axes=0, bg='w') vp.add(Text(__doc__)) vp.add(Torus(c='g', r=RingRadius, thickness=RingThickness, alpha=.1).wire(1)) ### <-- Atoms = [] poslist = [] plist, mlist, rlist = [], [], [] mass = Matom * Ratom**3 / Ratom**3 pavg = np.sqrt(2. * mass * 1.5 * k * T) # average kinetic energy p**2/(2mass) = (3/2)kT for i in range(Natoms): alpha = 2 * np.pi * random() x = RingRadius * np.cos(alpha) * .9 y = RingRadius * np.sin(alpha) * .9
width = 10e-6 # slit width in m D = 0.1 # screen distance in m ######################################### # create the slits as a set of individual coherent point-like sources n = 10 # nr of elementary sources in slit (to control precision). slit1 = list(zip([0]*n, arange(0,n)*width/n, [0]*n)) # source points inside slit 1 slit2 = list(slit1 + array([1e-5, 0,0])) # a shifted copy of slit 1 slits = slit1 + slit2 #slits += list(slit1 + array([-2e-5, 1e-5, 0])) # add an other copy of slit 1 #slits = [(cos(x)*4e-5, sin(x)*4e-5, 0) for x in arange(0,2*pi, .1)] # Arago spot #slits = Grid(sx=1e-4, sy=1e-4, resx=9, resy=9).coordinates() # a square lattice vp = Plotter(title='The Double Slit Experiment', axes=0, verbose=0, bg='black') screen = vp.add(Grid(pos=[0,0,-D], sx=0.1, sy=0.1, resx=200, resy=50)) screen.wire(False) # show it as a solid plane (not as wireframe) k = 0.0 + 1j * 2*pi/lambda1 # complex wave number norm = len(slits)*5e+5 amplitudes = [] for i, x in enumerate(screen.coordinates()): psi = 0 for s in slits: r = mag(x-s) psi += exp( k * r )/r psi2 = real( psi * conj(psi) ) # psi squared amplitudes.append(psi2) screen.setPoint(i, x+[0,0, psi2/norm]) # elevate grid in z
and align them using the Iterative Closest Point algorithm. ''' from __future__ import division from random import uniform as u from vtkplotter import Plotter, align, Arrow, Text, Points vp = Plotter(shape=[1, 2], verbose=0, axes=2, bg='w') N1 = 15 # number of points of first set N2 = 15 # number of points of second set x = 1. # add some randomness pts1 = [(u(0, x), u(0, x), u(0, x) + i) for i in range(N1)] pts2 = [(u(0, x) + 3, u(0, x) + i / 2 + 2, u(0, x) + i + 1) for i in range(N2)] act1 = Points(pts1, r=8, c='b').legend('source') act2 = Points(pts2, r=8, c='r').legend('target') vp.show([act1, act2], at=0) # find best alignment between the 2 sets of Points, e.i. find # how to move act1 to best match act2 alpts1 = align(act1, act2).coordinates() vp.add(Points(alpts1, r=8, c='b')) for i in range(N1): # draw arrows to see where points end up vp.add(Arrow(pts1[i], alpts1[i], c='k', s=0.007, alpha=.1)) vp.add(Text(__doc__, c='k')) vp.show(at=1, interactive=1)
ListPos.append(PossiblePos[n]) del PossiblePos[n] Pos = np.array(ListPos) # Create an array with all the radius and a list with all the masses Radius = np.concatenate((np.array([Rb]), np.array([Rs] * (Nsp - 1)))) Mass = [1.0] + [Ms] * (Nsp - 1) # Create the initial array of velocities at random with big sphere at rest ListVel = [(0., 0.)] for s in range(1, Nsp): ListVel.append((Rb * random.uniform(-1, 1), Rb * random.uniform(-1, 1))) Vel = np.array(ListVel) # Create the spheres Spheres = [vp.add(sphere(pos=(Pos[0][0], Pos[0][1], 0), r=Radius[0], c='red'))] for s in range(1, Nsp): a = vp.add(sphere(pos=(Pos[s][0], Pos[s][1], 0), r=Radius[s], c='blue')) Spheres.append(a) vp.add(grid(sx=screen_w, sy=screen_w)) # Auxiliary variables Id = np.identity(Nsp) Dij = (Radius + Radius[:, np.newaxis])**2 # Matrix Dij=(Ri+Rj)**2 # The main loop pb = ProgressBar(0, 2000, c='r') for i in pb.range(): # Update all positions np.add(Pos, Vel * Dt, Pos) # Fast version of Pos = Pos + Vel*Dt
##################################################################################################### if __name__ == "__main__": # An example simulation of N particles scattering on a charged target. # See e.g. https://en.wikipedia.org/wiki/Rutherford_scattering vp = Plotter(title="Particle Simulator", bg="black", axes=0, interactive=False) vp.camera.Elevation(20) # Initial camera position vp.camera.Azimuth(40) vp.add(Cube(c="white").wire(1)) # a wireframe cube sim = ParticleSim(dt=5e-6, iterations=200) sim.add_particle((-0.4, 0, 0), color="w", charge=3e-6, radius=0.01, fixed=True) # the target positions = np.random.randn(500, 3) / 60 # generate a beam of 500 particles for p in positions: p[0] = -0.5 # Fix x position. Their charge are small/negligible compared to target: sim.add_particle(p, charge=0.01e-6, mass=0.1e-6,
# Blue points are the N points used for fitting. # Green histogram is the distribution of residuals from the fitting. # Red histogram is the distribution of the curvatures (1/r**2). # Fitted radius can be accessed from attribute actor.radius from __future__ import division, print_function from vtkplotter import Plotter, fitSphere, histogram, line vp = Plotter(verbose=0, axes=0) # load mesh and increase by a lot (N=2) the nr of surface vertices s = vp.load('data/shapes/cow.vtk').alpha(0.3).subdivide(N=2) reds, invr = [], [] for i, p in enumerate(s.coordinates()): if i%1000: continue # skip most points pts = s.closestPoint(p, N=16) # find the N closest points to p sph = fitSphere(pts, alpha=0.05) # find the fitting sphere if sph is None: continue # may fail if all points sit on a plane vp.add(sph) vp.points(pts) vp.add(line(sph.info['center'], p, lw=2)) reds.append(sph.info['residue']) invr.append(1/sph.info['radius']**2) vp.add(histogram(reds, title='residue', bins=12, c='g', corner=3)) vp.add(histogram(invr, title='1/r**2', bins=12, c='r', corner=4)) vp.show(viewup='z')
Matom = 4E-3/6E23 # helium mass Ratom = 0.025 # wildly exaggerated size of helium atom RingThickness=0.3 # thickness of the toroid RingRadius=1 k = 1.4E-23 # Boltzmann constant T = 300 # room temperature dt = 1E-5 ############################################################# def reflection(p, pos): n = norm(pos) return np.dot(np.identity(3)-2*n*n[:,np.newaxis], p) vp = Plotter(title='gas in toroid', verbose=0, axes=0) vp.add(torus(c='g', r=RingRadius, thickness=RingThickness, alpha=.1, wire=1)) ### <-- Atoms = [] poslist = [] plist, mlist, rlist = [],[],[] mass = Matom*Ratom**3/Ratom**3 pavg = np.sqrt(2.*mass*1.5*k*T) # average kinetic energy p**2/(2mass) = (3/2)kT for i in range(Natoms): alpha = 2*np.pi*random() x = RingRadius*np.cos(alpha)*.9 y = RingRadius*np.sin(alpha)*.9 z = 0 Atoms = Atoms + [vp.add(sphere(pos=(x,y,z), r=Ratom, c=i))] ### <-- theta = np.pi*random() phi = 2*np.pi*random()
from vtkplotter import Plotter, load, Plane, datadir vp = Plotter() cow = vp.load(datadir + "cow.byu", c="grey", alpha=0.7) vp.add(Plane(pos=[0, -3.6, 0], normal=[0, 1, 0], sx=20, texture="grass")) # vp.light() returns a vtkLight object with focal Point, fp, to actor cow # fp can also be explicitly set as fp=[x,y,z] l = vp.light(pos=[-6, 6, 6], fp=cow, deg=12, showsource=1) # can be switched on/off this way # l.SwitchOff() vp.show()