Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中为多边形创建圆角边_Python_Python 3.x_Tkinter_Canvas_Tkinter Canvas - Fatal编程技术网

在Python中为多边形创建圆角边

在Python中为多边形创建圆角边,python,python-3.x,tkinter,canvas,tkinter-canvas,Python,Python 3.x,Tkinter,Canvas,Tkinter Canvas,我遇到了一个有趣的问题(),与在Tkinter中创建圆形矩形有关,特别是Francisco Gomes的回答(稍加修改): def圆形多边形(x,y,锐度): #这里的锐度就是子点之间的距离 #都将到达顶点。越尖锐,, #子点越多,越接近顶点。 #(这不是标准化的) 如果锐度0.5),并且可以参数化 函数make\u round\u corners\u rect返回一个元组,其中包含作为矩形实体片段的所有画布项ID。所有片段都使用其同伴的id进行标记,因此仅使用一个片段id就可以访问整个对象

我遇到了一个有趣的问题(),与在Tkinter中创建圆形矩形有关,特别是Francisco Gomes的回答(稍加修改):

def圆形多边形(x,y,锐度):
#这里的锐度就是子点之间的距离
#都将到达顶点。越尖锐,,
#子点越多,越接近顶点。
#(这不是标准化的)
如果锐度<2:
锐度=2
比率倍增器=锐度-1
比率视差=锐度
#数组来存储点
点数=[]
#在x点上迭代
对于范围内的i(len(x)):
#设置顶点
points.append(x[i])
点。追加(y[i])
#如果这不是最后一点
如果我(len(x)-1):
#插入子多个点。锐度越高,这些点就越多
#靠近顶点。
points.append((比率乘法器*x[i]+x[i+1])/ratioDividend)
points.append((比率乘法器*y[i]+y[i+1])/ratioDividend)
points.append((比率乘法器*x[i+1]+x[i])/ratioDividend)
points.append((比率乘法器*y[i+1]+y[i])/ratioDividend)
其他:
#插入子多个点。
points.append((比率乘法器*x[i]+x[0])/ratioDividend)
points.append((比率乘法器*y[i]+y[0])/ratioDividend)
points.append((比率乘法器*x[0]+x[i])/ratioDividend)
points.append((ratioMultiplier*y[0]+y[i])/ratiovidend)
#闭合多边形
points.append(x[0])
点。追加(y[0])
当我将这段代码改编成我的图形库时,它已经足够好了!但当我创建一个“拉伸正方形”(非正方形矩形)时,圆度也会拉伸:


因此,我如何更改此代码以删除拉伸的圆度并保持其恒定半径?

这里有一种方法使用内置的
tcl tk
基本体
canvas。创建线
,和
canvas。创建弧
以构建各种大小的矩形,以及具有圆角(圆弧)的比例

角半径表示为矩形最短边的比例
(0.0-->0.5)
,并且可以参数化

函数
make\u round\u corners\u rect
返回一个元组,其中包含作为矩形实体片段的所有
画布项ID
。所有片段都使用其同伴的id进行标记,因此仅使用一个片段id就可以访问整个对象




下一步(留给读者作为练习),是将圆形矩形封装在类中


编辑:如何填充圆角矩形:
这有点复杂,从长远来看,可能需要一种方法,即明确定义所有点,并将形状形成多边形,而不是聚合
tkinter
基本体。在此编辑中,圆角矩形由两个重叠矩形和四个圆盘填充;它允许创建填充/未填充的形状,但在创建后不更改该属性-尽管这样做不需要太多的工作。(收集画布ID,并根据需要与
大纲
属性一起打开/关闭画布ID);但是,如前所述,将所有这些行为封装在一个类中,以模仿
tk.canvas.items
的行为,这样做更有意义

def make_round_corners_rect(canvas, x0, y0, x1, y1, ratio=0.2, npts=12, filled=False, fillcolor=''):
    ...
    if filled:
        canvas.create_rectangle(x0+r, y0, x1-r, y1, fill=fillcolor, outline='')
        canvas.create_rectangle(x0, y0+r, x1, y1-r, fill=fillcolor, outline='')
        canvas.create_oval(x0, y0, x0+2*r, y0+2*r, fill=fillcolor, outline='')
        canvas.create_oval(x1-2*r, y0, x1, y0+2*r, fill=fillcolor, outline='')
        canvas.create_oval(x1-2*r, y1-2*r, x1, y1, fill=fillcolor, outline='')
        canvas.create_oval(x0, y1-2*r, x0+2*r, y1, fill=fillcolor, outline='')
    ...

if __name__ == '__main__':
    ...
    TL = 100, 300
    BR = 400, 400
    make_round_corners_rect(canvas, *TL, *BR, ratio=.3, filled=True, fillcolor='cyan')
    ...



