如何获取单击位置的圆形图形坐标

2024-10-02 12:25:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我用python创建了一个turtle程序,它在位置(0,0)周围创建了一个色轮。这是一个纸篓:http://pastebin.com/xDyddfwa。我希望能够做的是,能够点击方向盘上的某个地方,然后被告知我点击的颜色围绕圆圈的度数。所以基本上,我想要的是圆坐标,而不是笛卡尔坐标。如果你运行色轮程序,它会提示你输入一个数字。如果输入6,它将绘制一个六色轮子。你会看到红色在底部的右边。我希望能点击它,得到0。如果我点击黄色,我会得到1,等等,我如何将这个值存储到一个变量中。(我在使用onclick()时遇到问题)请帮助。在


Tags: 程序comhttp颜色地方绘制数字turtle
2条回答

onclick()仅当您单击turtle时有效。每次单击时使用onscreenclick(callback)执行函数。它给你(x,y),所以你必须计算angle,然后把角度转换成正确的数字。它并不理想,因为它计算屏幕上每次点击的次数,而不仅仅是颜色。在

import turtle
from turtle import *
import colorsys
import math

def arch(radius, degree, width, colour):
    color(colour)
    pd()
    begin_fill()
    circle(radius, degree)
    lt(90)
    fd(width)
    lt(90)
    circle(-radius+width, degree)
    lt(90)
    fd(width)
    lt(90)
    end_fill()
    pu()
    circle(radius, degree)
    pd()

def start():
    pu()
    rt(90)
    fd(200)
    lt(90)

def startover():
    reset()
    main()

def get_number(x, y):
    # inform function to use global variable
    #global k

    angle = 180 - math.degrees(math.atan2(x,y))

    angle %= 360

    number = int(angle*k/360)

    print('Pos:', x, y, 'Angle:', angle, 'Number:', number)

def main():
    # Inform function to use global variable when you use `=`
    # You will need this value in `get_number
    global k

    s = turtle.Screen()
    #t = turtle.Turtle()

    s.colormode(255)
    tracer(False)

    reset()
    start()

    k = int(numinput(""," How many colors?"))

    colorlist = []

    for i in range(k):
        colorlist.append(list(colorsys.hsv_to_rgb(i/k,1,255)))

    print(colorlist)

    for i in range(len(colorlist)):
        for j in range(len(colorlist[i])):
            colorlist[i][j] = int(colorlist[i][j])
        arch(200, 360/k, 100, (colorlist[i]))

    onkey(startover, "a")
    onscreenclick(get_number)
    #listen()

    done()

if __name__ == "__main__":
    main()

编辑:turtle在后台使用tkinter,而{}功能更强大-即,它具有绘制arcpieslice等功能,并且可以为画布上的每个对象分配鼠标单击。在

^{pr2}$

在effbot.org网站:The Tkinter Canvas Widget

我觉得另一个基于OP代码的答案,在产生错误结果的同时,使问题变得更加复杂。下面是我尝试简化逻辑并生成正确的值(例如,6段HSB圆上的红色为0,黄色为1等)。我将圆旋转90度,以使数学对齐。此外,结果打印在圆的中心:

from turtle import Turtle, Screen
from colorsys import hsv_to_rgb
import math

FONT_SIZE = 18
FONT = ('Arial', FONT_SIZE, 'normal')

RADIUS = 200
WIDTH = 100

last_result = ()  # Also how could I store that value to a variable?

def arch(radius, width, colorlist):

    ''' Creates a color wheel around position (0,0) '''

    degree = 360 / len(colorlist)
    inner_radius = radius - width

    turtle = Turtle(visible=False)
    turtle.penup()
    turtle.setx(radius)
    turtle.setheading(90)

    for color in colorlist:
        turtle.color(color)

        turtle.begin_fill()
        turtle.circle(radius, degree)
        position = turtle.position()
        heading = turtle.heading()
        turtle.left(90)
        turtle.forward(width)
        turtle.left(90)
        turtle.circle(-inner_radius, degree)
        turtle.end_fill()

        turtle.setposition(position)
        turtle.setheading(heading)

def get_number(x, y, turtle, segments):

    '''
    Click somewhere on the wheel, and be told how many degrees around the
    circle the color you clicked. For a six-color wheel, if you click on
    red, you get 0. If you click on yellow, you get 1, etc.
    '''

    global last_result

    if (RADIUS - WIDTH) ** 2 < x ** 2 + y ** 2 < RADIUS ** 2:

        angle = math.degrees(math.atan2(y, x)) % 360

        number = int(angle * segments / 360)

        turtle.undo()
        turtle.write('{} ({:5.1f}\u00b0)'.format(number, angle), align='center', font=FONT)

        last_result = (number, angle)

def main():

    screen = Screen()

    segments = int(screen.numinput('Color Wheel', 'How many colors?'))

    colorlist = [hsv_to_rgb(i / segments, 1.0, 1.0) for i in range(segments)]

    screen.tracer(False)
    arch(RADIUS, WIDTH, colorlist)
    screen.tracer(True)

    magic_marker = Turtle(visible=False)
    magic_marker.penup()
    magic_marker.sety(-FONT_SIZE/2)
    magic_marker.write('', align='center', font=FONT)

    screen.onscreenclick(lambda x, y, t=magic_marker, s=segments: get_number(x, y, t, s))

    screen.mainloop()

if __name__ == '__main__':
    main()

为了简化代码,我将颜色逻辑更改为0.0到1.0,并使其仅在单击色轮时才响应,而不仅仅是在窗口中的任何位置。在

enter image description here

相关问题 更多 >

    热门问题