Jump to content
Sign in to follow this  
Arathalion

GUICtrlCreatePic coordinates problem

Recommended Posts

Arathalion

For a while now i've been working on a script that does something called diffusion limited aggregation (DLA) (for more info, go here)

So, my script is meant to generate these coral-like thingy's.

BUT it's not working properly, and i can't figure it out.

Basically, some dots are stopping when they're only near another, not right next to it, like they should. and if i decrease the range to stop them, they get stuck in a 3x3 square in the middle. as if the new dots are the same coordinates as the old one.

for a basic explanation of what my script does:

1)create gui with dot in middle

2)create randomly placed dot within restricted area

3)move dot around randomly until it is next not another dot

4)expand restricted area of movement if necessary.

5)repeat step 2-4 for x many times.

6)create msgbox with co-ordinates of each dot on it.

for an example of my problem, click here.

(in this example, i restricted it to about 5 dots - that sized gui is designed for a lot more)

you can see how some dots are not next to any others - not even diagonally.

why is this happening? i can't figure it out.

i'm going to post my entire script - sorry folks, i just can't figure out where i've gone wrong at all. i've tried everything i can think of.

and if you have a possible solution - it'd be great if you could test it before posting - i've had lots of ideas that haven't worked.

if you want the code as a file, it's here.

this .bmp is needed to run it, it needs placing in c:\

main input variables:

$GUI_Height, $GUI_Width = height and width of the GUI

$DotNum is how many dots to plot

;====================================================================================
;A dead simple DLA (diffusion limited aggregation) generator.
;====================================================================================
#include <GUIConstants.au3>



Opt("TrayIconDebug", 1)

$GUI_Height=500
$GUI_Width=500
$DotPosLeft=$GUI_Width/2
$DotPosTop=$GUI_Height/2
$DotNum = 4

GUICreate("DLA", $GUI_Height,$GUI_Width)
GUISetBkColor (0xFFFFFF) 
GUISetState( )


global const $BorderSize = 5
global $Dot[3][$DotNum+1]
global const $GUI_ID = 0
global const $ArrayPosLeft = 1
global const $ArrayPosTop = 2

global $AreaTop = $GUI_Height/2 + $BorderSize
global $AreaBottom = $GUI_Height/2 - $BorderSize
global $AreaRight = $GUI_Width/2 + $BorderSize
global $AreaLeft = $GUI_Width/2 - $BorderSize

;==========================================
;first dot defaults. 
;==========================================
$Dot[$GUI_ID][0] = GUICtrlCreatePic("c:\dot.bmp",$DotPosLeft,$DotPosTop,1,1)
$Dot[$ArrayPosLeft][0] = $DotPosLeft
$Dot[$ArrayPosTop][0] = $DotPosTop


;==========================================
;Main executed section. 
;==========================================
for $CurrentDot = 1 to $DotNum;1 to $DotNum
    $RanStartPosLeft = random($AreaLeft, $AreaRight, 1);generate random start points for new dots
    $RanStartPosTop = random($AreaBottom, $AreaTop, 1)
    $Dot[$GUI_ID][$CurrentDot] = GUICtrlCreatePic("c:\dot.bmp",$RanStartPosLeft,$RanStartPosTop,0,0);create a new dot
    move() ;move said dot.
next
sleep (1000)


;==========================================
;returns message co-ordinates of each dot (for testing purposes)
;==========================================
$Message = ""
for $MsgProgress = 0 to $DotNum
$Message = $Message & "dot" & $MsgProgress & " is at location " &$Dot[$ArrayPosLeft][$MsgProgress]& "," & $Dot[$ArrayPosTop][$MsgProgress] & @lf
next
msgbox(0, "", $Message)
exit


;==========================================
;moves the dot around randomly
;==========================================
func move()
local $MoveCount = 1
global $DotPosLeft = $RanStartPosLeft
global $DotPosTop = $RanStartPosTop
while $MoveCount > 0

    $MoveCount = $MoveCount+1
    $DotPosTop=$DotPosTop+Random(-1, 1, 1)
    $DotPosLeft=$DotPosLeft+Random(-1, 1, 1)
    if $DotPosLeft > $AreaRight then $DotPosLeft = $AreaLeft
    if $DotPosLeft < $AreaLeft then $DotPosLeft = $AreaRight
    if $DotPosTop > $AreaTop then $DotPosTop = $AreaBottom
    if $DotPosTop < $AreaBottom then $DotPosTop = $AreaTop


        ;Supposed to stop the dot moving if it falls within certain parameters
        ;IE next to another dot.

    for $PCheckProg = 0 to $CurrentDot-1
        
        If (Abs($DotPosLeft - $Dot[$ArrayPosLeft][$PCheckProg]) <=1) And _
           (Abs($DotPosTop - $Dot[$ArrayPosTop][$PCheckProg]) <=1) Then
            exitloop(2)
        EndIf
    next

    GUICtrlSetPos ($Dot[$GUI_ID][$CurrentDot], $DotPosLeft, $DotPosTop)
