Home > Enterprise >  In the tkinter environment, display the entered level n and the starting line a (xa, ya) b (xb, yb)
In the tkinter environment, display the entered level n and the starting line a (xa, ya) b (xb, yb)

Time:12-20

I am having a problem solving this problem, I need to create a connection between the L1 label (coordinates n) and for loop (it's marked in code with "n counter" ), so when I select in tkinter window from 0 to 5 and on the click of the button "display" to show a right image of Von Koch snowflake, and a custom starting line a(xa,ya) and b(xb,yb) in python.

from matplotlib import pyplot as plt
import numpy as np
from tkinter import *
import tkinter
 
top = tkinter.Tk()
top.geometry("400x400")
 
L1 = Label(top, text="Coordinates of n")
L1.pack(side=TOP)
L1 = Label(top)
L1.pack( side=TOP)
 
n = StringVar()
n1 = Entry(top,  textvariable=n)
n1.pack(side=TOP)
 
def Nacrtaj():
    class Segment:
        def __init__(self):
            self.x1 = 0
            self.x2 = 0
            self.y1 = 0
            self.y2 = 0
        def display(self):
            x=[self.x1, self.x2]
            y=[self.y1, self.y2]
            plt.axis('equal')
            plt.plot(x,y,"-", lw=0.5, color='k')
        def breakSegment(self, n):
            x=np.zeros(n 1)
            y=np.zeros(n 1)
            dx=(self.x2-self.x1)/n
            dy=(self.y2-self.y1)/n
            for i in range(n 1):
                x[i]=self.x1 dx*i
                y[i]=self.y1 dy*i
            return x,y
 
    def rotation(x, y, phi):
        phi=phi*np.pi/180.
        dx=x[1]-x[0]
        dy=y[1]-y[0]
        xr=x[0] dx*np.cos(phi)-dy*np.sin(phi)
        yr=y[0] dx*np.sin(phi) dy*np.cos(phi)
        return xr, yr
 
    def createSegmentList(x,y):
        list_seg=[]
        for i in range(len(x)-1):
            seg_new=Segment()
            seg_new.x1 = x[i]
            seg_new.y1 = y[i]
            seg_new.x2 = x[i 1]
            seg_new.y2 = y[i 1]
            list_seg.append(seg_new)
        return list_seg
 
    def create_shape(x,y,n):
        x1=np.zeros(len(x) 1)
        y1=np.zeros(len(x) 1)
        x1[:n 1]=x[:n 1]
        y1[:n 1]=y[:n 1]
        x1[n 2:]=x[n 1:]
        y1[n 2:]=y[n 1:]
        x1[n 1], y1[n 1]=rotation([x[n],x[n 1]],[y[n],y[n 1]], 60)
        return x1, y1
 
    A=Segment()
    A.x2=1
    list_seg=[A]
    for j in range(5):   #n counter
        list_new = []
        for i in list_seg:
            x,y=i.breakSegment(3)
            x,y=create_shape(x,y,1)
            list_sub_seg=createSegmentList(x,y)
            for k in list_sub_seg:
                list_new.append(k)
        list_seg=list_new
    for i in list_seg:
        i.display()
 
    A.display()
    plt.show()
 
B1 = Button(top, text="Display", command=Nacrtaj)
B1.pack(side = BOTTOM)
top.mainloop()

CodePudding user response:

If I inderstand problem:

You don't have value in L1 because it is only a Label but in n1 which is Entry and in n which is StringVar assigned to this Entry so you need to get int( n1.get() ) or int( n.get() )

for j in range( int(n.get()) ):

EDIT:

I would add Entry for Ax,Ay,Bx,By directly in main window to put values before clicking Button

And it need also code which gets values after clicking Button

    start_segment = Segment()
    start_segment.x1 = float(entry_ax.get())
    start_segment.y1 = float(entry_ay.get())
    start_segment.x2 = float(entry_bx.get())
    start_segment.y2 = float(entry_by.get())

enter image description here

Full working code:

import tkinter as tk  # PEP8: `import *` is not preferred  
import numpy as np
from matplotlib import pyplot as plt
 
# --- classes ---

class Segment:
    
    def __init__(self):
        self.x1 = 0
        self.x2 = 0
        self.y1 = 0
        self.y2 = 0
        
    def display(self):
        x = [self.x1, self.x2]
        y = [self.y1, self.y2]
        
        plt.axis('equal')
        plt.plot(x, y, "-", lw=0.5, color='k')
        
    def break_segment(self, n):
        x = np.zeros(n 1)
        y = np.zeros(n 1)
        
        dx = (self.x2 - self.x1) / n
        dy = (self.y2 - self.y1) / n
        
        for i in range(n 1):
            x[i] = self.x1   dx * i
            y[i] = self.y1   dy * i
            
        return x, y

# --- functions ---

def rotation(x, y, phi):
    phi = phi*np.pi/180.
    cos_phi = np.cos(phi)
    sin_phi = np.sin(phi)
    dx = x[1] - x[0]
    dy = y[1] - y[0]
    xr = x[0]   dx*cos_phi - dy*sin_phi
    yr = y[0]   dx*sin_phi   dy*cos_phi
    
    return xr, yr

def create_segments(x, y):
    all_segments = []
    
    for i in range(len(x)-1):
        segment = Segment()
        segment.x1 = x[i]
        segment.y1 = y[i]
        segment.x2 = x[i 1]
        segment.y2 = y[i 1]
        all_segments.append(segment)
        
    return all_segments

def create_shape(x, y, n):
    x1 = np.zeros(len(x) 1)
    y1 = np.zeros(len(x) 1)
    x1[:n 1] = x[:n 1]
    y1[:n 1] = y[:n 1]
    x1[n 2:] = x[n 1:]
    y1[n 2:] = y[n 1:]
    x1[n 1], y1[n 1] = rotation([x[n], x[n 1]], [y[n], y[n 1]], 60)
    return x1, y1

def display():

    button['text'] = 'wait'
    top.update()  # force `mainloop` to display new text on button
    
    start_segment = Segment()
    start_segment.x1 = float(entry_ax.get())
    start_segment.y1 = float(entry_ay.get())
    start_segment.x2 = float(entry_bx.get())
    start_segment.y2 = float(entry_by.get())
    
    all_segments = [start_segment]
    
    for j in range( int(entry.get()) ):   #n counter
        new_segments = []
        for segment in all_segments:
            x, y = segment.break_segment(3)
            x, y = create_shape(x, y, 1)
            all_subsegments = create_segments(x, y)
            #for subsegment in all_subsegments:
            #    new_segments.append(subsegment)
            new_segments  = all_subsegments
        all_segments = new_segments

    for segment in all_segments:
        segment.display()
 
    #start_segment.display()
                    
    plt.show()

    button['text'] = 'Display'
    
# --- main ---

top = tk.Tk()
#top.geometry("400x400")
 
label = tk.Label(top, text="Coordinates of n")
label.pack(side='top')
 
entry = tk.Entry(top)
entry.pack(side='top')
entry.insert('end', 2)  # default value at start

# --- frame to create rows using `grid()` ---

frame = tk.Frame(top)
frame.pack()

# --- row 0 ---
 
label_ax = tk.Label(frame, text="ax:")
label_ax.grid(row=0, column=0)
entry_ax = tk.Entry(frame, width=5)
entry_ax.grid(row=0, column=1)
entry_ax.insert('end', 0)  # default value at start

label_ay = tk.Label(frame, text="ay:")
label_ay.grid(row=0, column=2)
entry_ay = tk.Entry(frame, width=5)
entry_ay.grid(row=0, column=3)
entry_ay.insert('end', 0)  # default value at start

# --- row 1 ---

label_bx = tk.Label(frame, text="bx:")
label_bx.grid(row=1, column=0)
entry_bx = tk.Entry(frame, width=5)
entry_bx.grid(row=1, column=1)
entry_bx.insert('end', 1)  # default value at start

label_by = tk.Label(frame, text="by:")
label_by.grid(row=1, column=2)
entry_by = tk.Entry(frame, width=5)
entry_by.grid(row=1, column=3)
entry_by.insert('end', 0)  # default value at start

# ---

button = tk.Button(top, text="Display", command=display)
button.pack(side='bottom')

top.mainloop()

Result for A(0,0) B(1,1):

enter image description here

  • Related