def accelerate(self, n): force = (0.0, 0.0) # attraction for m in n.adj: if n == m: continue delta = vec.sub(n.pos, m.pos) force = vec.sub(force, vec.mul(delta, ATTRACTION)) # repulsion for m in self.nodes: if n == m: continue delta = vec.sub(n.pos, m.pos) dist = vec.norm(delta) if dist <= KICK_DIST and id(n) < id(m): angle = random.uniform(0, 2 * math.pi) kick = vec.rotate2d((KICK_SIZE, 0), angle) n.vel = vec.add(n.vel, kick) m.vel = vec.sub(m.vel, kick) dist = max(dist, MIN_CLOSENESS) delta = vec.mul(delta, REPULSION / (dist ** 3)) force = vec.add(force, delta) n.force = force
def move(self, n, dt): if n.static: n.vel = (0.0, 0.0) return n.vel = vec.add(n.vel, vec.mul(n.force, dt / n.mass)) n.vel = vec.mul(n.vel, math.pow(FRICTION, dt)) n.pos = vec.add(n.pos, vec.mul(n.vel, dt))
def in_viewport(self, n): p1 = self.viewport.pos p2 = vec.add(self.viewport.pos, self.get_viewport_dims()) scale = self.viewport.scale xrect = n.style.value.radius * scale yrect = n.style.value.radius * scale return p1[0] <= n.pos[0] + xrect and p2[0] >= n.pos[0] - xrect and \ p1[1] <= n.pos[1] + yrect and p2[1] >= n.pos[1] - yrect
def draw_edge(self, n, m, thickness, colour): z1 = self.project(n.pos) z2 = self.project(m.pos) if thickness <= 1: pygame.draw.aaline(self.screen, colour, z1, z2, 1) else: angle = math.atan2(z2[1] - z1[1], z2[0] - z1[0]) delta = vec.rotate2d((thickness / 2.0, 0), angle) delta = (-delta[0], delta[1]) p1 = vec.add(z1, delta) p2 = vec.sub(z1, delta) p3 = vec.sub(z2, delta) p4 = vec.add(z2, delta) pygame.gfxdraw.aapolygon(self.screen, (p1, p2, p3, p4), colour) pygame.gfxdraw.filled_polygon(self.screen, (p1, p2, p3, p4), colour)
def draw_node(self, n): screen_pos = self.project(n.pos) pygame.draw.circle(self.screen, n.style.value.colour, screen_pos, n.style.value.radius, 0) if not n.style.valid: n.style.cache.text = self.font.render(n.style.value.name, 1, n.style.value.font_colour) n.style.validate() text = n.style.cache.text self.screen.blit( text, vec.add(screen_pos, (-0.5 * text.get_width(), text.get_height() - 7)))
def scale_viewport(self, k, relative): delta = vec.mul(relative, self.viewport.scale) self.viewport.pos = vec.add(self.viewport.pos, vec.mul(delta, 1 - k)) self.viewport.scale *= k
def unproject(self, v): viewport_pos = vec.mul(v, self.viewport.scale) return vec.add(viewport_pos, self.viewport.pos)