Create points has equal distance between two points on screen Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Create points has equal distance between two points on screen

17 Apr 2021, 02:04

Hello ,
I am trying to create several points has equal size between two points on the screen,
I have this Code (It shows me the two points that i pressed), but I have no idea what math I would have to do to achieve what i wanted.

Code: Select all

LButton::
Count++
If Count = 1
	MouseGetPos, x1
else
{
	MouseGetPos, x2
	MsgBox, The first cursor point it was at X%x1% `nThe Secound cursor point is at X%x2%
	Count := 0
}
Return
Regardless of the y Pos
Untitled3.png
Untitled3.png (14.99 KiB) Viewed 1119 times
lets say I assigned the number of points 3 ,I want code to set x3 var for the first point , x4 for the second point and x5 for the third point, and so on..

I hope my question is clear. Thank you for any help
User avatar
Smile_
Posts: 858
Joined: 03 May 2020, 00:51

Re: Create points has equal distance between two points on screen  Topic is solved

17 Apr 2021, 03:24

Something like that maybe

Code: Select all

MidPoints := 10
~LButton::
    Count++
    If (Count = 1)
        MouseGetPos, x1
    Else
    {
        x1_ := x1, Var := ""
        MouseGetPos, x2
        If (x1 > x2) 
        {
            x1 := x2
            x2 := x1_
        }
        Distance := Round((x2 - x1) / (MidPoints + 1))
        Loop, %MidPoints%
        {
            x1 += Distance
            Var .= "X" x1 "-"
        }
        Var := RTrim(Var, "-")
        MsgBox, Note: The results are approximative!.`n`n1 - The first cursor point it was at X%x1_%`n2 - The secound cursor point is at X%x2%`n3 - Middle cursor points %Var%`n4 - Distance between points X%Distance%
        Count := 0
    }
Return
User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Create points has equal distance between two points on screen

17 Apr 2021, 03:58

Thank you @Smile_ , but how do I deal with the points,
I mean, I want to move the mouse to the first point, then after 5 seconds, toward the second point ... and so on..

I tried to add

Code: Select all

MouseMove, %Var%
but it didn't work..
User avatar
Smile_
Posts: 858
Joined: 03 May 2020, 00:51

Re: Create points has equal distance between two points on screen

17 Apr 2021, 04:08

Var variable is not pure number to move the cursor into it, it contain "X" char I used it to show the final result in message box.
if you want to move the mouse to the extracted positions, you have to get this positions from the Var variable.

Or you can create an array object for example ResultArr := [] and then later append the positions into it while looping MidPoints
like follow ResultArr.Push(x1).
At this point you got all middle positions stored in an array, I think now will be easy to mouse move into them.
User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Create points has equal distance between two points on screen

17 Apr 2021, 04:20

You are genius ,it works perfectly,
Thank you so much @Smile_ , this code is very useful to me ...

Edit:This final code, Maybe it will be useful to someone in the future..

Code: Select all

MidPoints := 3
ResultArr := []
SetTimer,WatchMouse,1000
WatchMouse:
MouseGetPos,X,Y
ToolTip,X%X%`,Y%Y%
Return
~LButton::
Count++
If (Count = 1)
	MouseGetPos, x1
Else
{
	x1_ := x1, Var := ""
	MouseGetPos, x2
	If (x1 > x2) 
	{
		x1 := x2
		x2 := x1_
	}
	Distance := Round((x2 - x1) / (MidPoints + 1))
	Loop, %MidPoints%
	{
		x1 += Distance
		Var .= "X" x1 "-"
		ResultArr.Push(x1)
	}
	for k , v in ResultArr
	{
		sleep, 1000
		MouseMove %v%, %Y%
		sleep, 1000
	}
	Var := RTrim(Var, "-")
	MsgBox, Note: The results are approximative!.`n`n1 - The first cursor point it was at X%x1_%`n2 - The secound cursor point is at X%x2%`n3 - Middle cursor points %Var%`n4 - Distance between points X%Distance%
	Count := 0
}
Return
Last edited by HiSoKa on 17 Apr 2021, 04:22, edited 2 times in total.
User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Create points has equal distance between two points on screen

