Jump to content

Point which get closer to another


 Share

Recommended Posts

Hello All

I'm trying to create a au3 script for get closer one point from another with iterations.

I'm bad at math, and I didn't succeed to create the GetCloser() Func (see below), if anyone have an idea... ^^ Ty

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.14.2
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here
#include <Math.au3>
#include <MsgBoxConstants.au3>

;Best geometrical representation :)
;~                             |
;~                             |
;~                             |
;~          *B3                |                *B1
;~                             |
;~                             |
;~                             |
;~                             +1
;~ ----------------------..-1,*A +1,..-------------------------
;~                             -1
;~                             |
;~                             |
;~                             |
;~          *B4                |                *B2
;~                             |
;~                             |
;~                             |


Local $A[2]
Local $B1[2]
Local $B2[2]
Local $B3[2]
Local $B4[2]
$A[0] = 0
$A[1] = 0

;xB > xA & yB > yA (top right corner)
$B1[0] = 100
$B1[1] = 100

;xB > xA & yB < yA (bottom right corner)
$B2[0] = 100
$B2[1] = -100

;xB < xA & yB > yA (top left corner)
$B3[0] = -100
$B3[1] = 100

;xB < xA & yB < yA (bottom right corner)
$B4[0] = -100
$B4[1] = -100

;Same dist for all B points, its ok
Local $D1 = Distance($A,$B1);141
Local $D2 = Distance($A,$B2)
Local $D3 = Distance($A,$B3)
Local $D4 = Distance($A,$B4)
;MsgBox(0,"Dist A <-> B1",$D1)
;MsgBox(0,"Dist A <-> B2",$D2)
;MsgBox(0,"Dist A <-> B3",$D3)
;MsgBox(0,"Dist A <-> B4",$D4)

;get the new $A pos every ($D-20)
$step = 20

;141/6 Then 8 loops ?
While $D1 <> 0
   $A = GetCloser($A,$B1,$D1,$step)
   $D1 = Distance($A,$B1)
   MsgBox(0,"NEW POS","A = "&$A[0]&","&$A[1])
WEnd

 MsgBox(0,"Pos A = B","A = "&$A[0]&","&$A[1]&" B= "$B[0]&","$B[1])

;B2,B3,B4 loop laters....

Func Distance($A,$B)
   local $valeur = (($B[0]-$A[0])^2) + (($B[1]-$A[1])^2)
   $valeur = Sqrt($valeur)
   $valeur = Round($valeur,0)
   return $valeur
EndFunc

;Try to understand mathematics... :)
;~ Func Angle($A,$B)
;~    local $angle = _Degree(ATan(($B[1]-$A[1])/($B[0]-$A[0])))
;~    return $angle
;~ EndFunc

;I really dont know how to do this, I find this
;https://www.developpez.net/forums/d830412/general-developpement/algorithme-mathematiques/mathematiques/calcul-rapprocher-point-d/ (souviron34 answer)
Func GetCloser($A,$B,$D,$step)
   local $newPosA[2]

   ;x
   $newPosA[0] = -1;how to calcuate... ACos (or something like this?)
   ;y
   $newPosA[1] = -1;how to calcuate...ASin (or something like this?)

   ;I need this x/y pos
   return $newposA
EndFunc

 

Link to comment
Share on other sites

Can't remember where AutoIt measures 0 degrees from, but Cosine is +1 at 0 degrees and -1 at 180 degrees, Sine is +1 at 90 degrees, -1 at 270 degrees. Multiply by your radius by Sine to reduce/expand in the y direction, and by Cosine to reduce/expand in the x direction (I think). I think the trig functions use radians, so multiply the degrees by Pi/180 to convert.

Link to comment
Share on other sites

Post mentionned "simple"? Geez!

There is no need for trigonometry here:

Local $aPts = [ _
    [-1.58, 1.06], _        ; start point
    [6.06, 4.46], _         ; goal 1
    [-8.32, 7.44], _
    [6.22, -7.3], _
    [3.02, 6.36] _          ; goal 4
]

Local $Step = 5
For $i = 1 To 4
    _Walk($aPts[0][0], $aPts[0][1], $aPts[$i][0], $aPts[$i][1], $Step)
Next