;sleep(1)
wend
$Dot[$ArrayPosLeft][$CurrentDot] = $DotPosLeft
$Dot[$ArrayPosTop][$CurrentDot] = $DotPosTop


;msgbox (0,"", $DotPosLeft+5 & " " & $areatop)
If ($DotPosTop+$BorderSize) > $AreaTop then $AreaTop = ($DotPosTop+$BorderSize)
If ($DotPosTop-$BorderSize) < $AreaBottom then $AreaBottom = ($DotPosTop-$BorderSize)
If ($DotPosLeft+$BorderSize) > $AreaRight then $AreaRight = ($DotPosLeft+$BorderSize)
If ($DotPosLeft-$BorderSize) < $AreaLeft then $AreaLeft = ($DotPosLeft-$BorderSize)
 
endfunc

Thanks guys, in advance.

EDIT: clarification; fixing code/comments

Edited by Arathalion

Share this post


Link to post
Share on other sites
phillip123adams

Top and Left are reversed. Change the following

$Dot[$ArrayPosLeft][$CurrentDot] = $DotPosTop
  $Dot[$ArrayPosTop][$CurrentDot] = $DotPosLeft

to

$Dot[$ArrayPosLeft][$CurrentDot] = $DotPosLeft
  $Dot[$ArrayPosTop][$CurrentDot] = $DotPosTop

Phillip

Share this post


Link to post
Share on other sites
Arathalion

Top and Left are reversed.  Change the following

$Dot[$ArrayPosLeft][$CurrentDot] = $DotPosTop
  $Dot[$ArrayPosTop][$CurrentDot] = $DotPosLeft

to

$Dot[$ArrayPosLeft][$CurrentDot] = $DotPosLeft
  $Dot[$ArrayPosTop][$CurrentDot] = $DotPosTop

<{POST_SNAPBACK}>

You are correct, thankyou. i have now corrected that mistake, but the original problem persists.

Share this post


Link to post
Share on other sites
phillip123adams

You are correct, thankyou. i have now corrected that mistake, but the original problem persists.

<{POST_SNAPBACK}>

Oops! I ran it 3 times, all with positive results. After your reply, I ran it again and it failed. So I looked a little deeper and found that the closing parenthesis for the "Abs" functions is in the wrong place. I did a few more tests and it looks okay. Change

If (Abs($DotPosLeft - $Dot[$ArrayPosLeft][$PCheckProg]) <= 1) And _
                (Abs($DotPosTop - $Dot[$ArrayPosTop][$PCheckProg]) <= 1) Then

to

If (Abs($DotPosLeft - $Dot[$ArrayPosLeft][$PCheckProg]) <= 1 And _
                Abs($DotPosTop - $Dot[$ArrayPosTop][$PCheckProg]) <= 1) Then

Could you post the BMP? I'd like to watch it develop the pattern with a large loop.


Phillip

Share this post


Link to post
Share on other sites
Arathalion

Oops!  I ran it 3 times, all with positive results.  After your reply, I ran it again and it failed.  So I looked a little deeper and found that the closing parenthesis for the "Abs" functions is in the wrong place.  I did a few more tests and it looks okay.  Change

If (Abs($DotPosLeft - $Dot[$ArrayPosLeft][$PCheckProg]) <= 1) And _
                (Abs($DotPosTop - $Dot[$ArrayPosTop][$PCheckProg]) <= 1) Then

to

If (Abs($DotPosLeft - $Dot[$ArrayPosLeft][$PCheckProg]) <= 1 And _
                Abs($DotPosTop - $Dot[$ArrayPosTop][$PCheckProg]) <= 1) Then

Could you post the BMP?  I'd like to watch it develop the pattern with a large loop.

<{POST_SNAPBACK}>

