class GraphicsScreen(pygame.Surface): def __init__(self, size, buttons): pygame.Surface.__init__(self, size) self.size = size self.buttons = buttons self.pointAdding = False self.pinAdding = False self.segmentAdding = False self.segmentAddingStage = 0 self.snapGrid = True self.snapPoint = True self.cartesian = True self.cartesianOrigin = (self.size[0] / 2, self.size[1] / 2) self.cartesianSpacing = 20 self.polar = False self.polarOrigin = (self.size[0] / 2, self.size[1] / 2) self.polarRSpacing = 20 self.polarThetaSpacing = pi / 12 self.buttons["cartesianGrid"].setState(self.cartesian) self.buttons["polarGrid"].setState(self.polar) self.buttons["snapToGrid"].setState(self.snapGrid) self.buttons["snapToPoint"].setState(self.snapPoint) self.origin = self.polarOrigin self.allGeometry = [] self.prevGeometry = [] self.runningGeometry = [] self.runningSimulation = False self.simulationPaused = False def runSimulationStart(self): self.runningGeometry = [] for drawable in self.allGeometry: self.runningGeometry.append(copy(drawable)) self.anim = AnimationPositions() self.runningSimulation = True self.geom = self.anim.dfs( self.diagram, self.anim.find_head(self.diagram), self.traj, self.varList, self.runningGeometry, self.origin ) # for geom in anim.dfs(self.diagram, anim.find_head(self.diagram), self.traj, self.varList, self.runningGeometry, self.origin): # print geom # for node in geom: # print node.__dict__ # self.draw(geom) def simulationFrame(self): if not self.simulationPaused: try: self.runningGeometry = self.geom.next() except: self.buttons["run"].setState(False) self.runningSimulation = False return # print self.runningGeometry # for node in self.runningGeometry: # print node.__dict__ # self.draw(geom) def buttonPressed(self, buttonID): if buttonID == "cartesianGrid": self.cartesian = True self.polar = False self.buttons["cartesianGrid"].setState(True) self.buttons["polarGrid"].setState(False) elif buttonID == "polarGrid": self.cartesian = False self.polar = True self.buttons["cartesianGrid"].setState(False) self.buttons["polarGrid"].setState(True) elif buttonID == "snapToGrid": self.snapGrid = not self.snapGrid self.buttons["snapToGrid"].setState(self.snapGrid) elif buttonID == "snapToPoint": self.snapPoint = not self.snapPoint self.buttons["snapToPoint"].setState(self.snapPoint) elif buttonID == "point": if self.pointAdding: self.pointAdding = False else: self.pointAdding = True self.pinAdding = False self.segmentAdding = False self.buttons["pin"].setState(False) self.buttons["segment"].setState(False) self.buttons["point"].setState(self.pointAdding) elif buttonID == "pin": if self.pinAdding: self.pinAdding = False else: self.pinAdding = True self.segmentAdding = False self.pointAdding = False self.buttons["point"].setState(False) self.buttons["segment"].setState(False) self.buttons["pin"].setState(self.pinAdding) elif buttonID == "segment": if self.segmentAdding: self.segmentAdding = False else: self.segmentAdding = True self.pointAdding = False self.pinAdding = False self.buttons["point"].setState(False) self.buttons["pin"].setState(False) self.buttons["segment"].setState(self.segmentAdding) elif buttonID == "undo": if len(self.allGeometry) > 0: self.allGeometry.pop() elif len(self.prevGeometry) > 0: for geom in self.prevGeometry: self.allGeometry.append(geom) self.prevGeometry = [] self.buttons["undo"].setState(True) elif buttonID == "delete": if len(self.allGeometry) > 0: for geom in self.allGeometry: self.prevGeometry.append(geom) self.allGeometry = [] self.buttons["delete"].setState(True) elif buttonID == "run": if not self.runningSimulation: if len(self.allGeometry) > 0: self.diagram, self.varList, self.angleDict = StaticDrawing.makeDiagram( self.allGeometry, self.origin ) self.traj, tempLag = Driver.drive(self.diagram, self.varList, self.angleDict) frame = DisplayLagrangeWindow(None, "Euler-Lagrange Equations", tempLag) # app.MainLoop() self.runSimulationStart() self.buttons["run"].setState(True) else: if self.simulationPaused: self.simulationPaused = False self.buttons["pause"].setState(False) elif buttonID == "pause": if self.runningSimulation: self.simulationPaused = not self.simulationPaused self.buttons["pause"].setState(self.simulationPaused) elif buttonID == "restart": if self.runningSimulation: self.runningSimulation = False self.buttons["run"].setState(False) self.buttons["pause"].setState(False) def snap(self, x, y, objToSnapTo): snapped = False if self.snapPoint: for geom in self.allGeometry: if isinstance(geom, objToSnapTo): if objToSnapTo == Segment: if self.dist((x, y), (geom.x0, geom.y0)) < 50 and self.dist((x, y), (geom.x1, geom.y1)) < 50: if self.dist((x, y), (geom.x0, geom.y0)) < self.dist((x, y), (geom.x1, geom.y1)): x, y = geom.x0, geom.y0 else: x, y = geom.x1, geom.y1 snapped = True elif self.dist((x, y), (geom.x0, geom.y0)) < 50: x, y = geom.x0, geom.y0 snapped = True elif self.dist((x, y), (geom.x1, geom.y1)) < 50: x, y = geom.x1, geom.y1 snapped = True else: if self.dist((x, y), (geom.x, geom.y)) < 50: x, y = geom.x, geom.y snapped = True if self.snapGrid and not snapped: if self.cartesian: x -= self.cartesianOrigin[0] y -= self.cartesianOrigin[1] x = int(round(float(x) / self.cartesianSpacing) * self.cartesianSpacing) y = int(round(float(y) / self.cartesianSpacing) * self.cartesianSpacing) x += self.cartesianOrigin[0] y += self.cartesianOrigin[1] elif self.polar: r = self.dist((x, y), self.polarOrigin) theta = atan2(y - self.polarOrigin[1], x - self.polarOrigin[0]) r = int(round(float(r) / self.polarRSpacing) * self.polarRSpacing) theta = round(theta / self.polarThetaSpacing) * self.polarThetaSpacing x = int(r * cos(theta)) + self.polarOrigin[0] y = int(r * sin(theta)) + self.polarOrigin[1] return x, y def addPoint(self, x, y): x, y = self.snap(x, y, Segment) newPoint = Point(self, x, y) self.allGeometry.append(newPoint) def addPin(self, x, y): x, y = self.snap(x, y, Segment) newPoint = Point(self, x, y, isFixed=True) self.allGeometry.append(newPoint) def startSegment(self, x, y): x, y = self.snap(x, y, Point) self.currentSegment = Segment(self, x, y, x, y) self.segmentAddingStage = 1 self.allGeometry.append(self.currentSegment) def updateSegment(self, x, y): x, y = self.snap(x, y, Point) self.currentSegment.setX1(x) self.currentSegment.setY1(y) def finishSegment(self, x, y): x, y = self.snap(x, y, Point) self.currentSegment.setX1(x) self.currentSegment.setY1(y) self.segmentAddingStage = 0 del (self.currentSegment) def mousePressed(self, mx, my): if self.pointAdding: self.addPoint(mx, my) elif self.pinAdding: self.addPin(mx, my) elif self.segmentAdding: self.startSegment(mx, my) def mouseReleased(self, mx, my): if self.segmentAdding and self.segmentAddingStage == 1: self.finishSegment(mx, my) def mouseMoved(self, mx, my): if self.segmentAdding and self.segmentAddingStage == 1: self.updateSegment(mx, my) def updateSize(self, size): pygame.Surface.__init__(self, size) self.size = size def dist(self, p1, p2): (x1, y1) = p1 (x2, y2) = p2 return sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) def draw(self, geom=None): if self.runningSimulation: self.simulationFrame() if self.cartesian: pygame.draw.line(self, (0, 0, 0), (self.cartesianOrigin[0], -10000), (self.cartesianOrigin[0], 10000), 3) pygame.draw.line(self, (0, 0, 0), (-10000, self.cartesianOrigin[1]), (10000, self.cartesianOrigin[1]), 3) cur = self.cartesianOrigin[0] + self.cartesianSpacing while cur < self.size[0]: pygame.draw.line(self, (0, 0, 0), (cur, -10000), (cur, 10000), 1) cur += self.cartesianSpacing cur = self.cartesianOrigin[0] - self.cartesianSpacing while cur > 0: pygame.draw.line(self, (0, 0, 0), (cur, -10000), (cur, 10000), 1) cur -= self.cartesianSpacing cur = self.cartesianOrigin[1] + self.cartesianSpacing while cur < self.size[1]: pygame.draw.line(self, (0, 0, 0), (-10000, cur), (10000, cur), 1) cur += self.cartesianSpacing cur = self.cartesianOrigin[1] - self.cartesianSpacing while cur > 0: pygame.draw.line(self, (0, 0, 0), (-10000, cur), (10000, cur), 1) cur -= self.cartesianSpacing elif self.polar: # pygame.draw.line(self, (0,0,0), (self.polarOrigin[0], -10000), (self.polarOrigin[0], 10000), 3) # pygame.draw.line(self, (0,0,0), (-10000, self.polarOrigin[1]), (10000, self.polarOrigin[1]), 3) for i in range(12): angle = pi * i / 12.0 x1 = cos(angle) * -10000 + self.polarOrigin[0] y1 = sin(angle) * -10000 + self.polarOrigin[1] x2 = cos(angle) * 10000 + self.polarOrigin[0] y2 = sin(angle) * 10000 + self.polarOrigin[1] if i == 0 or i == 6: pygame.draw.line(self, (0, 0, 0), (x1, y1), (x2, y2), 3) else: pygame.draw.line(self, (0, 0, 0), (x1, y1), (x2, y2), 1) dist1 = self.dist(self.polarOrigin, (0, 0)) dist2 = self.dist(self.polarOrigin, (self.size[0], 0)) dist3 = self.dist(self.polarOrigin, (0, self.size[1])) dist4 = self.dist(self.polarOrigin, (self.size[0], self.size[1])) dist = max([dist1, dist2, dist3, dist4]) cur = self.polarRSpacing while cur <= dist: pygame.draw.circle(self, (0, 0, 0), self.polarOrigin, cur, 1) cur += self.polarRSpacing segments = [] points = [] if not self.runningSimulation: for drawable in self.allGeometry: if isinstance(drawable, Segment): segments.append(drawable) else: points.append(drawable) for drawable in segments: drawable.draw() for drawable in points: drawable.draw() else: # print "drawing new geom" for drawable in self.runningGeometry: drawable.draw()
class GraphicsScreen(pygame.Surface): def __init__(self, size, buttons): pygame.Surface.__init__(self, size) self.size = size self.buttons = buttons self.pointAdding = False self.segmentAdding = False self.segmentAddingStage = 0 self.snapGrid = True self.snapPoint = True self.cartesian = True self.cartesianOrigin = (self.size[0]/2,self.size[1]/2) self.cartesianSpacing = 20 self.polar = False self.polarOrigin = (self.size[0]/2,self.size[1]/2) self.polarRSpacing = 20 self.polarThetaSpacing = pi/12 self.buttons[0].setState(self.cartesian) self.buttons[1].setState(self.polar) self.buttons[2].setState(self.snapGrid) self.buttons[3].setState(self.snapPoint) self.allGeometry = [] def buttonPressed(self, buttonID): if buttonID == 1: #Cartesian self.cartesian = True self.polar = False self.buttons[0].setState(True) self.buttons[1].setState(False) elif buttonID == 2: #Polar self.cartesian = False self.polar = True self.buttons[0].setState(False) self.buttons[1].setState(True) elif buttonID == 3: #Snap To Grid self.snapGrid = not self.snapGrid self.buttons[2].setState(self.snapGrid) elif buttonID == 4: #Snap To Point self.snapPoint = not self.snapPoint self.buttons[3].setState(self.snapPoint) if buttonID == 8: #Point Adding if self.pointAdding: self.pointAdding = False else: self.pointAdding = True self.segmentAdding = False self.buttons[8].setState(False) self.buttons[7].setState(self.pointAdding) elif buttonID == 9: #Segment Adding if self.segmentAdding: self.segmentAdding = False else: self.segmentAdding = True self.pointAdding = False self.buttons[7].setState(False) self.buttons[8].setState(self.segmentAdding) elif buttonID == 10: #Undo if len(self.allGeometry) > 0: self.allGeometry.pop() self.buttons[9].setState(True) def snap(self, x, y): if self.snapGrid: if self.cartesian: x = int(round(float(x)/self.cartesianSpacing)*self.cartesianSpacing) y = int(round(float(y)/self.cartesianSpacing)*self.cartesianSpacing) elif self.polar: r = self.dist((x,y), self.polarOrigin) theta = atan2(y-self.polarOrigin[1], x-self.polarOrigin[0]) r = int(round(float(r)/self.polarRSpacing)*self.polarRSpacing) theta = round(theta/self.polarThetaSpacing)*self.polarThetaSpacing x = int(r*cos(theta)) + self.polarOrigin[0] y = int(r*sin(theta)) + self.polarOrigin[1] return x, y def addPoint(self, x, y): newPoint = Point(self, x, y) self.allGeometry.append(newPoint) def startSegment(self, x, y): self.currentSegment = Segment(self, x, y, x, y) self.segmentAddingStage = 1 self.allGeometry.append(self.currentSegment) def updateSegment(self, x, y): self.currentSegment.setX1(x) self.currentSegment.setY1(y) def finishSegment(self, x, y): self.currentSegment.setX1(x) self.currentSegment.setY1(y) self.segmentAddingStage = 0 del(self.currentSegment) def mousePressed(self, mx, my): if self.pointAdding: mx, my = self.snap(mx, my) self.addPoint(mx,my) elif self.segmentAdding: mx, my = self.snap(mx, my) self.startSegment(mx, my) def mouseReleased(self, mx, my): if self.segmentAdding and self.segmentAddingStage == 1: mx, my = self.snap(mx, my) self.finishSegment(mx, my) def mouseMoved(self, mx, my): if self.segmentAdding and self.segmentAddingStage == 1: mx, my = self.snap(mx, my) self.updateSegment(mx, my) def doStuff(self): pass def updateSize(self, size): pygame.Surface.__init__(self, size) self.size = size def dist(self, p1, p2): (x1, y1) = p1 (x2, y2) = p2 return sqrt((x1-x2)**2 + (y1-y2)**2) def draw(self): if self.cartesian: pygame.draw.line(self, (0,0,0), (self.cartesianOrigin[0], -10000), (self.cartesianOrigin[0], 10000), 3) pygame.draw.line(self, (0,0,0), (-10000, self.cartesianOrigin[1]), (10000, self.cartesianOrigin[1]), 3) cur = self.cartesianOrigin[0] + self.cartesianSpacing while cur < self.size[0]: pygame.draw.line(self, (0,0,0), (cur, -10000), (cur, 10000), 1) cur += self.cartesianSpacing cur = self.cartesianOrigin[0] - self.cartesianSpacing while cur > 0: pygame.draw.line(self, (0,0,0), (cur, -10000), (cur, 10000), 1) cur -= self.cartesianSpacing cur = self.cartesianOrigin[1] + self.cartesianSpacing while cur < self.size[1]: pygame.draw.line(self, (0,0,0), (-10000, cur), (10000, cur), 1) cur += self.cartesianSpacing cur = self.cartesianOrigin[1] - self.cartesianSpacing while cur > 0: pygame.draw.line(self, (0,0,0), (-10000, cur), (10000, cur), 1) cur -= self.cartesianSpacing elif self.polar: # pygame.draw.line(self, (0,0,0), (self.polarOrigin[0], -10000), (self.polarOrigin[0], 10000), 3) # pygame.draw.line(self, (0,0,0), (-10000, self.polarOrigin[1]), (10000, self.polarOrigin[1]), 3) for i in range(12): angle = pi*i/12.0 x1 = cos(angle)*-10000 + self.polarOrigin[0] y1 = sin(angle)*-10000 + self.polarOrigin[1] x2 = cos(angle)*10000 + self.polarOrigin[0] y2 = sin(angle)*10000 + self.polarOrigin[1] if i==0 or i==6: pygame.draw.line(self, (0,0,0), (x1, y1), (x2, y2), 3) else: pygame.draw.line(self, (0,0,0), (x1, y1), (x2, y2), 1) dist1 = self.dist(self.polarOrigin, (0,0)) dist2 = self.dist(self.polarOrigin, (self.size[0], 0)) dist3 = self.dist(self.polarOrigin, (0, self.size[1])) dist4 = self.dist(self.polarOrigin, (self.size[0], self.size[1])) dist = max([dist1, dist2, dist3, dist4]) cur = self.polarRSpacing while cur <= dist: pygame.draw.circle(self, (0,0,0), self.polarOrigin, cur, 1) cur += self.polarRSpacing for drawable in self.allGeometry: drawable.draw()