; walk from point (x0, y0) to point (x1, y1) in n steps
Func _Walk($x0, $y0, $x1, $y1, $n)
    Local $dX = ($x1 - $x0) / $n, $dY = ($y1 - $y0) / $n
    For $i = 0 To $n
        ConsoleWrite('(' & Round($x0 + $dX * $i, 2) & '), (' & Round($y0 + $dY * $i, 2) & ')' & @LF)
    Next
    ConsoleWrite(@LF)
EndFunc

"Look 'Ma: no Cos()"

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Hello all :)

Thx for all your comments, I'm able to find a way to achieve this.

The code is verbos and not optimise I think if anyone has idea to improve this :)

For jchd, I badly name my var $step but its not step but the distance to do for a loop (see ex below) : 

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.14.2
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here
#include <Math.au3>
#include <MsgBoxConstants.au3>

;Best geometrical representation :)
;~                             |
;~                             |
;~                             |
;~          *B3                |                *B1
;~                             |
;~                             |
;~                             |
;~                             +1
;~ ----------------------..-1,*A +1,..-------------------------
;~                             -1
;~                             |
;~                             |
;~                             |
;~          *B4                |                *B2
;~                             |
;~                             |
;~                             |


Local $A[2]
Local $B1[2]
Local $B2[2]
Local $B3[2]
Local $B4[2]

;xB > xA & yB > yA (top right corner)
$B1[0] = 100
$B1[1] = 100

;xB > xA & yB < yA (bottom right corner)
$B2[0] = 100
$B2[1] = -100

;xB < xA & yB > yA (top left corner)
$B3[0] = -100
$B3[1] = 100

;xB < xA & yB < yA (bottom right corner)
$B4[0] = -100
$B4[1] = -100

;Same dist for all B points, its ok
Local $D1 = Distance($A,$B1);141
Local $D2 = Distance($A,$B2)
Local $D3 = Distance($A,$B3)
Local $D4 = Distance($A,$B4)
;MsgBox(0,"Dist A <-> B1",$D1)
;MsgBox(0,"Dist A <-> B2",$D2)
;MsgBox(0,"Dist A <-> B3",$D3)
;MsgBox(0,"Dist A <-> B4",$D4)

$DistToDo = 20
$A[0] = 0
$A[1] = 0
While $D1 <> 0
   $A = GetCloser($A,$B1,$D1,$DistToDo)
   $D1 = Distance($A,$B1)
   If $D1 <= $DistToDo Then
      $DistToDo = $D1
   EndIf

   MsgBox(0,"NEW POS","A = "&$A[0]&","&$A[1]&" DIST LEFT = "&$D1&" DISTTODO = "&$DistToDo)
WEnd

$DistToDo = 20
$A[0] = 0
$A[1] = 0
While $D2 <> 0
   $A = GetCloser($A,$B2,$D2,$DistToDo)
   $D2 = Distance($A,$B2)
   If $D2 <= $DistToDo Then
      $DistToDo = $D2
   EndIf

   MsgBox(0,"NEW POS","A = "&$A[0]&","&$A[1]&" DIST LEFT = "&$D2&" DISTTODO = "&$DistToDo)
WEnd

$DistToDo = 20
$A[0] = 0
$A[1] = 0
While $D3 <> 0
   $A = GetCloser($A,$B3,$D3,$DistToDo)
   $D3 = Distance($A,$B3)
   If $D3 <= $DistToDo Then
      $DistToDo = $D3
   EndIf

   MsgBox(0,"NEW POS","A = "&$A[0]&","&$A[1]&" DIST LEFT = "&$D3&" DISTTODO = "&$DistToDo)
WEnd

$DistToDo = 20
$A[0] = 0
$A[1] = 0
While $D4 <> 0
   $A = GetCloser($A,$B4,$D4,$DistToDo)
   $D4 = Distance($A,$B4)
   If $D4 <= $DistToDo Then
      $DistToDo = $D4
   EndIf

   MsgBox(0,"NEW POS","A = "&$A[0]&","&$A[1]&" DIST LEFT = "&$D4&" DISTTODO = "&$DistToDo)
WEnd

