Thread Agnesi - Netter Programmierspaß
(4 answers)
Opened by hlubenow at 2014-05-18 01:58
Hi,
gestern gab es ein interessantes Google-Doodle, gif-Animation hier. Das wollte ich mal in Tk (Tkinter) nachmachen. Anleitung zur Mathematik hier. Und ein Video hier. Die Formel für die Kurve scheint zu sein: y = 8 / (4 + x ^ 2). Mein Ansatz in Python (konnt's leider noch nicht nach Perl/Tk übertragen): Code (python): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 #!/usr/bin/python # coding: iso-8859-1 import math import Tkinter from Tkconstants import * # Screen resolution: RESX = 800 RESY = 600 XFAC = 100 XSUM = 400 YFAC = 90 YSUM = 300 class AgnesiWindow: def __init__(self): self.mw = Tkinter.Tk() self.mw.option_add("*font", ("Arial", 12, "normal")) self.mw.title("Agnesi") self.mw.geometry("+90+45") self.cv = Tkinter.Canvas(self.mw, bg = "white", width = RESX, height = RESY) self.cv.pack() self.btn = Tkinter.Button(self.mw, text = "Ok", command = self.mw.destroy) self.btn.bind(sequence = "<Return>", func = self.bindFunc) self.btn.focus() self.btn.pack(side = RIGHT, padx = 10, pady = 10) self.w = 90 self.points = {"up" : [math.cos(math.radians(270)), math.sin(math.radians(270))], "low" : [math.cos(math.radians(90)), math.sin(math.radians(90))], "circle" : [0, 0], "line" : [-3.6, 0]} self.withdraw = [] self.cv.create_line(0, self.points["up"][1] * YFAC + YSUM, 800, self.points["up"][1] * YFAC + YSUM) self.cv.create_line(0, self.points["low"][1] * YFAC + YSUM, 800, self.points["low"][1] * YFAC + YSUM) self.plotDot(self.points["low"], withdraw = False) self.mw.after(1000, self.draw) self.mw.mainloop() def bindFunc(self, a): self.mw.destroy() def plotPoint(self, point): a = [point[0] * XFAC + XSUM, point[1] * YFAC + YSUM] self.cv.create_line(a[0], a[1], a[0] + 1, a[1] + 1) def plotDot(self, point, withdraw = False): a = [point[0] * XFAC + XSUM, point[1] * YFAC + YSUM] if withdraw: self.withdraw.append(self.cv.create_oval(a[0] - 5, a[1] - 5, a[0] + 5, a[1] + 5, fill = 'black')) else: self.cv.create_oval(a[0] - 5, a[1] - 5, a[0] + 5, a[1] + 5, fill = 'black') def drawLine(self, from_, to_, withdraw = False): a = [from_[0] * XFAC + XSUM, from_[1] * YFAC + YSUM] b = [to_[0] * XFAC + XSUM, to_[1] * YFAC + YSUM] if withdraw: self.withdraw.append(self.cv.create_line(a[0], a[1], b[0], b[1])) else: self.cv.create_line(a[0], a[1], b[0], b[1]) def draw(self): if self.w <= 450: for i in self.withdraw: self.cv.delete(i) self.points["circle"] = [math.cos(math.radians(self.w)), math.sin(math.radians(self.w))] self.plotDot(self.points["circle"], withdraw = True) self.plotPoint(self.points["circle"]) self.w += 1 b = math.pow(self.points["line"][0], 2) self.points["line"][1] = 1 - (8. / (4. + b)) self.plotPoint(self.points["line"]) self.plotDot(self.points["line"], withdraw = True) self.plotDot([self.points["line"][0], self.points["up"][1]], withdraw = True) self.drawLine(self.points["low"], [self.points["line"][0], self.points["up"][1]], withdraw = True) self.plotDot([self.points["line"][0], self.points["low"][1]], withdraw = True) self.drawLine([self.points["line"][0], self.points["up"][1]], [self.points["line"][0], self.points["low"][1]], withdraw = True) self.points["line"][0] += 0.02 self.mw.after(50, self.draw) if __name__ == "__main__": app = AgnesiWindow() Sieht schon ganz passabel aus, finde ich, aber da ist noch ein Fehler drin: Der Punkt auf dem Kreis müßte auf Höhe des Punktes auf der Kurve sein (und auf der Linie vom unteren Punkt aus). Das ist er leider nicht. :( Na ja, wenn jemand Zeit und Lust dazu hat, kann er ja versuchen, den Fehler zu finden. Ich habe bisher aber auch mit Probieren "gearbeitet". :) |