17 Apr 2021, 06:19

I am trying to execute this Procedure for Y pos also ,
but I do not know why it does not work as expected, do you have a way to implement this Procedure ..

Code: Select all

MidPoints := 3
ResultArr := []
SetTimer,WatchMouse,1000
WatchMouse:
MouseGetPos,X,Y
ToolTip,X%X%`,Y%Y%
Return
~LButton::
Count++
If (Count = 1)
	MouseGetPos, x1, y1
Else
{
	x1_ := x1, xVar := ""
	y1_ := y1, yVar := ""
	MouseGetPos, x2, y2
	If (x1 > x2) 
	{
		x1 := x2
		x2 := x1_
		y1 := y2
		y2 := y1_
	}
	xDistance := Round((x2 - x1) / (xMidPoints + 1))
	yDistance := Round((y2 - y1) / (yMidPoints + 1))
	Loop, %xMidPoints%
	{
		x1 += xDistance
		xVar .= "X" x1 "-"
	}
	Loop, %yMidPoints%
	{
		y1 += yDistance
		yVar .= "Y" y1 "-"
	}
	xVar := RTrim(xVar, "-")
	yVar := RTrim(yVar, "-")
	MsgBox, Note: The results are approximative!.`n`n1 - The first cursor point it was at X%x1_%`n2 - The secound cursor point is at X%x2%`n3 - Middle cursor points %xVar%`n4 - Distance between points X%xDistance%
	MsgBox, Note: The results are approximative!.`n`n1 - The first cursor point it was at Y%y1_%`n2 - The secound cursor point is at Y%y2%`n3 - Middle cursor points %yVar%`n4 - Distance between points Y%yDistance%
	Count := 0
}
Return
Sorry to be a bother.
User avatar
Smile_
Posts: 858
Joined: 03 May 2020, 00:51

Re: Create points has equal distance between two points on screen

17 Apr 2021, 06:31

@HiSoKa
It is OK, nothing to bother about it
Here try this

Code: Select all

xMidPoints := 3, yMidPoints := 3
SetTimer,WatchMouse,1000
WatchMouse:
    MouseGetPos,x,y
    ToolTip,X%x%`,Y%y%
Return
~LButton::
    ResultArr := []
    Count++
    If (Count = 1)
        MouseGetPos, x1, y1
    Else
    {
        x1_ := x1, xVar := ""
        y1_ := y1, yVar := ""
        MouseGetPos, x2, y2
        If (x1 > x2) 
        {
            x1 := x2
            x2 := x1_
        }
        If (y1 > y2) 
        {
            y1 := y2
            y2 := y1_
        }
        xDistance := Round((x2 - x1) / (xMidPoints + 1))
        yDistance := Round((y2 - y1) / (yMidPoints + 1))
        Loop, %xMidPoints%
        {
            x1 += xDistance
            xVar .= "X" x1 "-"
        }
        Loop, %yMidPoints%
        {
            y1 += yDistance
            yVar .= "Y" y1 "-"
        }
        xVar := RTrim(xVar, "-")
        yVar := RTrim(yVar, "-")
        MsgBox, Note: The results are approximative!.`n`n1 - The first cursor point it was at X%x1_%`n2 - The secound cursor point is at X%x2%`n3 - Middle cursor points %xVar%`n4 - Distance between points X%xDistance%
        MsgBox, Note: The results are approximative!.`n`n1 - The first cursor point it was at Y%y1_%`n2 - The secound cursor point is at Y%y2%`n3 - Middle cursor points %yVar%`n4 - Distance between points Y%yDistance%
        Count := 0
    }