thanks again! but (again) it seems to still be having the same problem - there are still gaps between the dots.

would you mind briefly explaining why you suggested the above result? i don't understand the difference that it would make.

and here is the .bmp. it needs dropping onto the c:, it's just a black, 1x1 BMP basically.

EDIT: spelling

Edited by Arathalion

Share this post


Link to post
Share on other sites
phillip123adams

thanks again! but (again) it seems to still be having the same problem - there are still gaps between the dots.

would you mind briefly explaining why you suggested the above result? i don't understand the difference that it would make.

<{POST_SNAPBACK}>

Sorry, I was called away. Thanks for the BMP.

You're right, it comes out the same either way. I mistakenly saw the closing parenthesis on each line as the closing parenthesis for the Abs function (much as Lisp works). When I changed it and ran a few tests, all was well.

That said, the outer parenthesis are not needed as each side of the "And" evaluates completely when done either way. For example, the following works without the outer parenthesis:

If Abs($DotPosLeft - $Dot[$ArrayPosLeft][$PCheckProg]) <= 1 And _
    Abs($DotPosTop - $Dot[$ArrayPosTop][$PCheckProg]) <= 1 Then

Back to the problem. Every run I make seems to be correct to me. That is, dot 2 is within 1,1 of dot 1 and dot 3 is within 1,1 of either dot 1 or dot 2, and so on. In other words each subsequent dot is within one pixel measured either horizontally, vertically, or diagonally, from at least one of the previous dots.

I increased the $DotNum to 15 in the following. It is typical of the results I get. Are the results incorrect?

Sometimes more than one dot will be at the same coordinate. That's because the script does not test for that conditon. Is it permissible?

Phillip

Share this post


Link to post
Share on other sites
Arathalion

Sorry, I was called away.  Thanks for the BMP.

You're right, it comes out the same either way.  I mistakenly saw the closing parenthesis on each line as the closing parenthesis for the Abs function (much as Lisp works).  When I changed it and ran a few tests, all was well.

That said, the outer parenthesis are not needed as each side of the "And" evaluates completely when done either way.  For example, the following works without the outer parenthesis:

If Abs($DotPosLeft - $Dot[$ArrayPosLeft][$PCheckProg]) <= 1 And _
    Abs($DotPosTop - $Dot[$ArrayPosTop][$PCheckProg]) <= 1 Then

Back to the problem.  Every run I make seems to be correct to me.  That is, dot 2 is within 1,1 of dot 1 and dot 3 is within 1,1 of either dot 1 or dot 2, and so on.  In other words each subsequent dot is within one pixel measured either horizontally, vertically, or diagonally, from at least one of the previous dots.

I increased the $DotNum to 15 in the following.  It is typical of the results I get.  Are the results incorrect?

Sometimes more than one dot will be at the same coordinate. That's because the script does not test for that conditon. Is it permissible?

<{POST_SNAPBACK}>

ok, thanks for explaining that (and for taking the time to actually look at this for me, highly appreciated)

your points _seem_ fine - what i'd expect! and you're right, if properly plotted, they should work.

if it's working for you, would you mind posting the actual image, not just the co-ordinates? so i can visualise a bit better.

I'm still getting the former problem. maybe i didn't explain it clearly. i've done this picture to show you. it shows how it actually plotted - and what was wrong with that.

a dot should only stick if it's right next to another one - including diagonally.

the results i'm getting - well, they're "sticking" as far away as 3x3, if you look at the top left one in that picture.

the msgbox doesn't seem to be properly representing what is shown. if i plot the points it says, here is the image i should have got - and it is rather different. also, if these dots were properly plotted, it would give a correct image. so at least one part works properly.

i have a few trains of thought:

1) the BMP is registering incorrectly - and while only appearing to be 1x1, it's actually 3x3.

2) i've done some some check wrongly - a number 1 too high or low could be everything.

3) i've made some silly typo

4) points 2+3

thanks once again, this has been frustrating me so!

Edited by Arathalion

Share this post


Link to post
Share on other sites
phillip123adams

Okay, I think I see, the coordinates are right but it's not plotting correctly. I could not see that at 1600x1200. I set a lower resolution and then enlarged a screen shot to see what you mean.

I brought DOT.BMP into Irfan and it says the size is 1x1.

The problem is the loop is exited without re-positioning the current dot.

Move the following

GUICtrlSetPos($Dot[$GUI_ID][$CurrentDot], $DotPosLeft, $DotPosTop)

