Jump to content

Recommended Posts

Posted (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 5

edit: 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 by burrup

qq

  • Replies 45
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted (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! :)

#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 by erifash
Posted

@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:

#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

Posted

@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

Posted (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....    :D

<{POST_SNAPBACK}>

Yeah, but it will be even more efficient than it was! Edited by erifash
Posted (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 by erifash
Posted (edited)

Oh Oh!! I've seen this :D

$alg = Int((Abs($x2 - $x1)) / $size)

Dim $id[$alg + 2]

Thats some seriously slick code :)

Edited by Ejoc
Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Posted (edited)

Oh Oh!! I've seen this :D

$alg = Int((Abs($x2 - $x1)) / $size)

Dim $id[$alg + 2]

Thats some seriously slick code :D

<{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 by erifash
Posted

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 :

#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 :)

Posted

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

Posted (edited)

Nice :).

Edit: I somehow managed to create these with the oval function...

Posted Image

Bug? or new idea to create kits :D.

Edited by burrup

qq

Posted (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 by Smed

601DisengageEnd Program

Posted (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:Posted Image

This time it drew a really small triangle lol, but no kites.

Edited by burrup

qq

Posted

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

Posted (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 by burrup

qq

Posted

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

Posted

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

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
  • Recently Browsing   0 members

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