Как определить, в какую из треугольных областей попадает координата?
Моя идея в том, чтобы зная только x и y координаты мыши проверять в какой из областей экрана находится курсор, разделить нужно в таком виде:
Необязательна полная реализации в виде кода, но хотя бы решение в теоретическом виде.
Ответы (2 шт):
Автор решения: Amgarak
→ Ссылка
Интересная задача, так что решил сделать для вас небольшой пример.
Код:
from collections import namedtuple
import ctypes
import win32con
import win32api
import win32gui
import atexit
# pip install pywin32
MouseEvent = namedtuple('MouseEvent', ['event_type', 'x', 'y'])
handlers = []
def listen():
def low_level_handler(nCode, wParam, lParam):
point = ctypes.cast(lParam, ctypes.POINTER(ctypes.c_long * 2)).contents
x = point[0]
y = point[1]
event = MouseEvent(wParam, x, y)
for handler in handlers:
handler(event)
return ctypes.windll.user32.CallNextHookEx(hook_id, nCode, wParam, lParam)
CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_void_p))
ctypes.windll.user32.SetWindowsHookExW.argtypes = (
ctypes.c_int,
CMPFUNC,
ctypes.c_void_p,
ctypes.c_uint
)
pointer = CMPFUNC(low_level_handler)
hook_id = ctypes.windll.user32.SetWindowsHookExW(win32con.WH_MOUSE_LL, pointer,
win32api.GetModuleHandle(None), 0)
atexit.register(ctypes.windll.user32.UnhookWindowsHookEx, hook_id)
win32gui.GetMessage(None, 0, 0)
def get_screen_resolution():
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
screen_width = user32.GetSystemMetrics(0)
screen_height = user32.GetSystemMetrics(1)
return screen_width, screen_height
def get_triangles(screen_width, screen_height):
top_left = (0, 0)
top_right = (screen_width, 0)
bottom_right = (screen_width, screen_height)
bottom_left = (0, screen_height)
center = (screen_width // 2, screen_height // 2)
triangles = [
("Triangle 1", bottom_left, center, top_left),
("Triangle 2", top_left, center, top_right),
("Triangle 3", top_right, center, bottom_right),
("Triangle 4", bottom_right, center, bottom_left),
]
return triangles
screen_width, screen_height = get_screen_resolution()
triangles = get_triangles(screen_width, screen_height)
def is_in_triangle(x, y, v1, v2, v3):
x1, y1 = v1
x2, y2 = v2
x3, y3 = v3
def is_same_side(x2, y2, x3, y3):
return (x - x3) * (y2 - y3) - (x2 - x3) * (y - y3) < 0
bool1 = is_same_side(x1, y1, x2, y2)
bool2 = is_same_side(x2, y2, x3, y3)
bool3 = is_same_side(x3, y3, x1, y1)
return bool1 == bool2 == bool3
def find_triangle(x, y):
for name, v1, v2, v3 in triangles:
if is_in_triangle(x, y, v1, v2, v3):
return name
return "Outside"
if __name__ == '__main__':
def print_event(event):
print(f"Position: ({event.x}, {event.y})")
print(find_triangle(event.x, event.y))
handlers.append(print_event)
listen()
listen()
- ставим хук для получения (x,y)print_event(event)
- коллбэк в который возвращаем (x,y)get_screen_resolution()
- вернём размеры экрана.get_triangles(screen_width, screen_height)
- получим вершины всех 4 треугольников.find_triangle(x, y)
/is_in_triangle(x, y, v1, v2, v3)
- тут уже будем вычислять, попали ли (x,y) в треугольник и если да, то в какой.
Автор решения: Ivan Polevikov
→ Ссылка
В общем посидел подумал над предложением с уравнениями и написал вот такой код.
import win32api
import pyautogui
import time
width, height = 2560, 1440
# k1 = width/height
# k2 = height/width
k = height/width
while True:
if win32api.GetKeyState(0x01) < 0:
x, y = pyautogui.position()
if y < (width - x) * k:
if x * k < y:
print(1) # число - четверть согласно рисунку
else:
print(2)
else:
if x * k > y:
print(3)
else:
print(4)
time.sleep(0.1)
k1 и k2 это коэффициенты где x = y * k1 и y = x * k2. (Функции диагоналей)