Jump to content

GUICtrlCreateLine


erifash
 Share

Recommended Posts

hey, i just got done in the help and support forum with something that can really improve autoit. i've seached the forums for a way to connect two points through a line and i haven't found anything at all. so, with the help of some people on the support forum i finally got it! once the code get cleaned up a little it can really be put to good use!

#include <GUIConstants.au3>

Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size)
  $coeff_line = ( $y2-$y1 ) / ( $x2-$x1 )
  $p = $y2 - ( $coeff_line * $x2 )
  For $a = $x1 to $x2 step $size
    GUICtrlCreateLabel("", $a, ( $a * $coeff_line ) + $p, $size, $size, 0x1000)
  Next
EndFunc

GUICreate("Linear Example")
GUICtrlCreateLine(50, 50, 200, 300, 1)
GUICtrlCreateLine(50, 300, 300, 20, 5)
GUICtrlCreateLine(20, 200, 250, 100, 10)
GUISetState()

Do
  $msg = GUIGetMsg()
  Sleep(10)
Until $msg = $GUI_EVENT_CLOSE

check that out! thanks to the GUICtrlCreateEdge topic for giving me the idea! :)

EDIT: added a size parameter so you can tell it how big you want the pixels in the line

Edited by erifash
Link to comment
Share on other sites

  • Replies 45
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

I think it's very cool :)

"I thoroughly disapprove of duels. If a man should challenge me, I would take him kindly and forgivingly by the hand and lead him to a quiet place and kill him." - Mark TwainPatient: "It hurts when I do $var_"Doctor: "Don't do $var_" - Lar.
Link to comment
Share on other sites

I think it's very cool :)

<{POST_SNAPBACK}>

Thank you Insolence! I just really hope this gets added in the next version of AutoIt, it's really cool. :D Edited by erifash
Link to comment
Share on other sites

It won't get added. Just because it doesn't have that many real uses. But you did a good job.

[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]

Link to comment
Share on other sites

Yeah, most things don't get added :)

"I thoroughly disapprove of duels. If a man should challenge me, I would take him kindly and forgivingly by the hand and lead him to a quiet place and kill him." - Mark TwainPatient: "It hurts when I do $var_"Doctor: "Don't do $var_" - Lar.
Link to comment
Share on other sites

The things that can be done in AutoIt, usually don't get added, but unless it's like super duper cool, then it will be added as a UDF in the help file, and will be in one of the inlcude files, and SciTe will update it's definitions... But those things that cannot be done in AutoIt, and will be really useful to everyone, then that may get added to the AutoIt, but it doesn't always happen like that - !

FootbaG
Link to comment
Share on other sites

here is the newest version that does not have a sunken border so you can specify color on even the one by one pixels! Remember to use the "0x" before you type in your hex color:

#include <GUIConstants.au3>

Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size, $color)
  $coeff_line = ( $y2-$y1 ) / ( $x2-$x1 )
  $p = $y2 - ( $coeff_line * $x2 )
  For $a = $x1 to $x2 step $size
    GUICtrlSetBkColor(GUICtrlCreateLabel("", $a, ( $a * $coeff_line ) + $p, $size, $size), $color)
  Next
EndFunc

GUICreate("Linear Example")
GUICtrlCreateLine(50, 50, 200, 300, 1, "0xFF0000")
GUICtrlCreateLine(50, 300, 300, 20, 5, "0x00FF00")
GUICtrlCreateLine(20, 200, 250, 100, 10, "0x0000FF")
GUISetState()

Do
  $msg = GUIGetMsg()
  Sleep(10)
Until $msg = $GUI_EVENT_CLOSE
Link to comment
Share on other sites

yay, now i made the size and color parameters optional with $size = 1 (one by one pixel default) and $color = "0x000000" (black being default). here is the new function:

Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size = 1, $color = "0x000000")
  $coeff_line = ( $y2-$y1 ) / ( $x2-$x1 )
  $p = $y2 - ( $coeff_line * $x2 )
  For $a = $x1 to $x2 step $size
    GUICtrlSetBkColor(GUICtrlCreateLabel("", $a, ( $a * $coeff_line ) + $p, $size, $size), $color)
  Next
EndFunc

yawn! i'm tired... :)

Link to comment
Share on other sites

Yes, very nice, but you'll get much better results converting the linear equation into a pair of parameterized equations like this:

#include <GUIConstants.au3>
#include <math.au3>

Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size, $color)
  $deltaX = $x2 - $x1
  $deltaY = $y2 - $y1
  $slope = $deltaY/$deltaX
  $length = Sqrt ($deltaX*$deltaX + $deltaY*$deltaY)
  $incDeltaX = $deltaX/$length
  $incDeltaY = $deltaY/$length
  For $i = 1 to _Ceil ($length)
    GUICtrlSetBkColor(GUICtrlCreateLabel("", $x1 + $incDeltaX*$i, $y1 + $incDeltaY*$i, $size, $size), $color)
  Next
EndFunc

GUICreate("Linear Example")
GUICtrlCreateLine(50, 50, 200, 300, 1, "0xFF0000")
GUICtrlCreateLine(50, 300, 300, 20, 5, "0x00FF00")
GUICtrlCreateLine(20, 200, 250, 100, 10, "0x0000FF")
GUICtrlCreateLine(20, 300, 30, 20, 1, "0x000000")
GUISetState()