outside of the While/Wend loop

WEnd
GUICtrlSetPos($Dot[$GUI_ID][$CurrentDot], $DotPosLeft, $DotPosTop)

Before doing this, the plot was as you describe. Afterwards, the plot looks correct to me. I have attached an enlarged screen shot of the dots and the message box results.


Phillip

Share this post


Link to post
Share on other sites
Arathalion

Okay, I think I see, the coordinates are right but it's not plotting correctly.  I could not see that at 1600x1200.  I set a lower resolution and then enlarged a screen shot to see what you mean.

I brought DOT.BMP into Irfan and it says the size is 1x1.

The problem is the loop is exited without re-positioning the current dot.

Move the following

GUICtrlSetPos($Dot[$GUI_ID][$CurrentDot], $DotPosLeft, $DotPosTop)

outside of the While/Wend loop

WEnd
GUICtrlSetPos($Dot[$GUI_ID][$CurrentDot], $DotPosLeft, $DotPosTop)

Before doing this, the plot was as you describe.  Afterwards, the plot looks correct to me.  I have attached an enlarged screen shot of the dots and the message box results.

<{POST_SNAPBACK}>

Ah! it works!! thankyou SO SO much! i've been trying to get that to work for weeks now! i can't tell you how grateful i am! that is absolutely perfect, thankyou very much!

hopefully, soon, you'll see this with a proper GUI and with colour, in the scripts + scraps section.

Share this post


Link to post
Share on other sites
phillip123adams

Ah! it works!! thankyou SO SO much! i've been trying to get that to work for weeks now! i can't tell you how grateful i am! that is absolutely perfect, thankyou very much!

hopefully, soon, you'll see this with a proper GUI and with colour, in the scripts + scraps section.

<{POST_SNAPBACK}>

Happy to have helped, and glad to see your frustration has abated. A fresh pair of eyes is sometimes useful. I'll be watching for the public release. In the meantime, I'm going to set $DotNum alot higher and see if it will give me some interesting patterns (even though only in B&W).

Phillip

Share this post


Link to post
Share on other sites
therks

I haven't tried this script. But the gist I'm getting from your conversation is that you're using multiple Pic controls to create these dots. If you would like to download JPM's release, it has a Graphic control, which allows you to actually draw. Just seems to me that it would be more efficient than making several controls.

Also, as an afterthought, there is the Dll SetPixel function that layer was experimenting with a while ago.

Func SetPixel ($handle, $x, $y, $color)
    $dc= DllCall ("user32.dll", "int", "GetDC", "hwnd", $handle)
    DllCall ("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", $color)
    DllCall ("user32.dll", "int", "ReleaseDC", "hwnd", 0,  "int", $dc[0])
EndFunc
Edited by Saunders

Share this post


Link to post
Share on other sites
zcoacoaz

JPM's release probably would have solved it for you really early because it has GuiCtrlCreateGraphic


[font="Times"] If anyone remembers me, I am back. Maybe to stay, maybe not.----------------------------------------------------------------------------------------------------------[/font][font="Times"]Things I am proud of: Pong! in AutoIt | SearchbarMy website: F.R.I.E.S.A little website that is trying to get started: http://thepiratelounge.net/ (not mine)[/font][font="Times"] ----------------------------------------------------------------------------------------------------------[/font][font="Arial"]The newbies need to stop stealing avatars!!! It is confusing!![/font]

Share this post


Link to post
Share on other sites
Arathalion

I haven't tried this script. But the gist I'm getting from your conversation is that you're using multiple Pic controls to create these dots. If you would like to download JPM's release, it has a Graphic control, which allows you to actually draw. Just seems to me that it would be more efficient than making several controls.

Also, as an afterthought, there is the Dll SetPixel function that layer was experimenting with a while ago.

Func SetPixel ($handle, $x, $y, $color)
    $dc= DllCall ("user32.dll", "int", "GetDC", "hwnd", $handle)
    DllCall ("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", $color)
    DllCall ("user32.dll", "int", "ReleaseDC", "hwnd", 0,  "int", $dc[0])
EndFunc

<{POST_SNAPBACK}>

JPM's release probably would have solved it for you really early because it has GuiCtrlCreateGraphic

Thanks - i've been looking at the release and it looks seriously awesome - can't wait for the proper release. hopefully i'll manage to implement it.

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.