svorky
Новичок
- Сообщения
- 1
- Репутация
- 0
Добрый день!
Уже несколько дней бьюсь с алгоритмом и без каких-то костылей нормально сделать не получается, пересмотрел кучу формул и уже совсем запутался.
Задача такая: юзер кликает на экране в начальную точку A, затем в финишную точку B, и промежуточную точку C. Скрипт шагами ведет курсор мыши по этой дуге из точки А в точку В через точку С, делая в каждом шаге клик, включая А и В, С не обязательно.
Как я вижу, проблема заключается в том, что большинство формул в интернете для пространства, где точка (0,0) в левом нижнем углу, в отличие от экрана монитора, где она наверху. Соответственно, неправильно определяются углы точек. Пробовал делать координату Y отрицательной, но в геометрии я не силён и что ещё нужно менять я не понимаю.
Основные функции у меня есть такие
Прошу помочь с дописанием скрипта и добавить код для рисования дуги против часовой стрелки (будет передаваться аргументом в функцию arcDraw)
На просторах ещё нашёл такую функцию определения углов, но адаптировать без костылей и велосипедов не получилось.
Уже несколько дней бьюсь с алгоритмом и без каких-то костылей нормально сделать не получается, пересмотрел кучу формул и уже совсем запутался.
Задача такая: юзер кликает на экране в начальную точку A, затем в финишную точку B, и промежуточную точку C. Скрипт шагами ведет курсор мыши по этой дуге из точки А в точку В через точку С, делая в каждом шаге клик, включая А и В, С не обязательно.
Как я вижу, проблема заключается в том, что большинство формул в интернете для пространства, где точка (0,0) в левом нижнем углу, в отличие от экрана монитора, где она наверху. Соответственно, неправильно определяются углы точек. Пробовал делать координату Y отрицательной, но в геометрии я не силён и что ещё нужно менять я не понимаю.
Основные функции у меня есть такие
Код:
#include <Math.au3>
#include <Misc.au3>
#include <Date.au3>
Func GetSegmentLength($x1, $y1, $x2, $y2)
Return Sqrt(($x2 - $x1)^2 + ($y2 - $y1)^2)
EndFunc
; Вычисление радиуса и центра окружности по перпендикулярам
Func GetRadius($A, $B, $C)
$m1 = ($C[1]-$A[1]) / ($C[0]-$A[0])
$m2 = ($C[1]-$B[1]) / ($C[0]-$B[0])
$x = ($m1*$m2*($A[1]-$B[1])+$m2*($A[0]+$C[0])-$m1*($B[0]+$C[0])) / (2*($m2-$m1))
$y = (-1/$m1)*($x-($A[0]+$C[0])/2)+($A[1]+$C[1])/2
$r = Sqrt(($x-$A[0])^2+($y-$A[1])^2)
Local $q[3] = [$r, $x, $y]
Return $q
EndFunc
Func _ATan2(Const $nY, Const $nX)
If Not IsNumber($nY) Or Not IsNumber($nX) Then Return SetError(1, 0, 0)
Return SetError(0, 0, ATan($nY / $nX) + ((($nY <= 0) And ($nX < 0)) + (($nY > 0) And ($nX < 0)) - 2 * (($nY < 0) And ($nX < 0))) * 3.14159265358979323846)
EndFunc
Func getAngle2PointsDeg($p1_x, $p1_y, $p2_x, $p2_y)
$pi = 4 * ATan(1)
return ACos( ( ($p1_x * $p2_x) + ($p1_y * $p2_y) ) / (Sqrt($p1_x^2 + $p1_y^2) * sqrt($p2_x^2 + $p2_y^2)) ) * 180 / $pi
EndFunc
Func arcDraw($clockwise = 0)
Local $A
Local $B
Local $C
SplashTextOn("Рисование дуги по трём точкам", "Наведите мышь на 1-ю точку и нажмите пробел...", 300, 180, 40, 300, 4+16, "", 14)
While 1
If _IsPressed("20") Then
While _IsPressed("20") = 1
WEnd
Send("{SPACE} up")
$A = MouseGetPos()
$x1 = $A[0]
$y1 = $A[1]
ExitLoop
EndIf
Sleep(100)
WEnd
SplashTextOn("Рисование дуги по трём точкам", "Наведите мышь на 2-ю точку и нажмите пробел...", 300, 180, 40, 300, 4+16, "", 14)
;ControlSetText("Рисование дуги по трём точкам", "", "Static1", "Наведите мышь на 2-ю точку и нажмите пробел...")
While 1
If _IsPressed("20") Then
While _IsPressed("20") = 1
WEnd
Send("{SPACE} up")
$B = MouseGetPos()
$x2 = $B[0]
$y2 = $B[1]
ExitLoop
EndIf
Sleep(100)
WEnd
SplashTextOn("Рисование дуги по трём точкам", "Наведите мышь на 3-ю точку и нажмите пробел...", 300, 180, 40, 300, 4+16, "", 14)
While 1
If _IsPressed("20") Then
Send("{SPACE} up")
$C = MouseGetPos()
$x3 = $C[0]
$y3 = $C[1]
ExitLoop
EndIf
Sleep(100)
WEnd
$l = GetSegmentLength($A[0], $A[1], $B[0], $B[1])
$r = GetRadius($A, $B, $C)
$Ox = $r[1]
$Oy = $r[2]
$radius = $r[0]
$pi = 4 * ATan(1)
$AAngle = _Atan2($A[1] - $Oy, $A[0] - $Ox) * (180/$pi)
$BAngle = _Atan2($B[1] - $Oy, $B[0] - $Ox) * (180/$pi)
$step = $pi
moveMouseCircle($Ox, $Oy, $radius, 0, $AAngle, $BAngle, 100, $step)
SplashOff()
EndFunc
Func moveMouseCircle($h, $k, $radius, $direction = 0, $startangle = 0, $endangel = 360, $delay = 10, $step = 50)
;h = Center X
;k = Center Y
;radius in pixels
;direction: 0 = clockwise (default), 1 = counter-clockwise
;start angle in degrees (0-360): default is 0
;delay in milliseconds: default 10
;step in degrees: default 0
$pi = 4 * ATan(1)
$start = $startangle
$end = $endange
;For $Z = 1 to 2
For $A = $start to $end Step $step
If $direction Then
$X = $h - sin(_Radian($A)) * $radius
Else
$X = $h + sin(_Radian($A)) * $radius
EndIf
$Y = $k - cos(_Radian($A)) * $radius
MouseMove ( $X, $Y, 0)
MouseClick("left")
Sleep($delay)
Next
$start = 0
$end = $startangle
;Next
EndFunc
Прошу помочь с дописанием скрипта и добавить код для рисования дуги против часовой стрелки (будет передаваться аргументом в функцию arcDraw)
На просторах ещё нашёл такую функцию определения углов, но адаптировать без костылей и велосипедов не получилось.
Код:
Func AnglePointToPoint($fromX, $fromY, $toX, $toY)
$pi = 4 * ATan(1)
$distanceX = $toX - $fromX
$distanceY = -($toY - $fromY)
$beta = acos( abs($distanceX) / sqrt( $distanceX^2 + $distanceY^2 ) ) * 180 / $pi
ConsoleWrite(_NowTime() & " -- dx = $distanceX$" & @CRLF)
ConsoleWrite(_NowTime() & " -- dy = $distanceY$" & @CRLF)
ConsoleWrite(_NowTime() & " -- beta = $beta$" & @CRLF)
$angleResult = 0.0
if $distanceX > 0 Then
if $distanceY < 0 Then
$angleResult = $beta + 90;//right_bot
else
$angleResult = abs($beta - 90);//right_top
EndIf
else
if $distanceY < 0 then
$angleResult = abs($beta - 90) + 180;//left_bot
else
$angleResult = $beta + 270;//left_top
EndIf
EndIf
return $angleResult
EndFunc