Jump to content

[SOLVED] Line, coordinates


Recommended Posts

Hello everybody

Pic.png

I don't know how to explain this, but there are RED and BLUE dots, they make up a line, and I want to find out where is GREEN dot, in what side, and it would output TRUE or FALSE.
(there's coordinates/positions in picture)

Sorry for my bad English.

Edited by algiuxas
Updated picture

After switching years ago to Linux, sadly I don't use AutoIt anymore.

Link to comment
Share on other sites

ConsoleWrite(isTrue(4,1 , 10,10 , 3,9) & @CRLF)

Func isTrue($red_x, $red_y, $blue_x, $blue_y, $green_x, $green_y)
    Return (($blue_x - $red_x) * ($green_y - $red_y) - ($blue_y - $red_y) * ($green_x - $red_x) > 0)
EndFunc   ;==>isTrue

Note that this will also return "false" if the point is ON the line (you didn't specify that so I don't know whether that matters).

I'm not sure what you want to happen if the line goes from bottom left to top right or maybe the red/blue points are reversed, i.e. if the line is directed (i.e. the order of the red/blue determines the orientation of true/false), but this solution should work in reverse if the red/blue are reversed. Try it out with a few test values to make sure that this is what you wanted, if not, clarify with a few more examples.

This is really more of a math question I guess?

Edited by SadBunny
Added example line to code

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

Try this:

#include <GDIPlus.au3>
_GDIPlus_Startup()
$fRedX = 4
$fRedY = 1
$fBlueX = 10
$fBlueY = 10

$fGreenX = 3
$fGreenY = 9

Global $bResult = Check($fRedX, $fRedY, $fBlueX, $fBlueY, $fGreenX, $fGreenY)
MsgBox(0, "Test", $bResult)

_GDIPlus_Shutdown()

Func Check($fRX, $fRY, $fBX, $fBY, $fGX, $fGY, $iHeight = 5000)
    Local $hPath = _GDIPlus_PathCreate(), $bResult, $m, $b
    $m = ($fRX - $fBY) / ($fRY - $fBY) ;y = mx+b
    $b = $fRY - $m * $fRedX
    Local $aPoints[7][2] = [[6]]
    $aPoints[1][0] = 0
    $aPoints[1][1] = 0
    $aPoints[2][0] = -$b / $m   ;x at position $y = 0
    $aPoints[2][1] = 0
    $aPoints[3][0] = $fRX
    $aPoints[3][1] = $fRY
    $aPoints[4][0] = $fBX
    $aPoints[4][1] = $fBX
    $aPoints[5][0] = ($iHeight - $b) / $m
    $aPoints[5][1] = $iHeight
    $aPoints[6][0] = 0
    $aPoints[6][1] = $iHeight
    _GDIPlus_PathAddPolygon($hPath, $aPoints)
    $bResult = _GDIPlus_PathIsVisiblePoint($hPath, $fGX, $fGY)
    _GDIPlus_PathDispose($hPath)
    Switch $fRedY < $fBlueY
        Case True
            Return $bResult
        Case False
            Return $bResult * -1
    EndSwitch
EndFunc

 

Not tested!

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

5 minutes ago, UEZ said:

Try this:

#include <GDIPlus.au3>
_GDIPlus_Startup()
$fRedX = 4
$fRedY = 1
$fBlueX = 10
$fBlueY = 10

$fGreenX = 3
$fGreenY = 9

Global $bResult = Check($fRedX, $fRedY, $fBlueX, $fBlueY, $fGreenX, $fGreenY)
MsgBox(0, "Test", $bResult)

_GDIPlus_Shutdown()

Func Check($fRX, $fRY, $fBX, $fBY, $fGX, $fGY, $iHeight = 5000)
    Local $hPath = _GDIPlus_PathCreate(), $bResult, $m, $b
    $m = ($fRX - $fBY) / ($fRY - $fBY) ;y = mx+b
    $b = $fRY - $m * $fRedX
    Local $aPoints[7][2] = [[6]]
    $aPoints[1][0] = 0
    $aPoints[1][1] = 0
    $aPoints[2][0] = -$b / $m   ;x at position $y = 0
    $aPoints[2][1] = 0
    $aPoints[3][0] = $fRX
    $aPoints[3][1] = $fRY
    $aPoints[4][0] = $fBX
    $aPoints[4][1] = $fBX
    $aPoints[5][0] = ($iHeight - $b) / $m
    $aPoints[5][1] = $iHeight
    $aPoints[6][0] = 0
    $aPoints[6][1] = $iHeight
    _GDIPlus_PathAddPolygon($hPath, $aPoints)
    $bResult = _GDIPlus_PathIsVisiblePoint($hPath, $fGX, $fGY)
    _GDIPlus_PathDispose($hPath)
    Switch $fRedY < $fBlueY
        Case True
            Return $bResult
        Case False
            Return False
    EndSwitch
EndFunc

 

Not tested!

Thank you very much! It would be really great if you would made it a bit faster... It took about 12 ms for me, if I would need to run this function for 50 times script would be a bit slow... I'm making 3D graphics, so I need to make it work fast enough :)

After switching years ago to Linux, sadly I don't use AutoIt anymore.

Link to comment
Share on other sites

UEZ' code works with the given numbers, but:

  1. It risks division by zero (if $fRY - $fBY equals zero)
  2. Return $bResult * -1 is incorrect, as multiplying a boolean with *-1 returns -0 (for true) or -1 (for false). You probably meant Return Not $bResult

Have you tried my version? It is much shorter, much faster and probably works better too :)

 

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

