def __init__(self, width=600, height=600, value_range_min=0, value_range_max=1): print(GLSL_PATH) self.value_range = (value_range_min, value_range_max) self._canvas = app.Canvas(size=(width, height), position=(0, 0), keys='interactive', title="ALife book " + self.__class__.__name__) self._canvas.events.draw.connect(self._on_draw) self._canvas.events.resize.connect(self._on_resize) vertex_shader = open( path.join(GLSL_PATH, 'matrix_visualizer_vertex.glsl'), 'r').read() fragment_shader = open( path.join(GLSL_PATH, 'matrix_visualizer_fragment.glsl'), 'r').read() self._render_program = gloo.Program(vertex_shader, fragment_shader) self._render_program['a_position'] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)] self._render_program['a_texcoord'] = [(0, 1), (0, 0), (1, 1), (1, 0)] self._render_program['u_texture'] = np.zeros((1, 1)).astype(np.uint8) self._canvas.show() gloo.set_viewport(0, 0, *self._canvas.physical_size)
def drawShadows( inputFile='/Users/rachel/Downloads/cloud_frac_padded_623_812_70_4096_4096.png', outputFile='/Users/rachel/Downloads/newshadow.png', lightPosition=(20, 0, 0), dataShape=(623, 812, 70), textureShape=(4096, 4096), tileLayout=(6, 5), steps=81, alphaScale=2): ''' Given a tiled data PNG file and a light position, computes the shadows on the data and writes them to a second PNG. @param inputFile: path to the input PNG @type inputFile: string @param outputFile: path to write out the results @type outputFile: string @param lightPosition: position of the point light @type lightPosition: 3-tuple @param dataShape: 3D shape of the data field @type dataShape: 3-tuple @param textureShape: shape of the input image @type textureShape: 2-tuple @param tileLayout: (cols, rows) arrangement of tiles in the input PNG @type tileLayout: 2-tuple @param steps: how many steps to take through the data in calculations @type steps: int @param alphaScale: factor to scale the light absorption @type alphaScale: number ''' width = textureShape[0] height = textureShape[1] c = app.Canvas(show=False, size=(width, height)) cloudTex = getCloudTexture(inputFile, width, height) vertexPath = os.path.join(homeDir, 'shadow_vertex.glsl') fragmentPath = os.path.join(homeDir, 'shadow_frag.glsl') vertex = getShader(vertexPath) fragment = getShader(fragmentPath) program = mkProgram(vertex, fragment, cloudTex, dataShape=dataShape, textureShape=textureShape, tileLayout=tileLayout) setLightPosition(program, lightPosition) setResolution(program, steps, alphaScale) @c.connect def on_draw(event): gloo.clear((1, 1, 1, 1)) program.draw(gl.GL_TRIANGLE_STRIP) im = gloo.util._screenshot((0, 0, c.size[0], c.size[1])) imsave(outputFile, im) c.close() app.run()
def main(): app.Canvas(show=False) cube_faces = unstack_cross( stack_cross(load_envmap(os.path.join(_cubemap_dir, 'yokohama')))) irradiance_map = prefilter_irradiance(cube_faces) plt.imshow( np.vstack((stack_cross(cube_faces), stack_cross(irradiance_map)))) plt.show()
def main(): app.Canvas(show=False) cross = stack_cross(load_envmap(os.path.join(_cubemap_dir, 'yokohama')), format=args.format) plt.imshow(cross) plt.show() plt.imshow(stack_cross(unstack_cross(cross), format='horizontal')) plt.show()
def show_colored_canvas(color): """Show a transient VisPy canvas with a uniform background color.""" from vispy import app, gloo c = app.Canvas() @c.connect def on_draw(e): gloo.clear(color) show_test(c)
def __init__(self, width=600, height=600): self._canvas = app.Canvas(size=(width, height), position=(0,0), keys='interactive', title="ALife book "+self.__class__.__name__) self._canvas.events.draw.connect(self._on_draw) self._canvas.events.resize.connect(self._on_resize) vertex_shader = open(path.join(GLSL_PATH, 'scl_visualizer_vertex.glsl'), 'r').read() fragment_shader = open(path.join(GLSL_PATH, 'scl_visualizer_fragment.glsl'), 'r').read() self._render_program = gloo.Program(vertex_shader, fragment_shader) gloo.set_state('translucent', clear_color='white') self._canvas.show() gloo.set_viewport(0, 0, *self._canvas.physical_size)
def _create_canvas(): """Create a VisPy canvas with a color background.""" from vispy import app c = app.Canvas() c.color = _random_color() @c.connect def on_draw(e): # pragma: no cover c.context.clear(c.color) return c
def __init__(self, point_function, dt_coeff, width=900, height=900): self.point_function = point_function self.dt_coeff = dt_coeff vertex =""" attribute vec3 circle; void main(void) { gl_Position = vec4(circle[0], circle[1], 0.0, 1.0); gl_PointSize = 2.0*(circle[2]); } """ fragment = """ void main(void) { float distance = length(vec2(0.5, 0.5) - gl_PointCoord); if (distance <= 0.5) gl_FragColor = vec4(1, 1, 1, 1); else discard; } """ program = gloo.Program(vertex, fragment) c = app.Canvas(keys='interactive', size=(width, height)) gloo.clear() self.c = c self.prev_tick_time = None @c.connect def on_draw(event): if self.prev_tick_time == None: self.prev_tick_time = time.perf_counter() dt = (time.perf_counter() - self.prev_tick_time) * self.dt_coeff circles = self.point_function(dt) program['circle'] = circles #~ gloo.clear() program.draw('points') c.update() @c.connect def on_resize(event): gloo.set_viewport(0, 0, *event.size)
def _create_canvas(): """Create a VisPy canvas with a color background.""" c = app.Canvas() c.color = _random_color() @c.connect def on_draw(e): c.context.clear(c.color) @c.connect def on_key_press(e): c.color = _random_color() c.update() return c
def test_error(self): vert = ''' void main() { vec2 xy; error on this line vec2 ab; } ''' frag = 'void main() { glFragColor = vec4(1, 1, 1, 1); }' with app.Canvas() as c: program = Program(vert, frag) try: program._glir.flush(c.context.shared.parser) except Exception as err: assert_in('error on this line', str(err)) else: raise Exception("Compile program should have failed.")
def __init__(self, nrows=1, ncols=1, samples=1000, colours=None): self.no_rows = nrows self.no_cols = ncols self.m = nrows * ncols self.n = samples self.signals = None self.c = app.Canvas(keys='interactive') # Assign colours to each graph if not colours: self.colours = np.repeat(np.random.uniform(size=(self.m, 3), low=.5, high=.9), self.n, axis=0).astype(np.float32) else: self.colours = colours # Create index of graphs self.index = np.c_[ np.repeat(np.repeat(np.arange(self.no_cols), self.no_rows), self.n ), np.repeat(np.tile(np.arange(self.no_rows), self.no_cols), self.n), np.tile(np.arange(self.n), self.m)].astype(np.float32)
def disp_circuit(by_id, *map_to_col_list): canvas = vapp.Canvas(size=(800, 800), keys='interactive', title='Floating Pwn2Win Mask') gloo.set_viewport(0, 0, 800, 800) gloo.set_viewport(0, 0, canvas.size[0], canvas.size[1]) gloo.set_state("translucent", depth_test=False) panzoom = PanZoomTransform(canvas, aspect=1) polys = PolygonCollection("agg", color="local", transform=panzoom) shift = np.zeros((1, 2)) for colmap in map_to_col_list: nshift = np.zeros((1, 2)) minp = np.zeros((1, 2)) for entry in by_id.values(): if entry.box.empty(): continue if entry.nodisplay: continue key = entry.idx if not key in colmap: continue points = np.concatenate((entry.box.poly() / 1e5 + shift, np.zeros((4, 1))), axis=1) nshift = np.maximum(nshift, np.amax(points, axis=0)[:2]) minp = np.minimum(minp, np.amin(points, axis=0)[:2]) polys.append(points, color=colmap[key].rgba) shift = (nshift - minp) * 1.1 shift[0, 1] = 0 polys.update.connect(canvas.update) @canvas.connect def on_draw(e): gloo.clear('white') polys.draw() @canvas.connect def on_resize(event): width, height = event.size gloo.set_viewport(0, 0, width, height) canvas.show() vapp.run()
#!/usr/bin/env python # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2014, Vispy Development Team. # Distributed under the (new) BSD License. See LICENSE.txt for more info. # ----------------------------------------------------------------------------- import sys from vispy import app from vispy.gloo import clear # app.use_app('pyqt4') # or pyside, glut, pyglet, sdl2, etc. canvas = app.Canvas(size=(512, 512), title = "Do nothing benchmark (vispy)", keys='interactive') @canvas.connect def on_draw(event): clear(color=True, depth=True) canvas.update() # Draw frames as fast as possible if __name__ == '__main__': canvas.show() canvas.measure_fps() if sys.flags.interactive == 0: app.run()
vec2 center = (floor(texcoord/size) + vec2(0.5,0.5)) * size; texcoord -= center; float theta = M_PI-atan(center.y-iMouse.y, center.x-iMouse.x); float cos_theta = cos(theta); float sin_theta = sin(theta); texcoord = vec2(cos_theta*texcoord.x - sin_theta*texcoord.y, sin_theta*texcoord.x + cos_theta*texcoord.y); float d = arrow_stealth(texcoord, body, 0.25*body, linewidth, antialias); gl_FragColor = filled(d, linewidth, antialias, vec4(0,0,0,1)); } """ canvas = app.Canvas(size=(2 * 512, 2 * 512), keys='interactive') canvas.context.set_state(blend=True, blend_func=('src_alpha', 'one_minus_src_alpha'), blend_equation='func_add') @canvas.connect def on_draw(event): gloo.clear('white') program.draw('triangle_strip') @canvas.connect def on_resize(event): program["iResolution"] = event.size gloo.set_viewport(0, 0, event.size[0], event.size[1])
# pylint: disable=invalid-name, no-member, unused-argument """ basic demo using shaders http://ipython-books.github.io/featured-06/ """ import numpy as np from vispy import app, gloo # In order to display a window, we need to create a Canvas. c = app.Canvas(size=(800, 400), keys='interactive') # When using vispy.gloo, we need to write shaders. # These programs, written in a C-like language called GLSL, # run on the GPU and give us full flexibility for our visualizations. # Here, we create a trivial vertex shader that directly displays # 2D data points (stored in the a_position variable) in the canvas vertex = """ attribute vec2 a_position; void main(void) { gl_Position = vec4(a_position, 0.0, 1.0); } """ # The other shader we need to create is the fragment shader. # It lets us control the pixels' color. fragment = """ void main() { gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); }
#!/usr/bin/env python # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # VisPy - Copyright (c) 2013, Vispy Development Team All rights reserved. # Distributed under the (new) BSD License. See LICENSE.txt for more info. # ----------------------------------------------------------------------------- import time from vispy import app, gl app.use('qt') # app.use('glut') # app.use('pyglet') canvas = app.Canvas(size=(512,512), title = "Do nothing benchmark (vispy)") @canvas.connect def on_paint(event): global t, t0, frames gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) t = time.time() frames = frames + 1 elapsed = (t-t0) # seconds if elapsed > 2.5: print( "FPS : %.2f (%d frames in %.2f second)" % (frames/elapsed, frames, elapsed)) t0, frames = t,0 canvas.update() t0, frames, t = time.time(),0,0 canvas.show()
#! /usr/bin/env python # -*- coding: utf-8 -*- # vispy: testskip import numpy as np from vispy import app, gloo from vispy.geometry import Triangulation from vispy.visuals.collections import PathCollection, TriangleCollection canvas = app.Canvas(size=(800, 800), show=True, keys='interactive') gloo.set_viewport(0, 0, canvas.size[0], canvas.size[1]) gloo.set_state("translucent", depth_test=False) def triangulate(P): n = len(P) S = np.repeat(np.arange(n + 1), 2)[1:-1] S[-2:] = n - 1, 0 S = S.reshape(len(S) // 2, 2) T = Triangulation(P[:, :2], S) T.triangulate() points = T.pts triangles = T.tris.ravel() P = np.zeros((len(points), 3), dtype=np.float32) P[:, :2] = points return P, triangles def star(inner=0.5, outer=1.0, n=5): R = np.array([inner, outer] * n) T = np.linspace(0, 2 * np.pi, 2 * n, endpoint=False)
# ----------------------------------------------------------------------------- # Copyright (c) 2014, Nicolas P. Rougier. All Rights Reserved. # Distributed under the (new) BSD License. # ----------------------------------------------------------------------------- from vispy import app, gloo from vispy.util import load_data_file from vispy.util.svg import Document from vispy.visuals.collections import PathCollection, PolygonCollection from vispy.visuals.transforms import PanZoomTransform path = load_data_file('tiger/tiger.svg') tiger = Document(path) width, height = int(tiger.viewport.width), int(tiger.viewport.height) canvas = app.Canvas(size=(width, height), show=True, keys='interactive') gloo.set_viewport(0, 0, width, height) gloo.set_state("translucent", depth_test=True) panzoom = PanZoomTransform(canvas, aspect=1.0) paths = PathCollection("agg+", linewidth='shared', color="shared", transform=panzoom) polys = PolygonCollection("agg", transform=panzoom) paths.update.connect(canvas.update) z = 0 for path in tiger.paths: for vertices, closed in path.vertices:
#!/usr/bin/env python # -*- coding: utf-8 -*- # vispy: gallery 1 """ Simplest Possible Script ======================== """ import sys from vispy import app, gloo canvas = app.Canvas(keys='interactive') @canvas.connect def on_draw(event): gloo.set_clear_color((0.2, 0.4, 0.6, 1.0)) gloo.clear() canvas.show() if __name__ == '__main__' and sys.flags.interactive == 0: app.run()
import numpy as np from vispy import app, scene from vispy import gloo from vispy import io, plot SIZE = (600, 600) TITLE = 'Physarum Polycephalum' c = app.Canvas(keys='interactive', title=TITLE, size=SIZE) vertex = """ attribute vec2 a_position; void main (void) { gl_Position = vec4(a_position, 0.0, 1.0); } """ fragment = """ void main() { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } """ program = gloo.Program(vertex, fragment) program['a_position'] = np.c_[ np.random.uniform(-0.5, +0.5, 1000).astype(np.float32), np.random.uniform(-0.5, +0.5, 1000).astype(np.float32)] '''''' fname1 = 'teapot.obj' fname2 = 'sphere.obj' fig = plot.Fig() fig[0, 0].mesh(*io.read_mesh(fname1)[:2])
# !/usr/bin/env python # -*- coding: utf-8 -*- """ Probably the simplest vispy example """ import sys from vispy import app, gloo canvas = app.Canvas(show=True, keys='interactive') @canvas.connect def on_draw(event): gloo.set_clear_color((0.2, 0.4, 0.6, 1.0)) gloo.clear() if __name__ == '__main__' and sys.flags.interactive == 0: app.run()
# #!/usr/bin/env python # -*- coding: utf-8 -*- """ Probably the simplest vispy example """ from vispy import app from vispy.gloo import gl c = app.Canvas(show=True) @c.connect def on_paint(event): gl.glClearColor(0.2, 0.4, 0.6, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) if __name__ == '__main__': app.run()
#! /usr/bin/env python # -*- coding: utf-8 -*- # vispy: testskip import numpy as np from vispy import app, gloo from vispy.visuals.collections import SegmentCollection c = app.Canvas(size=(1200, 600), show=True, keys='interactive') gloo.set_viewport(0, 0, c.size[0], c.size[1]) gloo.set_state("translucent", depth_test=False) segments = SegmentCollection("agg", linewidth="local") n = 100 P0 = np.dstack((np.linspace(100, 1100, n), np.ones(n) * 50, np.zeros(n))).reshape(n, 3) P0 = 2 * (P0 / (1200, 600, 1)) - 1 P1 = np.dstack((np.linspace(110, 1110, n), np.ones(n) * 550, np.zeros(n))).reshape(n, 3) P1 = 2 * (P1 / (1200, 600, 1)) - 1 segments.append(P0, P1, linewidth=np.linspace(1, 8, n)) segments['antialias'] = 1 segments['viewport'] = 0, 0, 1200, 600 @c.connect def on_draw(e): gloo.clear('white') segments.draw()
def main(quantity, radius, speed, max_x, max_y, min_x=0, min_y=0): def update_atoms(): def collisions(): def collision(f_i, s_i): f_atom = atom_list[f_i] s_atom = atom_list[s_i] dist = ((f_atom.x - s_atom.x)**2 + (f_atom.y - s_atom.y)**2)**0.5 if dist < radius * 2 and f_i != s_i: co = abs((s_atom.x - f_atom.x) / dist) si = abs((s_atom.y - f_atom.y) / dist) f_atom.s = (f_atom.xs**2 + f_atom.ys**2)**0.5 s_atom.s = (s_atom.xs**2 + s_atom.ys**2)**0.5 if f_atom.x > s_atom.x: f_atom.x += (radius - dist / 2) * si s_atom.x -= (radius - dist / 2) * si f_atom.xs = si * s_atom.s s_atom.xs = -si * f_atom.s else: f_atom.x -= (radius - dist / 2) * si s_atom.x += (radius - dist / 2) * si f_atom.xs = -si * s_atom.s s_atom.xs = si * f_atom.s if f_atom.y > s_atom.y: f_atom.y += (radius - dist / 2) * co s_atom.y -= (radius - dist / 2) * co f_atom.ys = co * s_atom.s s_atom.ys = -co * f_atom.s else: f_atom.y -= (radius - dist / 2) * co s_atom.y += (radius - dist / 2) * co f_atom.ys = -co * s_atom.s s_atom.ys = co * f_atom.s grid = [] non_empty_cells = [] for x in range(int(width / diam) + 2): grid.append([]) for y in range(int(height / diam) + 2): grid[-1].append([]) for i in range(len(atom_list)): grid[int(atom_list[i].x / diam)][int(atom_list[i].y / diam)].append(i) non_empty_cells.append( (int(atom_list[i].x / diam), int(atom_list[i].y / diam))) for x, y in non_empty_cells: others = grid[x][y] + grid[x][y + 1] + grid[x][y - 1] + grid[ x + 1][y] + grid[x + 1][y - 1] + grid[x + 1][y + 1] + grid[ x - 1][y] + grid[x - 1][y - 1] + grid[x - 1][y + 1] for atom_i in grid[x][y]: for other_atom_i in others: collision(atom_i, other_atom_i) def apply_speed(): for atom in atom_list: if atom.x - radius < min_x: atom.x = min_x + radius atom.xs *= -1 elif atom.x + radius > max_x: atom.x = max_x - radius atom.xs *= -1 if atom.y - radius < min_y: atom.y = min_y + radius atom.ys *= -1 elif atom.y + radius > max_y: atom.y = max_y - radius atom.ys *= -1 atom.x += atom.xs atom.y += atom.ys collisions() apply_speed() diam = radius * 2 width = max_x - min_x height = max_y - min_y atom_list = [] for i in range(quantity): angle = uniform(0, 2 * pi) coeff = 1 #uniform(0.5,2) atom_list.append( atom(uniform(min_x + radius, max_x - radius), uniform(min_y + radius, max_y - radius), sin(angle) * speed * coeff, cos(angle) * speed * coeff)) vertex = """ attribute vec2 positions; uniform float radius; void main (void) { gl_Position = vec4(positions, 0.0, 1.0); gl_PointSize = 2.0*(radius); } """ fragment = """ in vec2 gl_PointCoord; void main() { float distance = length(vec2(0.5, 0.5) - gl_PointCoord); if (distance <= 0.5) gl_FragColor = vec4(0, 0, 0, 1); else discard; } """ program = gloo.Program(vertex, fragment) program['radius'] = radius c = app.Canvas(keys='interactive', size=(width, height)) @c.connect def on_draw(event): if play: update_atoms() program['positions'] = [[(atom.x - width / 2) / width * 2, (atom.y - height / 2) / height * 2] for atom in atom_list] gloo.clear((1, 1, 1, 1)) program.draw('points') c.update() @c.connect def on_resize(event): gloo.set_viewport(0, 0, *event.size) @c.connect def on_key_press(event): if event.key == 'space': print(play) play = 0 play = True c.show() app.run()
# set colors of field (actually plot data) rc = 1.-np.zeros([num_ran*num_azi,1]) gc = 1.-np.zeros([num_ran*num_azi,1]) bc = 1.-np.zeros([num_ran*num_azi,1]) cidx = (field_flat[field_flat>0.]*255).astype(int) rc[field_flat>0.,0] = zh_map[cidx,0] gc[field_flat>0.,0] = zh_map[cidx,1] bc[field_flat>0.,0] = zh_map[cidx,2] rc = np.tile(rc, (1,nvert)).flatten() gc = np.tile(gc, (1,nvert)).flatten() bc = np.tile(bc, (1,nvert)).flatten() data['color'] = np.stack((rc, gc, bc), axis=1) c = app.Canvas(keys='interactive', size=(800,800)) vertex = """ uniform float scale; uniform vec2 rel_pos; attribute vec3 color; attribute vec2 position; varying vec3 v_color; void main() { gl_Position = vec4((position+rel_pos)*scale, 0.0, 1.0); v_color = color; } """ fragment = """
raise RuntimeError(gl.glGetShaderInfoLog(shader)) return shader def link_shader_program(vertex_shader, fragment_shader): program = gl.glCreateProgram() gl.glAttachShader(program, vertex_shader) gl.glAttachShader(program, fragment_shader) gl.glLinkProgram(program) result = gl.glGetProgramiv(program, gl.GL_LINK_STATUS) if not (result): raise RuntimeError(gl.glGetProgramInfoLog(program)) return program canvas = app.Canvas() @canvas.connect def on_paint(e): paint() def paint(): n = 100 data = np.hstack( (.2 * np.random.randn(n, 2), np.random.rand(n, 4))).astype(np.float32) vs = compile_shader(VS, gl.GL_VERTEX_SHADER) fs = compile_shader(FS, gl.GL_FRAGMENT_SHADER)
if button == 1: self.move(dxy) elif button == 2: center = event.press_event.pos if self._aspect is None: self.zoom(np.exp(dxy * (0.01, -0.01)), center) else: s = dxy[1] * -0.01 self.zoom(np.exp(np.array([s, s])), center) def on_mouse_wheel(self, event): self.zoom(np.exp(event.delta * (0.01, -0.01)), event.pos) canvas = app.Canvas(keys='interactive', size=(900, 600), show=True, title="Visual Canvas") pos = np.random.normal(size=(1000, 2), loc=0, scale=50).astype('float32') pos[0] = [0, 0] # Make a line visual line = LineVisual(pos=pos) line.transforms.canvas = canvas line.transform = STTransform(scale=(2, 1), translate=(20, 20)) panzoom = PanZoomTransform(canvas) line.transforms.scene_transform = panzoom panzoom.changed.connect(lambda ev: canvas.update()) # Attach color filter to all views (current and future) of the visual line.attach(ColorFilter((1, 1, 0.5, 0.7)))
def __init__(self, parent=None): super(GraphHigh, self).__init__(parent) self.canvas = app.Canvas(size=(1800, 600), keys="interactive", show=False) gloo.set_viewport(0, 0, self.canvas.size[0], self.canvas.size[1]) gloo.set_state("translucent", depth_test=False) # self.setObjectName("ThemeWidget") # self.setStyleSheet("QWidget#ThemeWidget{background:transparent;border: 0px;}") # self.canvas.native.setObjectName("ThemeWidget") # self.canvas.native.setStyleSheet("QWidget#ThemeWidget{background:transparent;border: 0px;}") self.filter_signal.connect(self.updateMarkerVisible) vbl = QtWidgets.QVBoxLayout() vbl.setSpacing(0) vbl.setContentsMargins(0, 0, 0, 0) vbl.addWidget(self.canvas.native) self.setLayout(vbl) gloo.clear(color="#231e1f") # gloo.set_state("translucent", depth_test=False,blend=True) self.canvas.show() self.pvertex = """ varying float v_size; varying vec4 v_color; varying float v_linewidth; varying float v_antialias; // Main (hooked) // ------------------------------------ void main (void) { fetch_uniforms(); v_size = size; v_color = color; gl_Position = $transform(vec4(position, 1)); gl_PointSize = size + 2.0 * (1.0 + 1.5*1.0); } """ self.pfragment = """ #include "markers/disc.glsl" #include "antialias/filled.glsl" // Varyings // ------------------------------------ varying float v_size; varying vec4 v_color; // Main // ------------------------------------ void main() { vec2 P = gl_PointCoord.xy - vec2(0.5,0.5); float point_size = v_size + 2. * (1.0 + 1.5*1.0); float distance = marker_disc(P*point_size, v_size); gl_FragColor = filled(distance, 1.0, 1.0, v_color); } """ self.lvertex = """ #include "misc/viewport-NDC.glsl" // Externs // ------------------------------------ // extern vec3 prev; // extern vec3 curr; // extern vec3 next; // extern float id; // extern vec4 color; // extern float antialias; // extern float linewidth; // extern vec4 viewport; // vec4 transform(vec3 position); // Varyings // ------------------------------------ varying float v_antialias; varying float v_linewidth; varying float v_distance; varying vec4 v_color; // Main // ------------------------------------ void main (void) { // This function is externally generated fetch_uniforms(); v_linewidth = linewidth; v_antialias = antialias; v_color = color; // transform prev/curr/next vec4 prev_ = $transform(vec4(prev, 1)); vec4 curr_ = $transform(vec4(curr, 1)); vec4 next_ = $transform(vec4(next, 1)); // prev/curr/next in viewport coordinates vec2 _prev = NDC_to_viewport(prev_, viewport.zw); vec2 _curr = NDC_to_viewport(curr_, viewport.zw); vec2 _next = NDC_to_viewport(next_, viewport.zw); // Compute vertex final position (in viewport coordinates) float w = linewidth/2.0 + 1.5*antialias; float z; vec2 P; if( curr == prev) { vec2 v = normalize(_next.xy - _curr.xy); vec2 normal = normalize(vec2(-v.y,v.x)); P = _curr.xy + normal*w*id; } else if (curr == next) { vec2 v = normalize(_curr.xy - _prev.xy); vec2 normal = normalize(vec2(-v.y,v.x)); P = _curr.xy + normal*w*id; } else { vec2 v0 = normalize(_curr.xy - _prev.xy); vec2 v1 = normalize(_next.xy - _curr.xy); vec2 normal = normalize(vec2(-v0.y,v0.x)); vec2 tangent = normalize(v0+v1); vec2 miter = vec2(-tangent.y, tangent.x); float l = abs(w / dot(miter,normal)); P = _curr.xy + miter*l*sign(id); } if( abs(id) > 1.5 ) v_color.a = 0.0; v_distance = w*id; gl_Position = viewport_to_NDC(vec3(P, curr_.z/curr_.w), viewport.zw); } """ self.lfragment = """
def main(quantity, radius, speed, max_x, max_y, min_x=0, min_y=0): def update_atoms(): # Finding collisions for (x, y) in non_empty_cells.copy(): other_atoms_i = grid[x][y] | grid[x][y-1] | grid[x+1][y-1] | grid[x+1][y] | grid[x+1][y+1] for atom_i in grid[x][y].copy(): for other_atom_i in other_atoms_i: if atom_i != other_atom_i: collision(atom_list[atom_i], atom_list[other_atom_i], radius) nx, ny = int(atom_list[atom_i].x / diam), int(atom_list[atom_i].y / diam) if (nx, ny) != (x, y): grid[x][y].discard(atom_i) grid[nx][ny].add(atom_i) if (nx, ny) not in non_empty_cells: non_empty_cells.append((nx, ny)) if not grid[x][y]: non_empty_cells.remove((x, y)) # Applying speed for atom in atom_list: if atom.x - radius < min_x: atom.x = min_x + radius atom.xs *= -1 elif atom.x + radius > max_x: atom.x = max_x - radius atom.xs *= -1 if atom.y - radius < min_y: atom.y = min_y + radius atom.ys *= -1 elif atom.y + radius > max_y: atom.y = max_y - radius atom.ys *= -1 atom.x += atom.xs atom.y += atom.ys diam = radius * 2 width = max_x - min_x height = max_y - min_y atom_list = [] for i in range(quantity): angle = uniform(0, 2*pi) coeff = uniform(0.5,2) atom_list.append(atom( uniform(min_x + radius, max_x - radius), uniform(min_y + radius, max_y - radius), sin(angle) * speed * coeff, cos(angle) * speed * coeff)) grid = [] for x in range(int(width / diam) + 2): grid.append([]) for y in range(int(height / diam) + 2): grid[-1].append(set()) non_empty_cells = [] for i in range(len(atom_list)): grid[int(atom_list[i].x / diam)][int(atom_list[i].y / diam)].add(i) non_empty_cells.append((int(atom_list[i].x / diam), int(atom_list[i].y / diam))) vertex = """ attribute vec2 positions; uniform float radius; void main () { gl_Position = vec4(positions, 0.0, 1.0); gl_PointSize = 2.0*(radius); } """ fragment = """ in vec2 gl_PointCoord; void main() { float distance = length(vec2(0.5, 0.5) - gl_PointCoord); if (distance <= 0.5) gl_FragColor = vec4(1, 1, 1, 1); else discard; } """ program = gloo.Program(vertex, fragment) program['radius'] = radius c = app.Canvas(keys='interactive', size=(width, height)) @c.connect def on_draw(event): update_atoms() program['positions'] = [[(atom.x - width / 2) / width * 2, (atom.y - height / 2) / height * 2] for atom in atom_list] gloo.clear() program.draw('points') c.update() @c.connect def on_resize(event): gloo.set_viewport(0, 0, *event.size) c.show() app.run()
def main(quantity, radius, speed, max_x, max_y, min_x=0, min_y=0, loops=None): def collision(f_i, s_i): f_atom = atom_list[f_i] s_atom = atom_list[s_i] dist = hypot((f_atom.x - s_atom.x), (f_atom.y - s_atom.y)) if dist < radius * 2 and f_i != s_i: co = abs((s_atom.x - f_atom.x) / dist) si = abs((s_atom.y - f_atom.y) / dist) sphere_dist = radius - dist / 2 f_atom.s = (f_atom.xs**2 + f_atom.ys**2)**0.5 s_atom.s = (s_atom.xs**2 + s_atom.ys**2)**0.5 if f_atom.x > s_atom.x: f_atom.xb += sphere_dist * si s_atom.xb -= sphere_dist * si f_atom.xs = si * s_atom.s s_atom.xs = -si * f_atom.s else: f_atom.xb -= sphere_dist * si s_atom.xb += sphere_dist * si f_atom.xs = -si * s_atom.s s_atom.xs = si * f_atom.s if f_atom.y > s_atom.y: f_atom.yb += sphere_dist * co s_atom.yb -= sphere_dist * co f_atom.ys = co * s_atom.s s_atom.ys = -co * f_atom.s else: f_atom.yb -= sphere_dist * co s_atom.yb += sphere_dist * co f_atom.ys = -co * s_atom.s s_atom.ys = co * f_atom.s def update_atoms(): # Find collisions fcol_t = time.perf_counter() for (x, y) in non_empty_cells: other_atoms_i = grid[x][y] + grid[x][y - 1] + grid[x + 1][ y - 1] + grid[x + 1][y] + grid[x + 1][y + 1] #~ other_atoms_i = (x for cell in (grid[x][y], grid[x][y-1], grid[x+1][y-1], grid[x+1][y], grid[x+1][y+1]) for x in cell) for atom_i in grid[x][y]: for other_atom_i in other_atoms_i: collision(atom_i, other_atom_i) fcol_t = time.perf_counter() - fcol_t # Apply speed aplspd_t = time.perf_counter() for atom in atom_list: if atom.x - radius < min_x: atom.x = min_x + radius atom.xs *= -1 elif atom.x + radius > max_x: atom.x = max_x - radius atom.xs *= -1 if atom.y - radius < min_y: atom.y = min_y + radius atom.ys *= -1 elif atom.y + radius > max_y: atom.y = max_y - radius atom.ys *= -1 atom.x += atom.xs + atom.xb atom.y += atom.ys + atom.yb atom.xb = 0 atom.yb = 0 aplspd_t = time.perf_counter() - aplspd_t # Update grid updgrd_t = time.perf_counter() for (x, y) in non_empty_cells.copy(): for atom_i in grid[x][y].copy(): nx, ny = int(atom_list[atom_i].x / diam), int( atom_list[atom_i].y / diam) if (nx, ny) != (x, y): grid[x][y].remove(atom_i) grid[nx][ny].append(atom_i) if (nx, ny) not in non_empty_cells: non_empty_cells.append((nx, ny)) if len(grid[x][y]) == 0: non_empty_cells.remove((x, y)) updgrd_t = time.perf_counter() - updgrd_t # Return time spent return fcol_t, aplspd_t, updgrd_t diam = radius * 2 width = max_x - min_x height = max_y - min_y atom_list = [] for i in range(quantity): angle = uniform(0, 2 * pi) coeff = uniform(0.5, 2) atom_list.append( atom(uniform(min_x + radius, max_x - radius), uniform(min_y + radius, max_y - radius), sin(angle) * speed * coeff, cos(angle) * speed * coeff)) grid = [] for x in range(int(width / diam) + 2): grid.append([]) for y in range(int(height / diam) + 2): grid[-1].append([]) non_empty_cells = [] for i in range(len(atom_list)): x, y = int(atom_list[i].x / diam), int(atom_list[i].y / diam) grid[x][y].append(i) if (x, y) not in non_empty_cells: non_empty_cells.append((x, y)) vertex = """ attribute vec2 positions; uniform float radius; void main(void) { gl_Position = vec4(positions, 0.0, 1.0); gl_PointSize = 2.0*(radius); } """ fragment = """ void main(void) { float distance = length(vec2(0.5, 0.5) - gl_PointCoord); if (distance <= 0.5) gl_FragColor = vec4(1, 1, 1, 1); else discard; } """ program = gloo.Program(vertex, fragment) program['radius'] = radius c = app.Canvas(keys='interactive', size=(width, height)) #~ update_times = [] @c.connect def on_draw(event): #~ nonlocal loops runtime = update_atoms() #~ if loops != None: #~ update_times.append(runtime) #~ loops -= 1 #~ if loops == 0: #~ fcol_t, aplspd_t, updgrd_t = [sum(times) / len(times) for times in zip(*update_times)] #~ print(fcol_t, aplspd_t, updgrd_t) positions = [[(atom.x - width / 2) / width * 2, (atom.y - height / 2) / height * 2] for atom in atom_list] program['positions'] = positions print(positions) gloo.clear() program.draw('points') c.update() @c.connect def on_resize(event): gloo.set_viewport(0, 0, *event.size) c.show() app.run()