Return
User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Create points has equal distance between two points on screen

17 Apr 2021, 06:36

That's what I wanted, thank you again :)
User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Create points has equal distance between two points on screen

17 Apr 2021, 06:56

I am trying to divide the slash on the left, as in the attached picture, but this code does not work,
Any ideas
Untitled4.png
Untitled4.png (21.83 KiB) Viewed 994 times
this my attempt::

Code: Select all

xMidPoints := 3
yMidPoints := 3
xResultArr := []
yResultArr := []
SetTimer,WatchMouse,1000
WatchMouse:
MouseGetPos,X,Y
ToolTip,X%X%`,Y%Y%
Return

~LButton::
Count++
If (Count = 1)
	MouseGetPos, x1, y1
Else
{
	x1_ := x1, xVar := ""
	y1_ := y1, yVar := ""
	MouseGetPos, x2, y2
	If (x1 > x2) 
	{
		x1 := x2
		x2 := x1_
	}
	If (y1 > y2) 
	{
		y1 := y2
		y2 := y1_
	}
	xDistance := Round((x2 - x1) / (xMidPoints + 1))
	yDistance := Round((y2 - y1) / (yMidPoints + 1))
	Loop, %xMidPoints%
	{
		x1 += xDistance
		xVar .= "X" x1 "-"
		xResultArr.Push(x1)
	}
	Loop, %yMidPoints%
	{
		y1 += yDistance
		yVar .= "Y" y1 "-"
		yResultArr.Push(y1)
	}
	for k , v in xResultArr
	{
		for k1 , v1 in yResultArr
		{
			sleep, 1000
			MouseMove %v%, %v1%
			sleep, 1000
		}
	}
	
	xVar := RTrim(xVar, "-")
	Count := 0
}
Return
User avatar
Smile_
Posts: 858
Joined: 03 May 2020, 00:51

Re: Create points has equal distance between two points on screen

17 Apr 2021, 09:28

@HiSoKa

LButton to define start and end positions.
RButton to apply the movement.

Code: Select all

MidPoints := 4, Count := 0
CoordMode, Mouse, Screen

~LButton::
    xResultArr := []
    yResultArr := []
    Count++
    If (Count = 1)
    {
        MouseGetPos, x1, y1
        ToolTip, Starting position taken! (%x1%`, %y1%)
    }
    Else
    {
        MouseGetPos, x2, y2
        ToolTip, End position taken! (%x2%`, %y2%)`nNow Click right mouse button.
        (x1 < x2) ? xDistance := Round((x2 - x1) / (MidPoints) + 1) : xDistance := Round((x1 - x2) / (MidPoints) + 1)
        (y1 < y2) ? yDistance := Round((y2 - y1) / (MidPoints) + 1) : yDistance := Round((y1 - y2) / (MidPoints) + 1)
        xResultArr.Push(x1)
        yResultArr.Push(y1)
        Loop, % MidPoints
        {
            (x1 < x2) ? x1 += xDistance : x1 -= xDistance
            xResultArr.Push(x1)
            (y1 < y2) ? y1 += yDistance : y1 -= yDistance
            yResultArr.Push(y1)
        }
        Count := 0, x1 := 0, y1 := 0, x2 := 0, y2 := 0
    }

Return
RButton::
    If (xResultArr[1] = "") || (yResultArr[1] = "")
    {
        ToolTip, % "Make sure end position is taken first!"
        Return
    }
    Loop, % MidPoints + 1
    {
        MouseMove, xResultArr[A_Index], yResultArr[A_Index]
        ToolTip, % "Reached position " A_Index ": X = " xResultArr[A_Index] ", Y = " yResultArr[A_Index]
        Sleep, 1000
    }
Return
Esc::ExitApp
That seems to work, although you might see that positions are not pretty exact, it is because the distance between positions is approximate.
User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Create points has equal distance between two points on screen

17 Apr 2021, 09:47

Thank you for your time, it works perfectly now ;) ...
User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Create points has equal distance between two points on screen