5 minutes ago, SadBunny said:

UEZ' code works with the given numbers, but:

  1. It risks division by zero (if $fRY - $fBY equals zero)
  2. Return $bResult * -1 is incorrect, as multiplying a boolean with *-1 returns -0 (for true) or -1 (for false). You probably meant Return Not $bResult

Have you tried my version? It is much shorter, much faster and probably works better too :)

 

Sorry, I didn't checked it, but now I checked, it works perfectly! Thank you very much! :D

You are awesome!

Edited by algiuxas

After switching years ago to Linux, sadly I don't use AutoIt anymore.

Link to comment
Share on other sites

1 hour ago, SadBunny said:

UEZ' code works with the given numbers, but:

  1. It risks division by zero (if $fRY - $fBY equals zero)
  2. Return $bResult * -1 is incorrect, as multiplying a boolean with *-1 returns -0 (for true) or -1 (for false). You probably meant Return Not $bResult

Have you tried my version? It is much shorter, much faster and probably works better too :)

 

Yes you are right, Return $bResult * -1 is bullshit. I was in a hurry because of the football match. Of course it must be Return Not $bResult to invert the result.

Btw, there are many ways to solve a problem. Further if your result is = 0 then the green dot is on the line. What is the status then?

 

Your version is of course the fastest and best solution. :thumbsup:

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

1 minute ago, UEZ said:

I was in a hurry because of the football match.

Judging from the beautiful moustache on your profile picture I guess I will have to say congratulations :)

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

1 minute ago, SadBunny said:

Judging from the beautiful moustache on your profile picture I guess I will have to say congratulations :)

:'(

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

3 minutes ago, UEZ said:

:'(

Ah, in that case mein herzliches Beileid :) Being Dutch myself I don't care either way ;) It's just that Dalí's moustache seemed French rather than German.

Edited by SadBunny

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

1 minute ago, SadBunny said:

Ah, in that case mein herzliches Beileid :) Being Dutch myself I don't care either way ;) It's just that Dalí's moustache seemed French rather than German.

More Spanish. ;)

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Just now, UEZ said:

More Spanish. ;)

 Guess so :) But I had to choose between French and German for obvious reasons and I had nothing else to go on :) 

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

Global $ver = "by algiuxas"
Global $GUITitle = "3D render " & $ver


Global $GUI_Loading = GUICreate($GUITitle, 616, 37, -1, 100, -2147483648)
GUISetBkColor(0x000000)
Global $GUI_Loading_Ctrl_Label = GUICtrlCreateLabel("Loading...", 8, 8, 600, 23, 1)
GUICtrlSetFont(-1, 12, 800, 0, "Consolas")
GUICtrlSetColor(-1, 0xFFFFFF)
GUISetState(@SW_SHOW)
Func _GUI_CL($Text)
    GUICtrlSetData($GUI_Loading_Ctrl_Label, $Text)
EndFunc   ;==>_GUI_CL

#Region # Data
_GUI_CL("Loading data...")
Global $SizeX = 480
Global $SizeY = 320
Global $CtrX = $SizeX / 2
Global $CtrY = $SizeY / 2
Global $DPI = 84

Global $GM_BgColor = 0x33AAFF
Global $GM_FPS_MAX = 0
#EndRegion # Data
#Region # P-Data
Global $GM_EXT = False
#EndRegion # P-Data
#Region # GUI
_GUI_CL("Loading GUI...")
#include <GUIConstantsEx.au3>
Global $GUI = GUICreate($GUITitle, $SizeX, $SizeY)
GUISetBkColor(0x000000)

Opt("GUIOnEventMode", 1)
OnAutoItExitRegister("GM_Exit")
GUISetOnEvent($GUI_EVENT_CLOSE, "GM_Exit", $GUI)
#EndRegion # GUI
#Region # GDIPlus
_GUI_CL("Loading GDI+ functions...")
#include <GDIPlus.au3>
_GDIPlus_Startup()
Global $Graphics = _GDIPlus_GraphicsCreateFromHWND($GUI)
Global $Bitmap = _GDIPlus_BitmapCreateFromGraphics($SizeX, $SizeY, $Graphics)
Global $GfxCtxt = _GDIPlus_ImageGetGraphicsContext($Bitmap)
#EndRegion # GDIPlus
#Region # Images
_GUI_CL("Loading images...")
#EndRegion # Images
#Region # Keyboard Data
_GUI_CL("Loading input data...")
#include <Misc.au3>


#EndRegion # Keyboard Data
#Region # Calculation
#include <Math.au3>
Const $PI = 3.14159256358979
ConsoleWrite("PI=" & $PI & @CRLF)
Const $PI180 = $PI / 180
ConsoleWrite("PI180=" & $PI180 & @CRLF)
Const $DRAD = Round($PI180, 7)
ConsoleWrite("DRAD=" & $DRAD & @CRLF)

#EndRegion # Calculation
#Region # Colors
Global $Brush_T77_000000 = _GDIPlus_BrushCreateSolid(0x77000000)
Global $Brush_T77_FFFFFF = _GDIPlus_BrushCreateSolid(0x77FFFFFF)
Global $Pen_TFF_000000 = _GDIPlus_PenCreate(0xFF000000)
Global $Pen_TFF_FFFFFF = _GDIPlus_PenCreate(0xFFFFFFFF)

#EndRegion # Colors
#Region # Etc. Data
_GUI_CL("Loading other things...")
Global $GM_CFPS = 0
Global $GM_CFPS_F = 0
Global $GM_CFPS_TI = TimerInit()
Global $GMS = 0
Global $GM_SH = TimerInit()
Global $GM_Cursor[5]
Global $GM_Active = 0
#EndRegion # Etc. Data
#Region # Render Data
Global $FOV = FOV(90)

#EndRegion # Game Data
#cs
    $GM_Cursor[0-3] = [X,Y,1,2]
    $GM_Active = ACTIVE I/O
    $GMS = 1/FPS
#ce

$x = 0
$y = 0
$z = 0

GUIDelete($GUI_Loading)
GUISetState(@SW_SHOW)

While 1
    GM_Loop()
    #Region# Testing area
    Local $posarrn[4][3] = [[0, 5, 4], [-2, 7, 4], [0, 7, 4], [0, 7, 6]]
    Local $rotarr[3] = [$GM_Cursor[1]/150-$CtrX, -$GM_Cursor[0]/150-$CtrY, $z]
    Local $posarr = _3DrotArrMulti($rotarr, $posarrn,4)
    _3D_Pyra_3base($posarr)
    #EndRegion # Testing area
    _GDIPlus_GraphicsDrawString($GfxCtxt, "FPS: " & $GM_CFPS, 10, 10)
    _GDIPlus_GraphicsDrawString($GfxCtxt, "3DG " & $ver, 10, $SizeY - 30)
WEnd

