Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from tkinter import *
- from tkinter import messagebox as mb
- CANVAS_HEIGHT = 500
- CANVAS_WIDTH = 500
- points = list()
- counter = 0
- scale_const_y = 1
- scale_const_x = 1
- def fill_header():
- Label(info_frame, text='#', relief=SUNKEN, width=5).grid(row=0, column=0)
- Label(info_frame, text='X', relief=SUNKEN, width=5).grid(row=0, column=1)
- Label(info_frame, text='Y', relief=SUNKEN, width=5).grid(row=0, column=2)
- def add_point():
- global counter
- changed = False
- x = entry_x.get()
- y = entry_y.get()
- try:
- float(x), float(y)
- except ValueError:
- mb.messagebox("Неверный тип координат точек.")
- return -1
- for i in range(counter):
- if points[i][0] == float(x) and points[i][1] == float(y):
- mb.showerror("Предупреждение", "Эта точка уже была введена.")
- return -2
- fill_table_row(counter, x, y)
- points.append([float(x), float(y)])
- max_x = points[0][0]
- max_y = points[0][1]
- for point in points[1:]:
- max_x = max_x if max_x > abs(point[0]) else abs(point[0])
- max_y = max_y if max_y > abs(point[1]) else abs(point[1])
- max_x = max(max_x, CANVAS_WIDTH)
- max_y = max(max_y, CANVAS_HEIGHT)
- if float(x) > max_x:
- scale_coords(x=x / max_x)
- changed = True
- if float(y) > max_y:
- scale_coords(y=y / max_y)
- changed = True
- if changed:
- redraw_canvas()
- new_coords = transform_coordinates(float(x), float(y))
- canvas.create_oval(new_coords, new_coords[0] + 2, new_coords[1] + 2, fill='green')
- counter += 1
- def redraw_canvas():
- canvas.delete("all")
- for point in points:
- canvas.create_oval(point, point)
- def find_solution():
- if len(points) < 3:
- mb.showerror("Недостаточно точек для построения решения.")
- return -1
- delta_min = len(points)
- line = None
- for i in range(len(points)):
- for j in range(len(points)):
- delta = 0
- if i != j:
- a = points[i][1] - points[j][1]
- b = points[j][0] - points[i][0]
- c = points[i][0] * points[j][1] - points[j][0] * points[i][1]
- for k in range(len(points)):
- if k != j and k != i:
- if a * points[k][0] + b * points[k][1] + c > 0: delta += 1
- elif a * points[k][0] + b * points[k][1] + c < 0: delta -= 1
- if abs(delta) < delta_min:
- delta_min = abs(delta)
- first_point = (- b * CANVAS_WIDTH / 2 - c) / a if a != 0 else points[i][0]
- second_point = ( b * CANVAS_WIDTH / 2 - c) / a if a != 0 else points[j][0]
- line = [transform_coordinates(first_point, CANVAS_HEIGHT / 2),
- transform_coordinates(second_point, - CANVAS_HEIGHT / 2)]
- canvas.delete('line')
- canvas.create_line(line, fill='blue', tag='line')
- def transform_coordinates(x, y):
- x = x + CANVAS_WIDTH // 2
- y = -y + CANVAS_HEIGHT // 2
- return [x, y]
- def scale_coords(scale_x=scale_const_x, scale_y=scale_const_y):
- global points
- scale_const_x = scale_x
- scale_const_y = scale_y
- for point in points:
- points[0] *= scale_x
- points[1] *= scale_y
- def fill_table_row(counter, a, b):
- cols = 3
- table_row = list()
- table_row.append(Label(info_frame,
- text=str(counter + 1),
- relief=SUNKEN,
- width=5))
- table_row.append(Label(info_frame,
- text=a,
- relief=SUNKEN,
- width=5))
- table_row.append(Label(info_frame,
- text=b,
- relief=SUNKEN,
- width=5))
- for j in range(cols):
- table_row[j].grid(row=counter + 1, column=j)
- window = Tk()
- info_frame = Frame(window)
- interface_frame = Frame(window)
- canvas = Canvas(window, width=CANVAS_WIDTH, height=CANVAS_HEIGHT)
- btn_solute = Button(interface_frame,
- text="Найти решение:",
- width=15,
- command=find_solution).pack()
- btn_points = Button(interface_frame,
- text="Добавить точку:",
- width=15,
- command=add_point).pack()
- upper_frame = Frame(interface_frame)
- bottom_frame = Frame(interface_frame)
- label_x = Label(upper_frame, width=6, text='X')
- label_y = Label(upper_frame, width=6, text='Y')
- entry_x = Entry(bottom_frame, width=6)
- entry_y = Entry(bottom_frame, width=6)
- label_x.pack(side=LEFT)
- label_y.pack(side=RIGHT)
- entry_x.pack(side=LEFT)
- entry_y.pack(side=RIGHT)
- upper_frame.pack()
- bottom_frame.pack()
- interface_frame.pack(side=LEFT)
- canvas.pack(side = RIGHT)
- info_frame.pack(side=LEFT)
- fill_header()
- window.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement