def render(self): "Render the vector as an arrow on a pygame.Surface" l = self.length() * self.canvas.unit if l < 2: return Image((1, 1), self.stroke).image shape = self.arrowShape if type(shape) is dict: if shape["fixed"]: shape = shape.copy() shape["width"] /= l shape["head"] /= l del shape["fixed"] a = Arrow(l, **shape).config(fill=self.fill, stroke=self.stroke, weight=self.weight) else: dx, dy = shape cv = Canvas((l, 2 * dy)) y = cv.center[1] cv += Line((0, y), (l, y)).config(stroke=self.stroke, weight=self.weight) cv += Line((l - dx, y - dy), (l, y)).config(stroke=self.stroke, weight=self.weight) cv += Line((l - dx, y + dy), (l, y)).config(stroke=self.stroke, weight=self.weight) a = cv.snapshot() return a.image
def axis(self, x=None, y=None, **kwargs): "Draw coordinate axes" style = {"weight": 2, "stroke": "black"} style.update(kwargs) px = self.px if y is None and len(x) == 4: x, y = x[:2], x[2:] if x: self += Line(px(x[0], 0), px(x[1], 0)).config(**style) if y: self += Line(px(0, y[0]), px(0, y[1])).config(**style) return self
def gridlines(self, lrbt, step=1, axis=None, **kwargs): "Draw gridlines and optional coordinate axes" style = {"weight": 1, "stroke": "lightgrey"} style.update(kwargs) if type(step) in (int, float): dx = dy = step else: dx, dy = step x0, x1, y0, y1 = lrbt px = self.px if dx: x = x0 while x < x1 + dx / 2: self += Line(px(x, y0), px(x, y1)).config(**style) x += dx if dy: while y0 < y1 + dy / 2: self += Line(px(x0, y0), px(x1, y0)).config(**style) y0 += dy return self if axis is None else self.axis(lrbt, **axis)
def drawLot(self): px = self.px self += Line(px(-2.7, 0), px(2.7, 0)).config(weight=10, stroke="blue") attr = dict(stroke="orange", weight=4) for x in range(-2, 3): self += Line(px(x, 2), px(x, 1)).config(**attr) self += Line(px(x, -2), px(x, -1)).config(**attr) self.flatten() img = Circle(0.4 * self.unit).config(fill="grey", weight=0).snapshot() for x in range(-3, 3): self += Sprite(img).config(pos=px(x + 0.5, 2.36), mass=50, drag=0.02, wrap=0) self += Sprite(img).config(pos=px(x + 0.5, -2.37), mass=50, drag=0.02, wrap=0) return self
def _distToWall(pos, angle, sWidth, w, h): "Calculate the distance to the sketch walls in the specified direction" walls = Polygon([(0, 0), (w, 0), (w, h), (0, h)]) w += h pts = [] for n in (-1, 0, 1): v = vec2d(w, angle + n * sWidth) line = Line(pos, vector=v) pts.extend(walls.intersect(line)) return min(dist(pos, pt) for pt in pts) if len(pts) else None
def setup(game): "Create Tic-Tac-Toe board with 100 pixel squares and 20 pixel margins" # Load costumes for X and O sprites, and logo img = Image(resolvePath("img/xo.png", __file__)).tiles(3) game.alien = Image.fromBytes(sc8prData("alien")).config(height=36) # Create and position sprites, one per square for s in range(9): pos = 70 + 100 * (s % 3), 70 + 100 * (s // 3) game += Sprite(img).bind(contains=Graphic.contains, onclick=clickSquare).config(pos=pos, width=100) # Draw the board and start game for pts in [((20,120), (320,120)), ((20,220), (320,220)), ((120,20), (120,320)), ((220,20), (220,320))]: game += Line(*pts) startGame(game)
def setup(self): self.caption = "Electric Force Simulation" w, h = self.size y = h - 40 x = w / 1.5 pivot = x, y - 200 self["string"] = Line(pivot, (x, y)).config(weight=3) self += Charge().config(pos=(x, y)) self["blue"] = QCircle(60).config( fill="blue").snapshot().bind(ondrag).config(pos=(40, y), height=24) self["angle"] = Text().config( pos=pivot, anchor=TOPRIGHT, font=MONO, color="red").config(height=24).bind(ondrag) self += Ruler(self.scale).config(pos=self.center) msg = "Red Sphere\n m = {:.2f} g\n q = {:.0f} nC\n\nBlue Sphere\n q = {:.0f} nC" msg = msg.format(self.mass, 1000 * self.q1, 1000 * self.q2) self += MessageBox(msg, buttons="Close", fontSize=14, font=MONO).bind(ondrag).config(pos=(8, 8), anchor=TOPLEFT)
def __init__(self, scale=10, size=50, step=5, unit=("cm", 2), **cfg): if "bg" not in cfg: cfg["bg"] = Image(bg="#e0e0f0a0") if "weight" not in cfg: cfg["weight"] = 1 coord = lambda x: (x + 1) * scale h = 3.5 * scale super().__init__((coord(size + 1), h)) self.config(**cfg) x = 0 cfg = dict(anchor=BOTTOM, font=MONO, fontStyle=BOLD, color="#000000a0") while x <= size: self += Text(x).config(pos=(coord(x), h - 1), **cfg) x += step if unit: self += Text(unit[0]).config(pos=(coord(unit[1]), h - 1), **cfg) x = 0 while x <= size: s = coord(x) self += Line((s, 0), (s, scale / (2 if x % step else 1))) x += 1 for t in self: if isinstance(t, Text): t.config(height=h / 2) self.bind(ondrag)