KIVY collide_point 顶点矩形

KIVY collide_point vertex Rectangle

我有一个带有矩形和水平线的自定义小部件,它们都是使用顶点指令创建的。我想检查用户是否在我的小部件中的矩形或水平线内触摸。尝试使用组但无法找到用户是否触摸了矩形或线。你能给我提供线索吗? 找到下面的示例代码。

from kivy.app import App
from kivy.graphics import Line
from kivy.uix.scatter import Scatter
from kivy.uix.relativelayout import RelativeLayout
from kivy.lang import Builder

KV = '''
<Actor>:
    id: Actor
    canvas:
        Color:
            rgba: 0,1,0,1
        Rectangle:
            group: 'rect'
            size: 100, 30
            pos: 0, root.height - 30
        Line:
            group: 'line'
            points: 50, root.height - 30, 50, 0
            width:2
    Label:
        id: _actr_lbl
        text: 'Hello World'
        markup: True
        color: 0,0,0,1
        size_hint: None, None
        size: 100, 30
        pos: 0, root.height - 30
'''

class Actor(Scatter):
    def __init__(self, **kwargs):
        super(Actor, self).__init__(**kwargs)

    def on_touch_down(self, touch):

        print('Touch location {} Actor location {} Actor Size {}'.format(touch, self.pos, self.size))
        if self.collide_point(*touch.pos) :
           for aVertex in self.canvas.get_group('rect') :
               try:
                   print ('Vertex size {} and pos'.format(aVertex.size, aVertex.pos))
               except:
                   pass
           return True

        return super(Actor, self).on_touch_down(touch)

class MyPaintApp(App):

    def build(self):
        Builder.load_string(KV)
        root = RelativeLayout()
        root.add_widget(Actor(pos_hint={'center_x':0.5, 'center_y':0.5}, size_hint=(.2, 1.)))
        return root

if __name__ == '__main__':
    MyPaintApp().run()

提前致谢

你可以做一个简单的边界框检查,但你必须考虑到 touch 在父坐标系中的事实。所以可以将触摸位置转换为本地坐标,然后进行测试。这是 Rectangle:

的示例
def on_touch_down(self, touch):

    print('Touch location {} Actor location {} Actor Size {}'.format(touch, self.pos, self.size))
    if self.collide_point(*touch.pos) :
        localTouchPos = self.to_local(*touch.pos)
        for aVertex in self.canvas.get_group('rect') :
            print('\tVertex size {} and pos {}'.format(aVertex.size, aVertex.pos))
            intersection = True
            if localTouchPos[0] < aVertex.pos[0]:
                intersection = False
            elif localTouchPos[0] > aVertex.pos[0] + aVertex.size[0]:
                intersection = False
            if localTouchPos[1] < aVertex.pos[1]:
                intersection = False
            elif localTouchPos[1] > aVertex.pos[1] + aVertex.size[1]:
                intersection = False
        print('intersection =', intersection)
        return True

    return super(Actor, self).on_touch_down(touch)

您可以为 Line 做类似的事情,但如果您想做一般的 Line,可能会稍微复杂一些。如果你的 Line 总是垂直的,它应该非常相似。