17 Apr 2021, 11:35

Here is another approach using a vector class to do the calculations.
I added a small gui for testing purposes but it isn't necessary to have it.

Code: Select all

#SingleInstance, Force
CoordMode, Mouse, Screen
SetBatchLines, -1
Handles := _CreateGui()
return
GuiClose:
GuiContextMenu:
*ESC::ExitApp
SetPositions:
	While( !GetKeyState( "ctrl" ) ){
		MouseGetPos, x , y
		ToolTip, Set Position 1: `nMove your cursor to your Starting Position `nand then press the "ctrl" key to lock it.`nX: %x% `tY: %y%
		sleep, 30
	}
	SoundBeep, 500
	;Create a vector object with the starting position
	StartingPosition :=  New Vector( x , y )
	KeyWait, ctrl
	While(!GetKeyState("ctrl")){
		MouseGetPos, x , y
		ToolTip, Set Position 2: `nMove your cursor to your Ending Position `nand then press the "ctrl" key to lock it.`nX: %x% `tY: %y%
		sleep, 30
	}
	ToolTip,
	SoundBeep, 500
	;Create a vector object with the ending position
	EndingPosition := New Vector( x , y )
	return
	
PlayBack:

	;Get the values from the gui edits
	for, k, v in Handles
		GuiControlGet, %k% , 1: , % v
		
	;Set / Reset the value of "currentPosition" to be the starting position selected by the user
	CurrentPosition := New Vector( StartingPosition.X , StartingPosition.Y ) 
	
	;Get the distance between the starting and ending positions. This is used with the intervals value to determin how far to move for each step.
	Distance := EndingPosition.Dist( CurrentPosition ) 
	
	;Create a new vector object that will be used to calculate the change in position
	PositionUpDate := New Vector() 
	
	;Move the cursor to the starting position
	DllCall("SetCursorPos", "int", StartingPosition.X, "int", StartingPosition.Y) 
	
	;wait the delay value amount of time
	Sleep, % DelayEdit
	
	;Loop the number of interval times set by the user minus 1 (moves = interval + 1 ( the starting position move ) )
	Loop, % IntervalEdit - 1	{
		;Reset the "PositionUpDate" vector object with the ending position values so new calculations can be made
		PositionUpDate.X := EndingPosition.X , PositionUpDate.Y := EndingPosition.Y
		
		;Subtract the value of "currentPosition" to get a vector that points from the current position to the ending position
		PositionUpDate.Sub( CurrentPosition )
		
		;Take the vector and scale it down to the distance to move for each interval
		PositionUpDate.SetMag( Distance / IntervalEdit )
		
		;Add the scaled vector to the current position
		CurrentPosition.Add( PositionUpDate )
		
		;Move the cursor to the current position
		DllCall("SetCursorPos", "int", CurrentPosition.X, "int", CurrentPosition.Y)
		
		;wait the delay value amount of time
		Sleep, % DelayEdit
	}
	
	;Move the cursor one last time to the endingposition
	DllCall("SetCursorPos", "int", EndingPosition.X, "int", EndingPosition.Y)
	return	
	