Func _3D_Vector($pa, $lbrush = 0x77000000)
    ;[3][3] = [[x,y,z],[x,y,z],[x,y,z]]
    ;Triangle


    Local $aPnt
    Local $aPoints[4][2]
    $aPoints[0][0] = 3
    $aPnt = _3Dpos($pa[0][0], $pa[0][1], $pa[0][2])
    $aPoints[1][0] = $aPnt[0]
    $aPoints[1][1] = $aPnt[1]
    $aPnt = _3Dpos($pa[1][0], $pa[1][1], $pa[1][2])
    $aPoints[2][0] = $aPnt[0]
    $aPoints[2][1] = $aPnt[1]
    $aPnt = _3Dpos($pa[2][0], $pa[2][1], $pa[2][2])
    $aPoints[3][0] = $aPnt[0]
    $aPoints[3][1] = $aPnt[1]
    If lineAbw($aPoints[2][0],$aPoints[2][1],$aPoints[1][0],$aPoints[1][1],$aPoints[3][0],$aPoints[3][1]) Then
        Local $hBrush = _GDIPlus_BrushCreateSolid($lbrush)
        _GDIPlus_GraphicsFillPolygon($GfxCtxt,$aPoints, $hBrush)
        _GDIPlus_BrushDispose($hBrush)
    EndIf
EndFunc   ;==>_Draw_Vector
Func _3D_Pyra_3base($pr, $lBrush1 = 0xFFFF0000, $lBrush2 = 0xFFFFFFFF, $lBrush3 = 0xFF00FF00, $lBrush4 = 0xFF0000FF)
    ;[4][3] = [[x,y,z],[x,y,z],[x,y,z],[x,y,z]]
    ;       0
    ;     /\\
    ;    /  \ \
    ;   /    \  \
    ;  /______\--3
    ;  1      2
    _3D_Vector(_ArrayWR3($pr,0,1,2),$lBrush1)
    _3D_Vector(_ArrayWR3($pr,0,2,3),$lBrush2)
    _3D_Vector(_ArrayWR3($pr,0,3,1),$lBrush3)
    _3D_Vector(_ArrayWR3($pr,3,2,1),$lBrush4)

EndFunc   ;==>_3D_Pyra_3base
Func _ArrayWR1($pa,$i)
    Local $paa[3]
    $paa[0] = $pa[$i][0]
    $paa[1] = $pa[$i][1]
    $paa[2] = $pa[$i][2]
    Return $paa
EndFunc
Func _ArrayWR3($pa,$i1,$i2,$i3)
    Local $paa[3][3]
    $paa[0][0] = $pa[$i1][0]
    $paa[0][1] = $pa[$i1][1]
    $paa[0][2] = $pa[$i1][2]
    $paa[1][0] = $pa[$i2][0]
    $paa[1][1] = $pa[$i2][1]
    $paa[1][2] = $pa[$i2][2]
    $paa[2][0] = $pa[$i3][0]
    $paa[2][1] = $pa[$i3][1]
    $paa[2][2] = $pa[$i3][2]
    Return $paa
EndFunc
Func _3DrotArrMulti($pr, $pp, $a=4)
    ;[3],[~][3] = ROTATION, POSITION
    Local $ats[$a][3]
    For $i = 0 to $a-1
    $b = _3Drot($pr[0], $pr[1], $pr[2], $pp[$i][0], $pp[$i][1], $pp[$i][2])
    $ats[$i][0] = $b[0]
    $ats[$i][1] = $b[1]
    $ats[$i][2] = $b[2]
    Next
    Return $ats
EndFunc   ;==>
Func _3DrotArr($pr, $pp)
    ;ROTATION, POSITION
    Return _3Drot($pr[0], $pr[1], $pr[2], $pp[0], $pp[1], $pp[2])
EndFunc   ;==>_3DrotArr
Func _3Drot($x, $y, $z, $xp = 0, $yp = 0, $zp = 0)
    ;ROTATION, POSITION
    $XA = _
            Cos($y) * Cos($z) * $xp + _
            (Cos($z) * Sin($x) * Sin($y) - Cos($x) * Sin($z)) * $yp + _
            (Cos($x) * Cos($z) * Sin($y) + Sin($x) * Sin($z)) * $zp
    $YA = _
            (Cos($y) * Sin($z)) * $xp + _
            (Cos($x) * Cos($z) + Sin($x) * Sin($y) * Sin($z)) * $yp + _
            (-Cos($z) * Sin($x) + Cos($x) * Sin($y) * Sin($z)) * $zp
    $ZA = _
            (-Sin($y)) * $xp + _
            (Cos($y) * Sin($x)) * $yp + _
            (Cos($x) * Cos($y)) * $zp
    Local $pos[3] = [$XA, $YA, $ZA]
    Return $pos
