Thread Agnesi - Netter Programmierspaß (4 answers)
Opened by hlubenow at 2014-05-18 01:58

hlubenow
 2014-05-18 17:34
#175563 #175563
User since
2009-02-22
876 Artikel
BenutzerIn
[default_avatar]
So, jetzt geht's doch (immer noch erstmal in Python).
Diesmal habe ich nicht die fertige Formel verwendet, sondern nur "gezeichnet", wie in dem pdf beschrieben.
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/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 = "<Key-space>", func = lambda k: self.pause())
        self.mw.bind(sequence = "<Return>", func = lambda k: self.mw.destroy())
        self.mw.bind(sequence = "<Control-q>", 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()

Hat Spaß gemacht!

View full thread Agnesi - Netter Programmierspaß