_CreateGui(){
	local Handles := {}
	Gui, 1:+AlwaysOnTop HwndGuiHwnd
	Gui, 1:Add, Text, xm ym ,Intervals:
	Gui, 1:Add, Edit, x+10 w50 r1 Number Center hwndhwnd, 100
	Handles.IntervalEdit := hwnd
	Gui, 1:Add, Text, xm , Delay Between Intervals [ms]: 
	Gui, 1:Add, Edit, x+10 w50 r1 Number Center hwndhwnd, 10
	Handles.DelayEdit := hwnd
	Gui, 1:Show, 
	WinGetPos,,, w ,, % "ahk_id " GuiHwnd 
	Gui, 1:Add, Button, % "xm  w" w / 2 - 20  " gSetPositions", Set Positions
	Gui, 1:Add, Button, % "x+10 w" w / 2 - 15  " gPlayBack", >  PlayBack
	Gui, 1:Show, AutoSize, Vector Move
	return Handles
}
Class Vector	{
	__New(x:=0,y:=0){
		This.X:=x,This.Y:=y
	}Add(Other_HB_Vector){
		This.X+=Other_HB_Vector.X,This.Y+=Other_HB_Vector.Y
	}Sub(Other_HB_Vector){
		This.X-=Other_HB_Vector.X,This.Y-=Other_HB_Vector.Y
	}mag(){
		return Sqrt(This.X*This.X + This.Y*This.Y)
	}magsq(){
		return This.Mag()**2
	}setMag(in1){
		m:=This.Mag(),This.X := This.X * in1/m,This.Y := This.Y * in1/m
		return This
	}dist(in1){
		return Sqrt(((This.X-In1.X)**2) + ((This.Y-In1.Y)**2))
	}
}
User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Create points has equal distance between two points on screen

17 Apr 2021, 12:19

Thank you very much @Hellbent for this great code and for comments , it will be useful for me,
But what name of points variables in this code, I tried to find it by myself, but I couldn't :mrgreen:
because i would like to deal with them separately
User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Create points has equal distance between two points on screen

17 Apr 2021, 12:31

HiSoKa wrote:
17 Apr 2021, 12:19
Thank you very much @Hellbent for this great code and for comments , it will be useful for me,
But what is the name of the points variable in this code, I tried to find it by myself, but I couldn't :mrgreen:
because i would like to deal with them separately
The points are the intervalEdit value + 1 (for the starting position). So it moves to the starting position and then moves the intervalEdit value times.

Also here is the same, but I added in some commented mousemove code so you can see how to change how fast the mouse moves between the points.
Just swap the dllcalls with the mousemove.

Code: Select all

#SingleInstance, Force
CoordMode, Mouse, Screen
SetBatchLines, -1
Handles := _CreateGui()
return
GuiClose:
GuiContextMenu:
*ESC::ExitApp
SetPositions:
	While( !GetKeyState( "ctrl" ) ){
		MouseGetPos, x , y
		ToolTip, Set Position 1: `nMove your cursor to your Starting Position `nand then press the "ctrl" key to lock it.`nX: %x% `tY: %y%
		sleep, 30
	}
	SoundBeep, 500
	;Create a vector object with the starting position
	StartingPosition :=  New Vector( x , y )
	KeyWait, ctrl
	While(!GetKeyState("ctrl")){
		MouseGetPos, x , y
		ToolTip, Set Position 2: `nMove your cursor to your Ending Position `nand then press the "ctrl" key to lock it.`nX: %x% `tY: %y%
		sleep, 30
	}
	ToolTip,
	SoundBeep, 500
	;Create a vector object with the ending position
	EndingPosition := New Vector( x , y )
	return
	