谢谢!现在我可能可以把它推广到任何多边形。关于将其封装到类中,这是我一直在做的工作。我会说Tkinter有一个陡峭的学习曲线,所以,在过去的2年里(断断续续),我尝试在Tk之上创建一个库,让一切变得更容易。如果你想看一下的话)不客气,很高兴我能帮上忙。我看过你的lib,这是一个雄心勃勃的项目;你确实做了很多工作。也许你会通过设定优先顺序和集中精力于你想做的事情而获益?是的。我一直在尝试整理一份待办事项清单,现在我的首要任务是测试我已经完成的工作。在为我自己的项目开发它时,我从不费心去测试我没有使用的部分,所以有很多bug。但在未来,我只想让它成为人们可以用来制作非图形化2D游戏和应用程序的东西。与此相关的问题是,我如何用特定的颜色填充圆形矩形?这有点复杂,从长远来看,可能需要一种明确定义所有点的方法,并且形状形成为多边形。我发布了一个编辑,其中矩形由两个重叠的矩形和四个磁盘填充;它允许创建填充/未填充的形状,但在创建后不更改该属性-尽管这样做不需要太多的工作。
#! python3

import math
import tkinter as tk
from tkinter import TclError


def make_round_corners_rect(canvas, x0, y0, x1, y1, ratio=0.2, npts=12):

    if x0 > x1:
        x0, x1 = x1, x0
    if y0 > y1:
        y0, y1 = y1, y0
        
    r = min(x1 - x0, y1 - y0) * ratio
    
    items = []

    topleft = x0, y0
    tld = x0, y0 + r
    tlr = x0 + r, y0
    item = canvas.create_arc(x0, y0, x0+2*r, y0+2*r, start=90, extent=90, fill='', outline='black', style=tk.ARC)
    items.append(item)
    
    top_right = x1, y0
    trl = x1 - r, y0
    trd = x1, y0 + r
    item = canvas.create_line(*tlr, *trl, fill='black')
    items.append(item)
    item = canvas.create_arc(x1-2*r, y0, x1, y0+2*r, start=0, extent=90, fill='', outline='black', style=tk.ARC)
    items.append(item)

    bot_right = x1, y1
    bru = x1, y1 - r
    brl = x1 - r, y1
    item = canvas.create_line(*trd, *bru, fill='black')
    items.append(item)
    item = canvas.create_arc(x1-2*r, y1-2*r, x1, y1, start=270, extent=90, fill='', outline='black', style=tk.ARC)
    items.append(item)

    bot_left = x0, y1
    blr = x0 + r, y1
    blu = x0, y1 - r
    item = canvas.create_line(*brl, *blr, fill='black')
    items.append(item)
    item = canvas.create_arc(x0, y1-2*r, x0+2*r, y1, start=180, extent=90, fill='', outline='black', style=tk.ARC)
    items.append(item)
    item = canvas.create_line(*blu, *tld, fill='black')
    items.append(item)
    
    items = tuple(items)
    print(items)
    
    for item_ in items:
        for _item in items:
            canvas.addtag_withtag(item_, _item)

    return items


if __name__ == '__main__':

    root = tk.Tk()
    canvas = tk.Canvas(root, width=500, height=500)
    canvas.pack(expand=True, fill=tk.BOTH)

    TL = 100, 100
    BR = 400, 200
    make_round_corners_rect(canvas, *TL, *BR)
    
    TL = 100, 300
    BR = 400, 400
    make_round_corners_rect(canvas, *TL, *BR, ratio = .3)

    TL = 300, 50
    BR = 350, 450
    that_rect = make_round_corners_rect(canvas, *TL, *BR, ratio=.4)
    for fragment in that_rect:
        canvas.itemconfig(fragment, width=4)
        try:
            canvas.itemconfig(fragment, outline='blue')
        except TclError:
            canvas.itemconfig(fragment, fill='blue')

    
    TL = 150, 50
    BR = 200, 450
    make_round_corners_rect(canvas, *TL, *BR, ratio=.07)
    
    TL = 30, 30
    BR = 470, 470
    that_rect = make_round_corners_rect(canvas, *TL, *BR, ratio=.3)
    for fragment in that_rect:
        canvas.itemconfig(fragment, dash=(3, 3))
   
    TL = 20, 20
    BR = 480, 480
    make_round_corners_rect(canvas, *TL, *BR, ratio=.1)
    

    root.mainloop()
def make_round_corners_rect(canvas, x0, y0, x1, y1, ratio=0.2, npts=12, filled=False, fillcolor=''):
    ...
    if filled:
        canvas.create_rectangle(x0+r, y0, x1-r, y1, fill=fillcolor, outline='')
        canvas.create_rectangle(x0, y0+r, x1, y1-r, fill=fillcolor, outline='')
        canvas.create_oval(x0, y0, x0+2*r, y0+2*r, fill=fillcolor, outline='')
        canvas.create_oval(x1-2*r, y0, x1, y0+2*r, fill=fillcolor, outline='')
        canvas.create_oval(x1-2*r, y1-2*r, x1, y1, fill=fillcolor, outline='')
        canvas.create_oval(x0, y1-2*r, x0+2*r, y1, fill=fillcolor, outline='')
    ...

if __name__ == '__main__':
    ...
    TL = 100, 300
    BR = 400, 400
    make_round_corners_rect(canvas, *TL, *BR, ratio=.3, filled=True, fillcolor='cyan')
    ...