Вопрос по PixelSearch

Помощь в написании скриптов
Karamba14
Posts: 1
Joined: 30 Mar 2021, 09:42

Вопрос по PixelSearch

Post by Karamba14 » 30 Mar 2021, 10:56

Здравствуйте. В команде PixelSearch две координаты прямоугольнка - левый верхний угол и правый нижний. Подскажите, пожалуйста, можно ли как-нибудь использовать 4 координаты, если мне нужно найти пиксель в прямоугольникe, стороны которого не параллельны сторонам окна?

mcl
Posts: 355
Joined: 04 May 2018, 16:35

Re: Вопрос по PixelSearch

Post by mcl » 30 Mar 2021, 13:45

Напрямую − нет. Можно написать функцию, которая будет искать пиксель в bounding box этого прямоугольника и затем проверять, лежат ли найденные координаты внутри искомого прямоугольника. Единственная проблема − если PixelSearch найдёт пиксель внутри bounding box, но вне прямоугольника (см. иллюстрацию).

Code: Select all

; Функция ищет пиксель аналогично PixelSearch
; и возвращает 1, если найденный пиксель внутри данного четырёхугольника
PixelSearchBBox(ByRef outX, ByRef outY, x1, y1, x2, y2, x3, y3, x4, y4, colorID, variation := 0, mode := "") {
	  aabb_xmin := Min(x1, x2, x3, x4)
	, aabb_xmax := Max(x1, x2, x3, x4)
	, aabb_ymin := Min(y1, y2, y3, y4)
	, aabb_ymax := Max(y1, y2, y3, y4)
	
	PixelSearch, pox, poy, %aabb_xmin%, %aabb_ymin%, %aabb_xmax%, %aabb_ymax%, %colorID%, %variation%, %mode%
	outX := pox
	outY := poy
	
	If (pox == "")
		Return 0
	
	; Проверяем, лежит ли точка внутри искомого прямоугольника
	; Для этого вычисляем векторное произведение между каждой стороной и вектором к этой точке
	Return (DotProduct_OnRightSide(x2, y2, x3, y3, pox, poy)
	    &&  DotProduct_OnRightSide(x2, y2, x3, y3, pox, poy)
	    &&  DotProduct_OnRightSide(x3, y3, x4, y4, pox, poy)
	    &&  DotProduct_OnRightSide(x4, y4, x1, y1, pox, poy))
}

; Если точка P лежит по правую сторону от AB,
; векторное произведение между векторами AB и AP будет меньше нуля.
DotProduct_OnRightSide(ax, ay, bx, by, px, py) {
	  dlx := bx - ax
	, dly := by - ay
	, dpx := px - ax
	, dpy := py - ay
	Return (dly*dpx - dlx*dpy) <= 0
}
Если угол поворота прямоугольника не очень большой, а искомый пиксель лежит ближе к центру, можно использовать более простой способ:

Code: Select all

; Альтернативный вариант: поиск внутри прямоугольника, лежащего на серединах сторон оригинального.
; Чем больше угол поворота, тем ниже точность − пропускает углы, даёт ложноположительные срабатывания.
PixelSearchHalfBBox(ByRef outX, ByRef outY, x1, y1, x2, y2, x3, y3, x4, y4, colorID, variation := 0, mode := "") {
	  hx1 := (x1 + x2) / 2,  hy1 := (y1 + y2) / 2
	, hx2 := (x2 + x3) / 2,  hy2 := (y2 + y3) / 2
	, hx3 := (x3 + x4) / 2,  hy3 := (y3 + y4) / 2
	, hx4 := (x4 + x1) / 2,  hy4 := (y4 + y1) / 2
	
	  aabb_xmin := Min(hx1, hx2, hx3, hx4)
	, aabb_xmax := Max(hx1, hx2, hx3, hx4)
	, aabb_ymin := Min(hy1, hy2, hy3, hy4)
	, aabb_ymax := Max(hy1, hy2, hy3, hy4)
	
	PixelSearch, pox, poy, %aabb_xmin%, %aabb_ymin%, %aabb_xmax%, %aabb_ymax%, %colorID%, %variation%, %mode%
	outX := pox
	outY := poy
}
На иллюстрации оригинальные прямоугольники отмечены контуром, область поиска − оранжевым.
Пиксель, найденный в зелёной области, даёт ложноположительное срабатывание, в синей − ложноотрицательное.
Attachments
rects.png
rects.png (9.19 KiB) Viewed 492 times
github://oGDIp - GDI+ wrapper for AHK v1.1

Post Reply

Return to “Помощь”