#!/usr/bin/python import math import Tkinter as tk # Screen resolution: RESX = 800 RESY = 600 # Zoom-factor and Up/Down-correction: XFAC = 70 XSUM = RESX // 2 YFAC = 60 YSUM = RESY // 2 class AgnesiWindow: def __init__(self): self.mw = tk.Tk() self.mw.option_add("*font", ("Arial", 12, "normal")) self.mw.title("Agnesi") self.mw.geometry("+90+45") self.cv = tk.Canvas(self.mw, bg = "white", width = RESX, height = RESY) self.cv.pack() self.btn = tk.Button(self.mw, text = "Ok", command = self.mw.destroy) self.mw.bind(sequence = "", func = lambda k: self.pause()) self.mw.bind(sequence = "", func = lambda k: self.mw.destroy()) self.mw.bind(sequence = "", func = lambda k: self.mw.destroy()) self.btn.pack(side = tk.RIGHT, padx = 10, pady = 10) self.angle = 130 self.points = {"up" : [math.cos(math.radians(270)), math.sin(math.radians(270))], "down" : [math.cos(math.radians(90)), math.sin(math.radians(90))], "circle" : [math.cos(math.radians(self.angle)), math.sin(math.radians(self.angle))], "upline" : [0, 0], "downline" : [0, 0], "curve" : [0, 0]} self.withdraw = [] self.drawStatic() self.calculatePoints() self.drawDynamic() self.running = -1 self.mw.after(1000, self.run) self.mw.mainloop() def run(self): self.running = 1 self.draw() def pause(self): self.running *= -1 if self.running == 1: self.draw() def getZoom(self, point): return [point[0] * XFAC + XSUM, point[1] * YFAC + YSUM] def plotPoint(self, point): point = self.getZoom(point) self.cv.create_line(point[0], point[1], point[0] + 1, point[1] + 1) def plotDot(self, point, withdraw = False): point = self.getZoom(point) o = self.cv.create_oval(point[0] - 5, point[1] - 5, point[0] + 5, point[1] + 5, fill = 'black') if withdraw: self.withdraw.append(o) def drawLine(self, from_, to_, withdraw = False): from_ = self.getZoom(from_) to_ = self.getZoom(to_) self.withdraw.append(self.cv.create_line(from_[0], from_[1], to_[0], to_[1])) def drawStatic(self): self.cv.create_line(0, self.points["up"][1] * YFAC + YSUM, RESX, self.points["up"][1] * YFAC + YSUM) self.cv.create_line(0, self.points["down"][1] * YFAC + YSUM, RESX, self.points["down"][1] * YFAC + YSUM) self.cv.create_oval((self.points["up"][0] - math.cos(math.radians(0))) * XFAC + XSUM, self.points["up"][1] * YFAC + YSUM, (self.points["up"][0] + math.cos(math.radians(0))) * XFAC + XSUM, self.points["down"][1] * YFAC + YSUM) self.plotDot(self.points["down"], withdraw = False) def drawDynamic(self): self.drawLine(self.points["down"], self.points["upline"]) self.drawLine(self.points["upline"], self.points["downline"]) self.drawLine(self.points["curve"], self.points["circle"]) self.plotDot(self.points["circle"], withdraw = True) self.plotDot(self.points["upline"], withdraw = True) self.plotDot(self.points["downline"], withdraw = True) self.plotDot(self.points["curve"], withdraw = True) self.plotPoint(self.points["curve"]) def calculatePoints(self): self.points["circle"] = [math.cos(math.radians(self.angle)), math.sin(math.radians(self.angle))] # Strahlensatz: d = self.points["up"][1] - self.points["down"][1] a = self.points["circle"][1] - self.points["down"][1] b = self.points["down"][0] - self.points["circle"][0] self.points["upline"] = [self.points["down"][0] - d / a * b, self.points["up"][1]] self.points["downline"] = [self.points["upline"][0], self.points["down"][1]] self.points["curve"] = [self.points["upline"][0], self.points["circle"][1]] def draw(self): if self.running == -1: return if self.angle <= 410: for i in self.withdraw: self.cv.delete(i) self.calculatePoints() self.drawDynamic() self.angle += 1 self.mw.after(50, self.draw) if __name__ == "__main__": app = AgnesiWindow()