;~ ;Use Case *A not from origin
Local $ATopRight[2]
$ATopRight[0] = 20
$ATopRight[1] = 15
$DistToDo = 20
$D1 = Distance($ATopRight,$B1)
While $D1 <> 0
   $ATopRight = GetCloser($ATopRight,$B1,$D1,$DistToDo)
   $D1 = Distance($ATopRight,$B1)
   If $D1 <= $DistToDo Then
      $DistToDo = $D1
   EndIf

   MsgBox(0,"NEW POS","A = "&$ATopRight[0]&","&$ATopRight[1]&" DIST LEFT = "&$D1&" DISTTODO = "&$DistToDo)
WEnd

Local $ATopLeft[2]
$ATopLeft[0] = -33
$ATopLeft[1] = 72
$DistToDo = 20
$D1 = Distance($ATopLeft,$B1)
While $D1 <> 0
   $ATopLeft = GetCloser($ATopLeft,$B1,$D1,$DistToDo)
   $D1 = Distance($ATopLeft,$B1)
   If $D1 <= $DistToDo Then
      $DistToDo = $D1
   EndIf

   MsgBox(0,"NEW POS","A = "&$ATopLeft[0]&","&$ATopLeft[1]&" DIST LEFT = "&$D1&" DISTTODO = "&$DistToDo)
WEnd

Func Distance($A,$B)
   local $valeur = (($B[0]-$A[0])^2) + (($B[1]-$A[1])^2)
   $valeur = Sqrt($valeur)
   $valeur = Round($valeur,0)
   return $valeur
EndFunc

Func GetCloser($A,$B,$D,$DistToDo)
   local $newPosA[2]
   $newPosA[0] = $A[0]
   $newPosA[1] = $A[1]

   local $CurrentDist = Distance($newPosA,$B)

   While $CurrentDist >= ($D-$DistToDo) And $CurrentDist <> 0
      ;MsgBox(0,"","NEWPOS A x = "&$newPosA[0]&" B x "&$B[0])
      ;MsgBox(0,"","NEWPOS A y = "&$newPosA[1]&" B y "&$B[1])
      ;x
      If $newPosA[0] < $B[0] Then
         $newPosA[0] = $newPosA[0]+1
      ElseIf $newPosA[0] <> $B[0] Then
         $newPosA[0] = $newPosA[0]-1
      EndIf

      ;y
      If $newPosA[1] < $B[1]  Then
         $newPosA[1] = $newPosA[1]+1
      ElseIf $newPosA[1] <> $B[1] Then
         $newPosA[1] = $newPosA[1]-1
      EndIf

      $CurrentDist = Distance($newposA,$B)
   WEnd


   return $newposA
EndFunc

 

Link to comment
Share on other sites

3 hours ago, Dohko said:

I badly name my var $step but its not step but the distance to do for a loop

OK. Then it just needs a little change in initialization:

Local $aPts = [ _
    [-1.58, 1.06], _        ; start point
    [6.06, 4.46], _         ; goal 1
    [-8.32, 7.44], _
    [-6.22, -7.3], _
    [3.02, -6.36] _         ; goal 4
]

Local $StepDist = 3.84      ; distance to move at every step (except the last)
For $i = 1 To UBound($aPts) - 1
    _Walk($aPts[0][0], $aPts[0][1], $aPts[$i][0], $aPts[$i][1], $StepDist)
Next

; walk from point (x0, y0) to point (x1, y1) moving at most dist at each step
Func _Walk($x0, $y0, $x1, $y1, $dist)
    Local $Steps = Sqrt(($x1 - $x0) ^ 2 + ($y1 - $y0) ^ 2) / $dist
    Local $dX = ($x1 - $x0) / $Steps, $dY = ($y1 - $y0) / $Steps
    For $i = 0 To Floor($Steps)
        ConsoleWrite('(' & Round($x0 + $dX * $i, 2) & ', ' & Round($y0 + $dY * $i, 2) & ')' & @LF)
    Next
    ConsoleWrite('(' & $x1 & ', ' & $y1 & ')' & @LF)
    ConsoleWrite(@LF)
EndFunc

NOTE: there was a couple of sign errors of point coordinates in my previous post (I wanted to illustrate all four quadrants).

Here you can see the walks in all quadrants. Some distances display slightly in excess of the limit, but that's a cosmetic effect due to marginal floating-point rounding. And still no trigonometry is needed.

EDIT: you may have to check that the last step is indeed required. It is not needed if ever the distance to go is an integral multiple of the step distance (pretty unlikely in random real-world data). Simply test whether $Step = Int($Step)

Walks.jpg

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...