Do
  $msg = GUIGetMsg()
  Sleep(10)
Until $msg = $GUI_EVENT_CLOSE

that way lines that are nearly vertical don't appear different than lines that are nearly horizontal.

EDIT: oh, and on the resource utilization note, removing the step makes a prettier line. Put it back if you like blocks :)

Edited by Smed

601DisengageEnd Program

Link to comment
Share on other sites

hello,

Congrulations Erifash, your idea is very good.

We can use it to draw a lot of functions like cos, sin , etc. very interesting...

#include <GUIConstants.au3>

Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size, $color)
  $coeff_line = ( $y2-$y1 ) / ( $x2-$x1 )
  $p = $y2 - ( $coeff_line * $x2 )
  For $a = $x1 to $x2 step $size
    GUICtrlSetBkColor(GUICtrlCreateLabel("", $a, ( $a * $coeff_line ) + $p, $size, $size), $color)
  Next
EndFunc

GUICreate("Cos and sin Examples")
$step=1

for $x=0 to 400 Step $step
    $xnext=$x+$step
    GUICtrlCreateLine($x, f($x),$xnext,f($xnext),$step,"0xffff00")
    GUICtrlCreateLine($x, f2($x),$xnext,f2($xnext),$step,"0x0000ff")
next





GUISetState()

Do
  $msg = GUIGetMsg()
  Sleep(10)
Until $msg = $GUI_EVENT_CLOSE



Func f(ByRef $x)
    Return (100*cos($x/30)+150)
EndFunc

Func f2(ByRef $x)
    Return (100*sin($x/30)+150)
EndFunc

Now, I'll look at your thread Cyberslug, it seems very very interseting too

Link to comment
Share on other sites

it's more nice if we take a little step :

$step=.2

for $x=0 to 400 Step $step
    $xnext=$x+$step
    GUICtrlCreateLine($x, f($x),$xnext,f($xnext),1,"0xffff00")
    GUICtrlCreateLine($x, f2($x),$xnext,f2($xnext),1,"0x0000ff")
next
GUISetState()

but if $step=.1, it stops to draw at the middle ... I don't know why ? (it seems that is you have notified it Smed)

Link to comment
Share on other sites

@Smed: yeah, my first way tried to utilize pythagoreans thoerem (i'm not sure how to spell it correctly...) but it was just too complicated for me, lol. :)

then sylvanie (with his great math skills :D ) comes along and shows me i can just simply use y=ax+b with the slope and all. Thanks!

Link to comment
Share on other sites

The problem with the y = ax + b method is that nearly vertical lines come out as a series of dots and you can't do a vertical line at all.

I had some free time on my hands this afternoon, and I wrote this little doodle program. Photoshop beware! :)

#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 GUICtrlCreateCircle($x1, $y1, $x2, $y2, $size = 1, $color = "0x000000")
  $deltaX = $x2 - $x1
  $deltaY = $y2 - $y1
  $radius = _Ceil (Sqrt ($deltaX*$deltaX + $deltaY*$deltaY))
  If Not $radius Then
    MsgBox (0, "Error!", "Circle is too Small!")
    Return
  EndIf
  $px = $x1 + Cos(0)*$radius
  $py = $y1 + Sin(0)*$radius
  $deltaTheta = $piX2/$radius
  For $theta = $deltaTheta To $piX2 + $deltaTheta Step $deltaTheta
    $nx = $x1 + Cos($theta)*$radius
    $ny = $y1 + Sin($theta)*$radius
; Need to do boundary checking here, but I'm bored with this already.
    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("Circle", 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 Line"
$tips[2] = "Click Opposing Corners to Draw Rectangle"
$tips[3] = "Click Center and Edge to Draw Circle"
$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
      If $msg[4] < 60 Then
        MsgBox(0, "Error!", "Can't Draw There!")
      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
              GUICtrlCreateCircle ($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
      $mouseDown = 1
      $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!")
      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

Known Bug: If you click on one of the buttons and you are already in that mode, you get the "Can't Draw There!" Error dialog. Not sure why.

This isn't practical for any purpose, but it was entertaining for a little while. You run out of controls very quickly, the limit is 4096. It'd be really cool if you could do this all in one Image Label with maybe a PixelSetColor function.

EDIT: Almost forgot, if someone wants to add a color selector thingy to it that'd be incredibly cool.

EDIT2: Modified code, now with never run out of controls goodness. (Watch your oldest scribbling disappear as you make new ones.)

Edited by Smed

601DisengageEnd Program

Link to comment
Share on other sites

The problem with the y = ax + b method is that nearly vertical lines come out as a series of dots and you can't do a vertical line at all.

You're right, a vertical line can't be defined with this equation, but don't worry, we can fixe that with this if statement :

Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size, $color)
  if $x1<>$x2 Then
        $coeff_line = ( $y2-$y1 ) / ( $x2-$x1 )
        $p = $y2 - ( $coeff_line * $x2 )
        For $a = $x1 to $x2 step $size
            GUICtrlSetBkColor(GUICtrlCreateLabel("", $a, ( $a * $coeff_line ) + $p, $size, $size), $color)
        Next
    Else
        For $a = $y1 to $y2 step $size
            GUICtrlSetBkColor(GUICtrlCreateLabel("", $x1, $a, $size, $size), $color)
        Next
    EndIf
EndFunc
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...