buzz44 Posted April 3, 2005 Posted April 3, 2005 (edited) cool, thats useful, i noticed that there is a limit on how much you can draw, eg, when it takes reaches the point it takes away line from the oldest line there,like if your familiar with some vidoe games, there is a limit of how many bullets holes you can put in a wall, say the limit is 5, and u make 5, then click one more it will delete the very first one you made then make he 6th one, so you always have 5edit: silly post lol, i didnt read all of your above post and realised you had already mentioned it , did you add that or can it only handle so much "line"? Edited April 3, 2005 by burrup qq
erifash Posted April 3, 2005 Author Posted April 3, 2005 (edited) That is pretty cool!Also, after 30 minutes of tinkering with different algorithims I got it to store all the control id's of the line into an array so you can delete the line using GUICtrlDelete inside a For... Next loop!!! Yay! expandcollapse popup#include <GUIConstants.au3> Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size = 1, $color = "0x000000") $coeff_line = ( $y2-$y1 ) / ( $x2-$x1 ) $p = $y2 - ( $coeff_line * $x2 ) $alg = Int((Abs($x2 - $x1)) / $size) Dim $id[$alg + 2] $id[0] = $alg + 1 For $a = $x1 to $x2 step $size $alg = Int((Abs($x2 - $a)) / $size) $id[$alg + 1] = GUICtrlCreateLabel("", $a, ( $a * $coeff_line ) + $p, $size, $size) GUICtrlSetBkColor($id[$alg + 1], $color) Next Return $id EndFunc GUICreate("Linear Example", 320, 320) $x = GUICtrlCreateLine(50, 50, 200, 300, 1, "0xFF0000") $y = GUICtrlCreateLine(50, 300, 300, 20, 5, "0x00FF00") $z = GUICtrlCreateLine(20, 200, 250, 100, 10, "0x0000FF") GUISetState() Do $msg = GUIGetMsg() Sleep(10) Until $msg = $GUI_EVENT_CLOSE For $i = 1 to $x[0] GUICtrlDelete($x[$i]) Next For $i = 1 to $y[0] GUICtrlDelete($y[$i]) Next For $i = 1 to $z[0] GUICtrlDelete($z[$i]) Next Sleep(3000)Check that out!EDIT: Slight code update. Edited April 3, 2005 by erifash My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver
Smed Posted April 3, 2005 Posted April 3, 2005 @sylvanie, I'll just stick with my parameterized version. You are correct, but why kludge for a special case when it doesn't fix the whole problem. @Burrup, the limit on controls is 4096 so I added the erase old stuff code just to make sure you never run out. I've changed the Circle tool to an Oval tool because after all, a circle is just a special case of an oval. Also changed the behavior to mimic the oval tool in PSP sice this is a little more intuitive for most people and it eliminates the posibility that most of the shape will be outside the window or drawn over the 'forbidden region' at the top. I haven't even looked for the bug that pops up the "Can't draw There!" dialog when you click a mode button when in the same mode. But I made a minor tweak that makes it a tiny bit less annoying when it happens in Freehand mode Updated Code: expandcollapse popup#include <GUIConstants.au3> #include <math.au3> Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size = 1, $color = "0x000000") $deltaX = $x2 - $x1 $deltaY = $y2 - $y1 ; $slope = $deltaY/$deltaX $length = _Ceil (Sqrt ($deltaX*$deltaX + $deltaY*$deltaY)) $incDeltaX = $deltaX/$length $incDeltaY = $deltaY/$length For $i = 0 to $length GUICtrlDelete($controlIDs[$nextControl]) $controlIDs[$nextControl] = GUICtrlCreateLabel("", $x1 + $incDeltaX*$i, $y1 + $incDeltaY*$i, $size, $size) GUICtrlSetBkColor($controlIDs[$nextControl], $color) $nextControl = Mod ($nextControl + 1, $maxControls) Next Return 1 EndFunc Func GUICtrlCreateRectangle($x1, $y1, $x2, $y2, $size = 1, $color = "0x000000") If Not GUICtrlCreateLine($x1, $y1, $x2, $y1, $size, $color) Then Return 0 If Not GUICtrlCreateLine($x2, $y1, $x2, $y2, $size, $color) Then Return 0 If Not GUICtrlCreateLine($x2, $y2, $x1, $y2, $size, $color) Then Return 0 If Not GUICtrlCreateLine($x1, $y2, $x1, $y1, $size, $color) Then Return 0 Return 1 EndFunc Func GUICtrlCreateOval($x1, $y1, $x2, $y2, $size = 1, $color = "0x000000") $centerX = $x2 - ($x2 - $x1)/2 $centerY = $y2 - ($y2 - $y1)/2 $radiusX = Abs ($centerX - $x1) $radiusY = Abs ($centerY - $y1) $px = $centerX + Cos(0)*$radiusX $py = $centerY + Sin(0)*$radiusY $deltaTheta = $piX2/$radiusX ; This needs to be better thought through For $theta = $deltaTheta To $piX2 + $deltaTheta Step $deltaTheta $nx = $centerX + Cos($theta)*$radiusX $ny = $centerY + Sin($theta)*$radiusY If Not GUICtrlCreateLine($px, $py, $nx, $ny, $size, $color) Then Return 0 $px = $nx $py = $ny Next Return 1 EndFunc GUICreate("Doodle") $fbutton = GUICtrlCreateButton("Freehand", 10, 10, 80, 20) $lbutton = GUICtrlCreateButton("Line", 100, 10, 80, 20) $rbutton = GUICtrlCreateButton("Rectangle", 190, 10, 80, 20) $cbutton = GUICtrlCreateButton("Oval", 280, 10, 80, 20) $label = GUICtrlCreateLabel("", 10, 40, 360, 15) GUISetState() $nextControl = 0 $maxControls = 4000 Dim $controlIDs[$maxControls] $piX2 = 2*3.14159265358979 $mode = 0; default to Freehand mode Dim $points[2][2] $pointsSet = 0 Dim $tips[4] $tips[0] = "Click, Hold and Move Mouse to Draw Freehand" $tips[1] = "Click Each End Point to Draw a Line" $tips[2] = "Click Opposing Corners to Draw a Rectangle" $tips[3] = "Click Opposing Corners to Draw an Oval inside the Defined Rectangle" $mouseDown = 0 Do GUICtrlSetData($label, $tips[$mode]) $msg = GUIGetMsg(1) $handeled = 0 Select Case $msg[0] = $fbutton $mode = 0 $pointsSet = 0 $handeled = 1 Case $msg[0] = $lbutton $mode = 1 $pointsSet = 0 $handeled = 1 Case $msg[0] = $rbutton $mode = 2 $pointsSet = 0 $handeled = 1 Case $msg[0] = $cbutton $mode = 3 $pointsSet = 0 $handeled = 1 Case $msg[0] = $GUI_EVENT_PRIMARYDOWN $mouseDown = 1 If $msg[4] < 60 Then MsgBox(0, "Error!", "Can't Draw There!") $mouseDown = 0 ElseIf $mode Then $points[$pointsSet][0] = $msg[3] $points[$pointsSet][1] = $msg[4] $pointsSet = $pointsSet + 1 Select Case $mode = 1 And $pointsSet = 2 GUICtrlCreateLine ($points[0][0], $points[0][1], $points[1][0], $points[1][1], 1, "0x000000") $pointsSet = 0 Case $mode = 2 And $pointsSet = 2 GUICtrlCreateRectangle ($points[0][0], $points[0][1], $points[1][0], $points[1][1], 1, "0x000000") $pointsSet = 0 Case $mode = 3 And $pointsSet = 2 GUICtrlCreateOval ($points[0][0], $points[0][1], $points[1][0], $points[1][1], 1, "0x000000") $pointsSet = 0 EndSelect Else $points[0][0] = $msg[3] $points[0][1] = $msg[4] EndIf $handeled = 1 Case $msg[0] = $GUI_EVENT_MOUSEMOVE And $mouseDown And $mode = 0 If $msg[4] < 60 Then MsgBox(0, "Error!", "Can't Draw There!") $mouseDown = 0 Else GUICtrlCreateLine ($points[0][0], $points[0][1], $msg[3], $msg[4], 1, "0x000000") $points[0][0] = $msg[3] $points[0][1] = $msg[4] EndIf Case $msg[0] = $GUI_EVENT_PRIMARYUP $mouseDown = 0 $handeled = 1 EndSelect Until $msg[0] = $GUI_EVENT_CLOSE Whether I will keep updating this is questionable, I really do have better things to do with my time, but it is an amusing distraction. Any suggestions are welcome. Oh, and before someone else points out that you can't make an oval that doesn't have its axes aligned with the x and y axes, I'm thinking about it. Maybe tomorrow. 601DisengageEnd Program
Smed Posted April 3, 2005 Posted April 3, 2005 @erifash, Excelent idea, much better than the way I did it with a global array! Keeps the interface clean. Sigh... gonna have to fix that now.... 601DisengageEnd Program
erifash Posted April 3, 2005 Author Posted April 3, 2005 (edited) @erifash, Excelent idea, much better than the way I did it with a global array! Keeps the interface clean.<{POST_SNAPBACK}>Thanks Smed! Sigh... gonna have to fix that now....  <{POST_SNAPBACK}>Yeah, but it will be even more efficient than it was! Edited April 3, 2005 by erifash My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver
erifash Posted April 3, 2005 Author Posted April 3, 2005 (edited) Smed and I came up with a function to delete a control group in an array so I put everything together in a UDF. ...and here is the example: #include <GUIConstants.au3> #include <line.au3> GUICreate("Linear Example", 320, 320) $x = GUICtrlCreateLine(50, 50, 200, 300, 1, "0xFF0000") $y = GUICtrlCreateLine(50, 300, 300, 20, 5, "0x00FF00") $z = GUICtrlCreateLine(20, 200, 250, 100, 10, "0x0000FF") GUISetState() Do $msg = GUIGetMsg() Sleep(10) Until $msg = $GUI_EVENT_CLOSE GUICtrlDeleteGroup($x) GUICtrlDeleteGroup($y) GUICtrlDeleteGroup($z) Sleep(3000) Hope you like it! Edited April 3, 2005 by erifash My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver
Ejoc Posted April 3, 2005 Posted April 3, 2005 (edited) Oh Oh!! I've seen this $alg = Int((Abs($x2 - $x1)) / $size) Dim $id[$alg + 2] Thats some seriously slick code Edited April 3, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
erifash Posted April 3, 2005 Author Posted April 3, 2005 (edited) Oh Oh!! I've seen this $alg = Int((Abs($x2 - $x1)) / $size)Dim $id[$alg + 2]Thats some seriously slick code <{POST_SNAPBACK}>Thank you, that part you helped me with. Also Sylvanie showed me that I could just use y=ax+b to draw the line. Sheesh, I learned that in Pre-Algebra and I totally forgot about it. Thanks for the compliments! Edited April 4, 2005 by erifash My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver
sylvanie Posted April 4, 2005 Posted April 4, 2005 Hello I have downloaded your last code Erifash. Be careful, you have forgotten 2 cases : 1) vertical lines (thanks Smed). If $x1=$x2, you devide by 0... If you add the case $x1=$x2 (cf my last post above), you can draw all lines. 2) if $x1>$x2 it doesn't work, so we have to permute the variable I have modified your last code : expandcollapse popup#include-once #include <GUIConstants.au3> Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size = 1, $color = "0x000000") if $x1<>$x2 Then $coeff_line = ( $y2-$y1 ) / ( $x2-$x1 ) $p = $y2 - ( $coeff_line * $x2 ) $alg = Int((Abs($x2 - $x1)) / $size) Dim $id[$alg + 2] $id[0] = $alg + 1 if $x1>$x2 Then $tmp=$x1 $x1=$x2 $x2=$tmp Endif For $a = $x1 to $x2 step $size $alg = Int((Abs($x2 - $a)) / $size) $id[$alg + 1] = GUICtrlCreateLabel("", $a, ( $a * $coeff_line ) + $p, $size, $size) GUICtrlSetBkColor($id[$alg + 1], $color) Next Return $id Else $alg = Int((Abs($y2 - $y1)) / $size) Dim $id[$alg + 2] $id[0] = $alg + 1 if $y1>$y2 Then $tmp=$y1 $y1=$y2 $y2=$tmp Endif For $a = $y1 to $y2 step $size $alg = Int((Abs($y2 - $a)) / $size) $id[$alg + 1] = GUICtrlCreateLabel("", $x1, $a, $size, $size) GUICtrlSetBkColor($id[$alg + 1], $color) Next Return $id EndIf EndFunc Func GUICtrlDeleteGroup($array) If not IsArray($array) then Return 0 For $i = 1 to $array[0] GUICtrlDelete($array[$i]) Next Return 1 EndFunc GUICreate("") $l0=GUICtrlCreateLine(50,0,60,100,1,"0xff00ff") $l1=GUICtrlCreateLine(160,0,150,100,1,"0xff0000") $l2=GUICtrlCreateLine(50,0,50,100,1,"0xffff00") $l3=GUICtrlCreateLine(160,100,160,0,1,"0x000000") GUISetState() Do $msg = GUIGetMsg() Sleep(10) Until $msg = $GUI_EVENT_CLOSE GUICtrlDeleteGroup($l0) GUICtrlDeleteGroup($l1) GUICtrlDeleteGroup($l2) GUICtrlDeleteGroup($l3) So, all lines can be drawn with this method
Smed Posted April 5, 2005 Posted April 5, 2005 Latest version of Doodle, Fixed: Can't Draw There! bug. Problem: PRIMARYDOWN event occurs before the control event, and the message box prevents GUI from receiving PRIMARYUP message. Solution: Get rid of the message box. Changed: Thanks to erifash for coming up with the Brilliant Idea of saving Control Groups in an array instead of the Silly Way I did it with global variables, I did a full code rework to handle this. Added: An 'Undo' Button Notes: It can be tediously slow sometimes. When it says "WAIT!", just wait, its doing its thing. Known Bugs: 1. You can't set a single pixel, life is tough, deal with it. 2. If you click somewhere you've already drawn, its not handeled correctly, but does not cause a failure. Code is here: doodle_0.2.au3 This code does not use erifash's line.au3 for two reasons. 1. I disagree with sylvanie's usage of the y=ax+b method for drawing lines. His latest posted code is 34 lines. My parameterized version is still only 20 lines. 2. I couldn't in good conscience put the array size in the first element in the array, so I had to redo everything with UBound. I hope the attachment works. First time I've tried that 601DisengageEnd Program
buzz44 Posted April 5, 2005 Posted April 5, 2005 Should stop the label flickering, so it should only update if it has changed. qq
Smed Posted April 5, 2005 Posted April 5, 2005 Should stop the label flickering, so it should only update if it has changed.<{POST_SNAPBACK}>Fixed:doodle_0.2.au3 601DisengageEnd Program
buzz44 Posted April 5, 2005 Posted April 5, 2005 (edited) Nice .Edit: I somehow managed to create these with the oval function...Bug? or new idea to create kits . Edited April 5, 2005 by burrup qq
Smed Posted April 5, 2005 Posted April 5, 2005 (edited) The screenshot sucks. The left one looks ok, but the right one looks like a bug. Is it repeatable? Tell me how. EDIT: If you click before the "WAIT!" message goes away behaviour may be unpredictable. Edited April 5, 2005 by Smed 601DisengageEnd Program
buzz44 Posted April 5, 2005 Posted April 5, 2005 (edited) Pfft, my SS is good, I cropped it to cut all the other crap out. Well what I done was click the Oval tool, then I click randomly in an oval shape, and some times it draws kits that that. Thats seems to be as big as they get but.Edit:This time it drew a really small triangle lol, but no kites. Edited April 5, 2005 by burrup qq
Smed Posted April 5, 2005 Posted April 5, 2005 I'm sure it looks fine there, but on the web page I got a nearly black image. By looking very closely I was able to pick out the two shapes. The Point being, if you can't tell me how to reproduce the problem. I can't fix it. 601DisengageEnd Program
buzz44 Posted April 5, 2005 Posted April 5, 2005 (edited) Well what I done was click the Oval tool, then I click randomly in the screen in an oval shape, and some times it draws kites that that. Thats seems to be as big as they get but.<{POST_SNAPBACK}> Um... btw the way the 2 shapes I originally posted are in the ScreenShot I just posted lol, so I'm not sure what you saw. Edited April 5, 2005 by burrup qq
Smed Posted April 5, 2005 Posted April 5, 2005 Yah, I just figured it out; sorry about berating your screenshots. Thats actualy normal behaviour for the Oval function. Since the Oval must be contained within a rectangle, when one of the rectangle dimensions is very small the curve doesn't appear to be curved. I know a way to fix it using sliding color scales, but thats not going to happen any time soon. 601DisengageEnd Program
buzz44 Posted April 5, 2005 Posted April 5, 2005 Cool, np, I dont know what "berating" means anyway lol. A kite function would still be nice , or a triangle. qq
Smed Posted April 5, 2005 Posted April 5, 2005 Describe to me in detail how you would like the interface to work, and I can throw in new the new shapes. The only reason I haven't added things like Triangle is that I'm not sure how the user would choose. 601DisengageEnd Program
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now