PlayBack:

	;Get the values from the gui edits
	for, k, v in Handles
		GuiControlGet, %k% , 1: , % v
		
	;Set / Reset the value of "currentPosition" to be the starting position selected by the user
	CurrentPosition := New Vector( StartingPosition.X , StartingPosition.Y ) 
	
	;Get the distance between the starting and ending positions. This is used with the intervals value to determin how far to move for each step.
	Distance := EndingPosition.Dist( CurrentPosition ) 
	
	;Create a new vector object that will be used to calculate the change in position
	PositionUpDate := New Vector() 
	
	;Move the cursor to the starting position
	DllCall("SetCursorPos", "int", StartingPosition.X, "int", StartingPosition.Y) 
	
	;wait the delay value amount of time
	Sleep, % DelayEdit
	
	;Loop the number of interval times set by the user minus 1 (moves = interval + 1 ( the starting position move ) )
	Loop, % IntervalEdit - 1	{
		;Reset the "PositionUpDate" vector object with the ending position values so new calculations can be made
		PositionUpDate.X := EndingPosition.X , PositionUpDate.Y := EndingPosition.Y
		
		;Subtract the value of "currentPosition" to get a vector that points from the current position to the ending position
		PositionUpDate.Sub( CurrentPosition )
		
		;Take the vector and scale it down to the distance to move for each interval
		PositionUpDate.SetMag( Distance / IntervalEdit )
		
		;Add the scaled vector to the current position
		CurrentPosition.Add( PositionUpDate )
		
		;Move the cursor to the current position
		DllCall("SetCursorPos", "int", CurrentPosition.X, "int", CurrentPosition.Y)
		;~ MouseMove, CurrentPosition.X , CurrentPosition.Y , 20 ;For slower movements
		
		;wait the delay value amount of time
		Sleep, % DelayEdit
	}
	
	;Move the cursor one last time to the endingposition
	DllCall("SetCursorPos", "int", EndingPosition.X, "int", EndingPosition.Y)
	;~ MouseMove, EndingPosition.X , EndingPosition.Y , 20  ;For slower movements
	return	
	
_CreateGui(){
	local Handles := {}
	Gui, 1:+AlwaysOnTop HwndGuiHwnd
	Gui, 1:Add, Text, xm ym ,Intervals:
	Gui, 1:Add, Edit, x+10 w50 r1 Number Center hwndhwnd, 100
	Handles.IntervalEdit := hwnd
	Gui, 1:Add, Text, xm , Delay Between Intervals [ms]: 
	Gui, 1:Add, Edit, x+10 w50 r1 Number Center hwndhwnd, 10
	Handles.DelayEdit := hwnd
	Gui, 1:Show, 
	WinGetPos,,, w ,, % "ahk_id " GuiHwnd 
	Gui, 1:Add, Button, % "xm  w" w / 2 - 20  " gSetPositions", Set Positions
	Gui, 1:Add, Button, % "x+10 w" w / 2 - 15  " gPlayBack", >  PlayBack
	Gui, 1:Show, AutoSize, Vector Move
	return Handles
}
Class Vector	{
	__New(x:=0,y:=0){
		This.X:=x,This.Y:=y
	}Add(Other_HB_Vector){
		This.X+=Other_HB_Vector.X,This.Y+=Other_HB_Vector.Y
	}Sub(Other_HB_Vector){
		This.X-=Other_HB_Vector.X,This.Y-=Other_HB_Vector.Y
	}mag(){
		return Sqrt(This.X*This.X + This.Y*This.Y)
	}magsq(){
		return This.Mag()**2
	}setMag(in1){
		m:=This.Mag(),This.X := This.X * in1/m,This.Y := This.Y * in1/m
		return This
	}dist(in1){
		return Sqrt(((This.X-In1.X)**2) + ((This.Y-In1.Y)**2))
	}
}
Last edited by Hellbent on 17 Apr 2021, 12:34, edited 1 time in total.
User avatar
Smile_
Posts: 858
Joined: 03 May 2020, 00:51

Re: Create points has equal distance between two points on screen

17 Apr 2021, 12:43

@HiSoKa
@Hellbent solution is much nicer (Positions are exact as I see), you should use it instead.
User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Create points has equal distance between two points on screen

17 Apr 2021, 12:49

Yes, I noticed that it was really very accurate :+1:
User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Create points has equal distance between two points on screen

17 Apr 2021, 13:18

If you have a few mins to spare I recommend checking out a few mins of this video by a channel called 3Blue1Brown on Linear algebra.
Start from around the 2 min mark, at around the 5 min mark he goes into adding vectors, and then scaling vectors at around the 7 min mark.
Ignore the notation he shows, here we do it as obj.x and obj.y


Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot] and 144 guests