EndFunc   ;==>_3Drot
Func _3DposArr($pos)
    Return _3Dpos($pos[0], $pos[1], $pos[2])
EndFunc   ;==>_3DposArr
Func _3Dpos($x, $y, $z)
    ;REMOVE DISTANCE FROM CENTER!
    $fvz = Round(($z + 15) / $FOV, 10)
    Local $pos[2] = [$x * $CtrX / 2 / $fvz + $CtrX, $y * $CtrY / 2 / $fvz + $CtrY]
    Return $pos
EndFunc   ;==>_3Dpos
Func lineAbw($rx, $ry, $bx, $by, $gx, $gy)
    Return (($bx - $rx) * ($gy - $ry) - ($by - $ry) * ($gx - $rx) > 0)
EndFunc   ;==>isTrue
Func FOV($FOVdegr = 90)
    $FOVdegr /= 2
    Return Round(ATan($DRAD * $FOVdegr) * 2, 7)
EndFunc   ;==>FOV
Func GM_Loop()
    $GMS = Floor(TimerDiff($GM_SH)) / 1000
    $GM_Cursor = GUIGetCursorInfo()
    If $GM_Cursor = 0 Then
        $GM_Active = 0
    Else
        $GM_Active = 1
    EndIf
    If $GM_FPS_MAX Then
        Do
            $GMS = Floor(TimerDiff($GM_SH)) / 1000
        Until $GMS > 1 / $GM_FPS_MAX
    EndIf
    $GM_SH = TimerInit()
    If TimerDiff($GM_CFPS_TI) > 1000 Then GM_FPS_RC()
    $GM_CFPS_F += 1
    _GDIPlus_GraphicsDrawImage($Graphics, $Bitmap, 0, 0)
    _GDIPlus_GraphicsClear($GfxCtxt, 0xFF000000 + $GM_BgColor)
EndFunc   ;==>GM_Loop
Func GM_SaveData()
    GM_CW("Saving data...")
    ;TODO: Save data
    GM_CWK("Saving data DONE!")
EndFunc   ;==>GM_SaveData
Func GM_FPS_RC()
    $GM_CFPS = Floor($GM_CFPS_F * 1000 / Floor(TimerDiff($GM_CFPS_TI)))
    $GM_CFPS_TI = TimerInit()
    $GM_CFPS_F = 0
EndFunc   ;==>GM_FPS_RC
Func GM_Exit()
    If $GM_EXT = True Then Exit
    $GM_EXT = True
    GUIDelete()
    GM_SaveData()
    ;TODO: Execute game closing functions
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>GM_Exit
Func GM_CW($CW)
    ConsoleWrite("!> " & $CW & @CRLF)
EndFunc   ;==>GM_CW
Func GM_CWK($CW)
    ConsoleWrite("+> " & $CW & @CRLF)
EndFunc   ;==>GM_CWK


Func getAngle($x1,$y1,$x2,$y2)
    Return ATAN2($x2-$x1,$y2-$y1)
EndFunc
Func ATAN2(Const $NY, Const $NX)
    Const $NPI = 3.14159265358979
    Local $NRESULT
    If IsNumber($NY) = 0 Then
        SetError(1)
        Return 0
    ElseIf IsNumber($NX) = 0 Then
        SetError(1)
        Return 0
    EndIf
    If $NX = 0 Then
        If $NY > 0 Then
            $NRESULT = $NPI / 2
        ElseIf $NY < 0 Then
            $NRESULT = 3 * $NPI / 2
        Else
            SetError(2)
            Return 0
        EndIf
    ElseIf $NX < 0 Then
        $NRESULT = ATan($NY / $NX) + $NPI
    Else
        $NRESULT = ATan($NY / $NX)
    EndIf
    While $NRESULT < 0
        $NRESULT += 2 * $NPI
    WEnd
    Return $NRESULT
EndFunc

I know that this is a huge mess... I will fix everything later, and make it better. :)
Try this script, and move mouse.

After switching years ago to Linux, sadly I don't use AutoIt anymore.

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...