Advertisement
Guest User

Untitled

a guest
Feb 26th, 2017
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.75 KB | None | 0 0
  1. from tkinter import *
  2. from tkinter import ttk
  3. from tkinter.messagebox import *
  4. import math
  5.  
  6.  
  7. def draw(event):
  8.     global f_lst, r_lst
  9.  
  10.     a = f_lst.get(0, END)
  11.     b = r_lst.get(0, END)
  12.  
  13.     print(a, b)
  14.     return
  15.     if a is None or b is None:
  16.         showerror('Ошибка', 'Введите точки в формате х,у')
  17.         return
  18.     cnv.delete('all')
  19.  
  20.     cir1, cir2, inter, l1, l2 = calc(a, b)
  21.     if cir1 is None:
  22.         showwarning('Упс', "Окружностей не найдено!")
  23.     else:
  24.         cnv.create_oval((cir1[0][0] - cir1[1]) * scale + dx, (cir1[0][1] + cir1[1]) * scale + dy,
  25.                         (cir1[0][0] + cir1[1]) * scale + dx, (cir1[0][1] - cir1[1]) * scale + dy, fill='#FFF0F5')
  26.  
  27.         cnv.create_oval((cir2[0][0] - cir2[1]) * scale + dx, (cir2[0][1] + cir2[1]) * scale + dy,
  28.                         (cir2[0][0] + cir2[1]) * scale + dx, (cir2[0][1] - cir2[1]) * scale + dy, fill='#E6E6FA')
  29.  
  30.         cnv.create_oval((cir1[0][0] - 0.2) * scale + dx, (cir1[0][1] - 0.2) * scale + dy, (cir1[0][0] + 0.2) * scale + dx,
  31.                         (cir1[0][1] + 0.2) * scale + dy, fil='#DB7093')
  32.  
  33.         cnv.create_oval((cir2[0][0] - 0.2) * scale + dx, (cir2[0][1] - 0.2) * scale + dy,
  34.                         (cir2[0][0] + 0.2) * scale + dx,
  35.                         (cir2[0][1] + 0.2) * scale + dy, fil='#9370DB')
  36.  
  37.         cnv.create_oval((inter[0] - 0.2) * scale + dx, (inter[1] - 0.2) * scale + dy, (inter[0] + 0.2) * scale + dx,
  38.                     (inter[1] + 0.2) * scale + dy, fill="black")
  39.         cnv.create_line(l1[0][0] * scale + dx, l1[0][1] * scale + dy, l1[1][0] * scale + dx, l1[1][1] * scale + dy,
  40.                         width=1, fill="black")
  41.         cnv.create_line(l2[0][0] * scale + dx, l2[0][1] * scale + dy, l2[1][0] * scale + dx, l2[1][1] * scale + dy,
  42.                         width=1, fill="black")
  43.  
  44.     for i in range(len(a)):
  45.         cnv.create_oval((a[i][0] - 0.2) * scale + dx, (a[i][1] - 0.2) * scale + dy, (a[i][0] + 0.2) * scale + dx,
  46.                         (a[i][1] + 0.2) * scale + dy, fill="green")
  47.     for i in range(len(b)):
  48.         cnv.create_oval((b[i][0] - 0.2) * scale + dx, (b[i][1] - 0.2) * scale + dy, (b[i][0] + 0.2) * scale + dx,
  49.                         (b[i][1] + 0.2) * scale + dy, fill="red")
  50.  
  51.  
  52.     tx.delete('1.0', END)
  53.     tx.insert(1.0, "Окружности найдены. \n "
  54.                    "Окружность 1: ее радиус {0:.2f}, координаты центра ({1:.2f}, {2:.2f}) \n"
  55.                    "Окружность 2: ее радиус {3:.2f}, координаты центра ({4:.2f}, {5:.2f}) \n"
  56.                    "Точка пересечения касательных {6:.2f}".format(cir1[1], cir1[0][0], cir1[0][1], cir2[1], cir2[0][0],
  57.                                                            cir2[0][1], inter[0], inter[1]))
  58.  
  59.  
  60. def redraw_max(event):
  61.     global scale, cnv
  62.     scale += 1
  63.     cnv.delete('all')
  64.     draw(event)
  65.  
  66.  
  67. def redraw_min(event):
  68.     global scale, cnv
  69.     scale -= 1
  70.     cnv.delete('all')
  71.     draw(event)
  72.  
  73.  
  74. def to_right(event):
  75.     global dx, cnv
  76.     dx += 10
  77.     cnv.delete('all')
  78.     draw(event)
  79.  
  80.  
  81. def to_left(event):
  82.     global dx, cnv
  83.     dx -= 10
  84.     cnv.delete('all')
  85.     draw(event)
  86.  
  87.  
  88. def to_top(event):
  89.     global dy, cnv
  90.     dy -= 10
  91.     cnv.delete('all')
  92.     draw(event)
  93.  
  94.  
  95. def to_bottom(event):
  96.     global dy, cnv
  97.     dy += 10
  98.     cnv.delete('all')
  99.     draw(event)
  100.  
  101.  
  102. def str_to_float(a):
  103.     if a == '':
  104.         return None
  105.     a = a.split(' ')
  106.     for i in range(len(a)):
  107.         try:
  108.             a[i] = float(a[i])
  109.         except ValueError:
  110.             showwarning('Упс', "Уберите лишние пробелы или добавьте еще одну координату!")
  111.             return None
  112.     return a
  113.  
  114.  
  115. def distance_between_points(xy1, xy2):
  116.     x_1 = xy1[0]
  117.     x_2 = xy2[0]
  118.     y_1 = xy1[1]
  119.     y_2 = xy2[1]
  120.     dis = math.sqrt((x_2 - x_1) ** 2 + (y_2 - y_1) ** 2)
  121.     return dis
  122.  
  123.  
  124. def calc(a, b):
  125.     min_squere = None
  126.     circle1 = None
  127.     circle2 = None
  128.     line1 = None
  129.     line2 = None
  130.     inter_points = None
  131.     for i in range(len(a) - 2):  # первая связка-точка
  132.         for j in range(i + 1, len(a) - 1):  # вторая связка-точка
  133.             for k in range(j + 1, len(a)):  # третья связка-точка
  134.                 res = find_cir(a[i], a[j], a[k])
  135.                 # print(a[i], a[j], a[k], centre_a, rad_a)
  136.                 if res is None:
  137.                     continue
  138.                 else:
  139.                     centre_a = res[0]
  140.                     rad_a = res[1]
  141.  
  142.                 for l in range(len(b) - 2):  # первая связка-точка
  143.                     for m in range(l + 1, len(b) - 1):  # вторая связка-точка
  144.                         for n in range(m + 1, len(b)):  # третья связка-точка
  145.                             res = find_cir(b[l], b[m], b[n])
  146.                             # print(b[i], b[j], b[k], centre_b, rad_b)
  147.                             if res is None:
  148.                                 continue
  149.                             else:
  150.                                 centre_b = res[0]
  151.                                 rad_b = res[1]
  152.  
  153.                             look_dis = distance_between_points(centre_b, centre_a)
  154.                             if look_dis <= rad_a + rad_b:
  155.                                 continue
  156.  
  157.  
  158.  
  159.                             k = rad_a / rad_b # коэфициент подобия
  160.  
  161.                             xm = (centre_a[0] + centre_b[0] * k) / (1 + k)  # точка пересечения касательных
  162.                             ym = (centre_a[1] + centre_b[1] * k) / (1 + k)
  163.  
  164.                             r = math.sqrt(distance_between_points([xm, ym], centre_a) ** 2 - rad_a ** 2)
  165.  
  166.                             d = math.sqrt(math.pow(abs(centre_a[0] - xm), 2) + math.pow(abs(centre_a[1] - ym), 2))  # расстояние между центрами окружностей
  167.                             if d >= r + rad_a:
  168.                                 continue
  169.  
  170.                             aa = (r**2 - rad_a**2 + d**2) / (2*d)  # расстояние от r до точки пересечения линии, соединяющей точки пересечения
  171.                             h = math.sqrt(math.pow(r, 2) - math.pow(aa ,2))  # //расстояние от точки пересеч окружностей до линииб соед т пересеч
  172.  
  173.                             x0 = xm + aa * (centre_a[0] - xm) / d  # точка пересеч линии соединения и линии центров
  174.                             y0 = ym + aa * (centre_a[1] - ym) / d
  175.  
  176.                             up_a = [x0 + h * (centre_a[1] - ym) / d,
  177.                                     y0 - h * (centre_a[0] - xm) / d]
  178.                             down_a = [x0 - h * (centre_a[1] - ym) / d,
  179.                                       y0 + h * (centre_a[0] - xm) / d]
  180.                             #print(up_a, '\n', down_a, '\n')
  181.  
  182.                             # _________________________________________________________________
  183.  
  184.                             r = math.sqrt(distance_between_points([xm, ym], centre_b) ** 2 - rad_b ** 2)
  185.  
  186.                             d = math.sqrt(math.pow(abs(centre_b[0] - xm), 2) + math.pow(abs(centre_b[1] - ym), 2))  # расстояние между центрами окружностей
  187.                             if d >= r + rad_b:
  188.                                 continue
  189.  
  190.                             aa = (r ** 2 - rad_b ** 2 + d ** 2) / (2 * d)  # расстояние от r до точки пересечения линии, соединяющей точки пересечения
  191.                             h = math.sqrt(math.pow(r, 2) - math.pow(aa, 2))  # //расстояние от точки пересеч окружностей до линииб соед т пересеч
  192.  
  193.                             x0 = xm + aa * (centre_b[0] - xm) / d  # точка пересеч линии соединения и линии центров
  194.                             y0 = ym + aa * (centre_b[1] - ym) / d
  195.  
  196.                             up_b = [x0 + h * (centre_b[1] - ym) / d,
  197.                                     y0 - h * (centre_b[0] - xm) / d]
  198.                             down_b = [x0 - h * (centre_b[1] - ym) / d,
  199.                                       y0 + h * (centre_b[0] - xm) / d]
  200.                             #print(up_b, '\n', down_b, '\n')
  201.  
  202.  
  203.                             d1 = distance_between_points(up_a, down_a)
  204.                             d2 = distance_between_points([xm, ym], centre_a)
  205.                             squere1 = (d1 * d2) / 2
  206.                             d1 = distance_between_points(up_b, down_b)
  207.                             d2 = distance_between_points([xm, ym], centre_b)
  208.                             squere2 = (d1 * d2) / 2
  209.                             if min_squere is None or abs(squere1 - squere2) < min_squere:
  210.                                 min_squere = abs(squere1 - squere2)
  211.                                 circle1 = [centre_a, rad_a]
  212.                                 circle2 = [centre_b, rad_b]
  213.                                 line1 = [up_a, up_b]
  214.                                 line2 = [down_b, down_a]
  215.                                 inter_points = [xm, ym]
  216.  
  217.     return circle1, circle2, inter_points, line1, line2
  218.  
  219.  
  220. def find_cir(p1, p2, p3):  # поиск окружности по трем точкам
  221.     x1, y1 = p1[0], p1[1]
  222.     x2, y2 = p2[0], p2[1]
  223.     x3, y3 = p3[0], p3[1]
  224.     if x1 == x2 == x3:  # три точки лежат на одной прямой
  225.         return None
  226.     if x2 == x1:  # случай, когда одна хорда вертикальная, ее коэф = int
  227.         x2, x3 = x3, x2
  228.         y2, y3 = y3, y2
  229.     elif x2 == x3:
  230.         x1, x2 = x2, x1
  231.         y1, y2 = y2, y1
  232.     ma = (y2 - y1) / (x2 - x1)  # наклонный коэф 1-ой хорды
  233.     mb = (y3 - y2) / (x3 - x2)  # накл коэф 2-ой хорды
  234.     if ma != mb:  # прямые совпадают
  235.         x_centre = (ma * mb * (y1 - y3) + mb * (x1 + x2) - ma * (x2 + x3)) / (2 * (mb - ma))
  236.         if ma == 0:
  237.             y_centre = (-1 / mb) * (x_centre - (x2 + x3) / 2) + ((y2 + y3) / 2)
  238.         else:
  239.             y_centre = (-1 / ma) * (x_centre - (x1 + x2) / 2) + ((y1 + y2) / 2)
  240.         radius = distance_between_points([x_centre, y_centre], [x1, y1])
  241.         return [[x_centre, y_centre], radius]
  242.     else:
  243.         return None
  244.  
  245.  
  246. def get_line(p1, p2):
  247.     x1, y1 = p1[0], p1[1]
  248.     x2, y2 = p2[0], p2[1]
  249.     try:
  250.         k = (y1 - y2) / (x1 - x2)
  251.     except ZeroDivisionError:
  252.         return None
  253.     b = y2 - k * x2
  254.     return [k, b]
  255.  
  256.  
  257. def is_tangent(x0, y0, rad, k, v):
  258.     c = x0 ** 2 + v ** 2 - 2 * y0 * v + y0 ** 2 - rad ** 2
  259.     a = k ** 2 + 1
  260.     b = -2 * x0 - 2 * y0 * k + 2 * k * v
  261.     D = b ** 2 - 4 * a * c
  262.     if D != 0:
  263.         return False
  264.     else:
  265.         return True
  266.  
  267.  
  268. def intersection(k1, b1, k2, b2):
  269.     try:
  270.         x = (b2 - b1) / (k1 - k2)
  271.     except ZeroDivisionError:
  272.         return None
  273.     y = k1 * x + b1
  274.     return [x, y]
  275.  
  276.  
  277. def k_comb(n, k):
  278.     assert n > k, "Check values in k_comb!"
  279.     return int(math.factorial(n) / (math.factorial(k) * math.factorial(n - k)))
  280.  
  281.  
  282. def quit_win(event):
  283.     global root, widgets
  284.     root.destroy()
  285.     widgets.destroy()
  286.     navigation.destroy()
  287.  
  288.  
  289. def insert_lst_f(event):
  290.     global f_lst, ent_f
  291.     p = ent_f.get()
  292.     p = str_to_float(p)
  293.     if p is None:
  294.         return
  295.     if len(p) > 2 or len(p) < 2:
  296.         showwarning('Упс', "У точки должно быть всего две координаты!")
  297.         return
  298.     f_lst.insert(END, str(p))
  299.     ent_f.delete(0, END)
  300.  
  301.  
  302. def insert_lst_s(event):
  303.     global r_lst, ent_s
  304.     p = ent_s.get()
  305.     p = str_to_float(p)
  306.     if p is None:
  307.         return
  308.     if len(p) > 2:
  309.         showwarning('Упс', "У точки должно быть всего две координаты!")
  310.         return
  311.     r_lst.insert(END, str(p))
  312.     ent_s.delete(0, END)
  313.  
  314.  
  315. def del_point(event):
  316.     global f_lst, r_lst
  317.     print(f_lst.get(ACTIVE))
  318.     print(r_lst.get(ACTIVE))
  319.  
  320. root = Tk()
  321. root.title("Поле точек")
  322. widgets = Tk()
  323. widgets.title("Инструменты")
  324. navigation = Tk()
  325. navigation.title("Навигация")
  326. root.geometry('700x600')
  327. widgets.wm_geometry("+%d+%d" % (100, 100))
  328. root.wm_geometry("+%d+%d" % (500, 50))
  329. navigation.wm_geometry("+%d+%d" % (100, 350))
  330. r = Tk()
  331.  
  332.  
  333. scale = 9
  334. dx = 10
  335. dy = 10
  336. scale_p = ttk.Button(navigation)
  337. scale_p['text'] = "Увеличить"
  338. scale_m = ttk.Button(navigation)
  339. scale_m['text'] = 'Уменьшить'
  340. right = ttk.Button(navigation)
  341. right['text'] = '〉'
  342. left = ttk.Button(navigation)
  343. left['text'] = '〈'
  344. bottom = ttk.Button(navigation)
  345. bottom['text'] = '﹀'
  346. top = ttk.Button(navigation)
  347. top['text'] = '︿'
  348.  
  349. scrollbar1 = Scrollbar(r)
  350. scrollbar2 = Scrollbar(r)
  351. f_lst = Listbox(r, selectmode=SINGLE, height=10, yscrollcommand=scrollbar1.set)
  352. r_lst = Listbox(r, selectmode=SINGLE, height=10, yscrollcommand=scrollbar2.set)
  353. scrollbar1.config(command=f_lst.yview)
  354. scrollbar2.config(command=r_lst.yview)
  355. lab_f = Label(r, text="Красное можество точек", font="Times 12")
  356. lab_s = Label(r, text="Зеленое можество точек", font="Times 12")
  357. xy_f = Label(r, text='Введите красную точку  ', font="Times 12")
  358. xy_s = Label(r, text='Введите зеленую точку  ', font="Times 12")
  359. ent_f = Entry(r, width=50, bd=3)
  360. ent_s = Entry(r, width=50, bd=3)
  361. but_change = ttk.Button(r)
  362. but_change['text'] = 'Изменить'
  363. but_del = ttk.Button(r)
  364. but_del['text'] = 'Удалить'
  365.  
  366.  
  367. but_answ = ttk.Button(r)
  368. but_answ["text"] = "Отобразить ответ"
  369. but_exit = ttk.Button(r)
  370. but_exit['text'] = 'Выход'
  371.  
  372. ent_f.bind('<Return>', insert_lst_f)
  373. ent_s.bind('<Return>', insert_lst_s)
  374. but_del.bind('<Button-1>', del_point)
  375.  
  376. ent1 = Entry(widgets, width=50, bd=3)
  377. ent2 = Entry(widgets, width=50, bd=3)
  378. tx = Text(root, width=700, height=4, font='Times 12')
  379. ent1.insert(0, '4,6 10,12.34 23.9,12 2,1 6.2,4 4,1')
  380. ent2.insert(0, '23.5,14 8.1,5.1 4,9 23,34 3,4')
  381. lab1 = Label(widgets, text="Первое можество точек:", font="Times 12", highlightcolor='red')
  382. lab2 = Label(widgets, text="Второе можество точек:", font="Times 12", highlightcolor='green')
  383.  
  384.  
  385. cnv = Canvas(root, height=600, width=700, bg='white')
  386. but_answ.bind("<Button-1>", draw)
  387. scale_p.bind('<Button-1>', redraw_max)
  388. scale_m.bind('<Button-1>', redraw_min)
  389. right.bind('<Button-1>', to_right)
  390. left.bind('<Button-1>', to_left)
  391. top.bind('<Button-1>', to_top)
  392. bottom.bind('<Button-1>', to_bottom)
  393. but_exit.bind('<Button-1>', quit_win)
  394.  
  395. f_lst.grid(row=1, column=0, padx=10)
  396. r_lst.grid(row=1, column=1, padx=10)
  397. lab_f.grid(row=0, column=0, padx=5)
  398. lab_s.grid(row=0, column=1, padx=5)
  399. xy_f.grid(row=2, column=0, pady=5)
  400. ent_f.grid(row=2, column=1, pady=5)
  401. xy_s.grid(row=3, column=0, pady=5)
  402. ent_s.grid(row=3, column=1, pady=5)
  403. but_change.grid(row=4, column=0, padx=10, pady=5)
  404. but_del.grid(row=5, column=0, padx=10, pady=5)
  405. but_answ.grid(row=4, column=1, padx=10, pady=5)
  406. but_exit.grid(row=5, column=1, padx=10, pady=5)
  407.  
  408. lab1.pack()
  409. ent1.pack()
  410. ent1.focus_set()
  411. lab2.pack()
  412. tx.pack()
  413. ent2.pack()
  414.  
  415. cnv.pack()
  416.  
  417. scale_p.grid(row=0, column=0, padx=20)
  418. scale_m.grid(row=1, column=0, padx=20, pady=5)
  419. right.grid(row=0, column=1, padx=20)
  420. left.grid(row=1, column=1, padx=20, pady=5)
  421. top.grid(row=0, column=2, padx=20)
  422. bottom.grid(row=1, column=2, padx=20, pady=5)
  423.  
  424. r.mainloop()
  425. root.mainloop()
  426. widgets.mainloop()
  427. navigation.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement