Jump to content
TheAutomator

Ellipse drawing algorithm

Recommended Posts

TheAutomator

Hi!

I'm trying to script an ellipse drawing algorithm in AutoIT for learning purposes.
I use an edit control to "draw" the ellipse with characters.

The code i have works kinda good but i would like to see if others around here know a better algorithm to do it..
I would like to be able to give the x, y and width, height arguments to the function and not have to start at the middle point and draw the ellipse around it.

side note, the ellipse glitches when it has to be 2 pixels high too..

 

func ellipsePlotPoints ($xc,$yc, $x,$y)

    pixel ($xc + $x, $yc + $y)
    pixel ($xc - $x, $yc + $y)
    pixel ($xc + $x, $yc - $y)
    pixel ($xc - $x, $yc - $y)

endfunc

func ellipse($xc,$yc, $a,$b)

    local $a2 = $a * $a
    local $b2 = $b * $b
    local $twoa2 = 2 * $a2
    local $twob2 = 2 * $b2
    local $p
    local $x = 0
    local $y = $b
    local $px = 0
    local $py = $twoa2 * $y

    ; Plot the initial point in each quadrant.
    ellipsePlotPoints ($xc,$yc, $x,$y)

    ; Region 1
    $p = int($b2 - ($a2 * $b) + (0.25 * $a2))
    while ($px < $py)
        $x+=1
        $px += $twob2
        if ($p < 0) then
            $p += $b2 + $px
        else
            $y-=1
            $py -= $twoa2
            $p += $b2 + $px - $py
        endif
        ellipsePlotPoints ($xc,$yc, $x,$y)
    wend

    ; Region 2
    $p = int ($b2 * ($x+0.5) * ($x+0.5) + $a2 * ($y-1) * ($y-1) - $a2 * $b2)
    while ($y > 0)
        $y-=1
        $py -= $twoa2
        if ($p > 0) then
            $p += $a2 - $py
        else
            $x+=1
            $px += $twob2
            $p += $a2 - $py + $px
        endif
        ellipsePlotPoints ($xc,$yc, $x,$y)
    wend

endfunc

 

Share this post


Link to post
Share on other sites
Chimp

here (https://www.autoitscript.com/forum/topic/181014-a-naive-question/?do=findComment&comment=1299979) you can find a simple implementation of the Bresenham's Algorithm, translated in AutoIt, to plot lines, circles, ellipses and Bézier curves plotted pixel by pixel (or character by character on a text box as well if you prefer)

 

Edited by Chimp
  • Like 1

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
TheAutomator

Would be nice to know how to fill the ellipse too btw :shifty:

[edit:] if you draw an ellipse with your algorithm (w = 9, h = 4) then there are some pixels drawn twice..

Edited by TheAutomator

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

  • Similar Content

    • tiye0405
      By tiye0405
      Hello, 
       
      I currently have a problem that deals with moving the mouse to a given location + or - a certain distance.
      $search1 =_WaitForImageSearch("envelope.bmp", 10, 1, $x, $y, 20)
      $search2 =_WaitForImageSearch("envelope2.bmp", 10, 1, $x, $y, 20)
       
      If $search1 = 1 Then
                  Sleep(100)
                  MouseMove($x, $y, 10)
                  sleep(99)
                  MouseClick("left")
                 Sleep(99)
      ElseIf $search2 = 1 Then
                 Sleep(100)
                 MouseMove($x, $y2, 10)
                 sleep(99)
                 MouseClick("left")
                 Sleep(100)
      Else
                Sleep(150)
                MouseMove($x2, $y, 10)
                Sleep(150)
                MouseClick("left")
               Sleep(150)
      EndIf
      The problem about this is that i defined $x2 = $x - 175  and $y2 = $y + 35
      I got these numbers ( 175 and 35) with the autoit helper and just subtracted point where it is to the point its supposed to move but it doesnt work.

      is there any proper way to find the distance between 2 points in pixels?
       
      Imgsearch doesnt always work for this picture so i want it to have a backup
       
      edit: could it be that the definition of $x and $y  from the previous image search arent there anymore and thats why it moves my mouse to strange places? 
      is there a way to preserve the $x $y from the previous img search untill the next succesful one?
       
       
    • Nitrolord
      By Nitrolord
      I had this problem with PixelGetColor not giving me the same HEX Color as the AU3Info Tool and searched every were with no luck then had a OH DA moment LoL.
      The problem is that the
      "PixelGetColor ($mouseX[0], $mouseY[1])"
      is looking rite at the very tip of the mouse pointer not under it.  So you have to set a -3 after the [0] and [1].  
      "PixelGetColor ($mouseX[0] -3, $mouseY[1] -3)"
      to make it search next to the pointer not on the pointer.  You may have to adjust this a bit for your display but you should not have  to go more then -5.  -3 seems to work best for me.
      Example.au3
      #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Form1", 141, 127, 276, 231) $Input1 = GUICtrlCreateInput("", 8, 8, 121, 21) $Label1 = GUICtrlCreateLabel("Press or Hold F1 to get Hex color at Mouse X -3, Y-3 Pos,", 8, 40, 124, 73) GUISetState(@SW_SHOW) HotKeySet("{f1}","MousePos") Func MousePos() $aPos = MouseGetPos() $PGC = PixelGetColor($aPos[0] -3, $aPos[1] -3) GUICtrlSetData($Input1, "0x" & Hex($PGC, 6)) EndFunc While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd  
    • Miliardsto
      By Miliardsto
      Hello i have problem with function PixelGetColor. On my computer it working fine but in some cases it not working.
      And Im clicking on the active window on red color and it give me the same color still. But in other computers when clicking on the same color red it gives other values and returned color in MsgBox is not red.
      Dont know is it a real main thing what causing problem but,
      I noticed that problem was on one windows 10.
      I have windows 8 and working well. On other windows 10 works well to
      Maybe it is caused by windows aero or something like that
      How to deal with it?
      There is a code
      HotKeySet("{PAUSE}", "MouseCord") While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func MouseCord() Global $MousePos = MouseGetPos() $clickedColor = PixelGetColor($MousePos[0], $MousePos[1]) MsgBox(0, "Done", $clickedColor) EndFunc  
       
    • Reizvoller
      By Reizvoller
      Greetings!
      I am having an issue that I can't seem to be able to figure out. I would really appreciate an extra pair of eyes to validate my work so far.
      All this is, so far, is just a bunch of shapes on an HTML page. It is to be a very simple game ( just exploring Javascript through making this ) but right now I am just building the framework/elements.
      The script is this 
      <!DOCTYPE HTML> <html> <head> <style> body { margin: 0px; padding: 0px; } #canvas-container { width: 100%; text-align:center; } canvas { display: inline; } </style> </head> <body onload="startUp()"> <div id="canvas-container"> <canvas id="game" width="300" height="500"></canvas> </div> <script> var canvas = document.getElementById('game'); var ctx = canvas.getContext('2d'); var x = canvas.width; var y = canvas.height; var scoreVal = 0; var itemXRand = Math.floor(Math.random() * x) + 1 ctx.stroke(); function cloud(){ ctx.beginPath(); ctx.moveTo(170, 30); ctx.bezierCurveTo(130, 100, 130, 150, 230, 150); ctx.bezierCurveTo(250, 180, 320, 180, 340, 150); ctx.bezierCurveTo(420, 150, 420, 120, 390, 100); ctx.bezierCurveTo(430, 40, 370, 30, 340, 50); ctx.bezierCurveTo(320, 5, 250, 20, 250, 50); ctx.bezierCurveTo(200, 5, 150, 20, 170, 80); ctx.closePath(); ctx.lineWidth = 5; ctx.fillStyle = '#8ED6FF'; ctx.fill(); ctx.strokeStyle = '#0000ff'; ctx.stroke(); } function workArea(){ ctx.beginPath(); ctx.rect(0, 0, x, y); ctx.fillStyle = "#2ab9ff"; ctx.fill(); ctx.stroke = 1; } function topRect(){ ctx.beginPath(); ctx.rect(0, 0, x, 30); ctx.fillStyle = "#D3D3D3"; ctx.fill(); ctx.stroke = 1; } function scoreKeep(){ ctx.font = "15px Arial"; ctx.fillStyle = "#000000"; ctx.fillText("Score "+scoreVal,5, 25); } function bttmRect(){ ctx.beginPath(); ctx.rect(0, y-30, x, 30); ctx.fillStyle = '#5bc928'; ctx.fill(); ctx.stroke = 1; } function monstRect(){ ctx.beginPath(); ctx.rect(0, y-80, x, 30); ctx.fillStyle = 'red'; ctx.fill(); ctx.stroke = 1; } function itemCirc(){ var centerX = itemXRand var radius = 15; var positionY = 45; ctx.beginPath(); ctx.arc(centerX, positionY, radius, 0, 2 * Math.PI, false); ctx.fillStyle = randomColor(); ctx.fill(); ctx.lineWidth = 1; ctx.strokeStyle = '#003300'; ctx.stroke(); } function startUp(){ workArea(); topRect(); bttmRect(); scoreKeep(); itemCirc(); monstRect(); cloud(); } function randomColor(){ return('#'+Math.floor(Math.random()*16777215).toString(16)); } </script> </body> </html> The issue is that cloud() and monstRect() will not show up when the page loads. If I comment out workArea(), topRect(), and bttmRect() in the function "startUp()" then monstRect() and cloud() show up. I've re-read those little snippets of code for those three areas that I comment out and I can't see where I have gone wrong.
      Any advice or if you can spot my mistake I would really appreciate it.
      Thank you!
      -Reiz
    • Reizvoller
      By Reizvoller
      Hello,
      I am using the addon-library of FastFind.au3  found here :
       
      The script I've put together is rather simple but it's returning a value that I don't understand.
      #include "FastFind.au3" #Include <WinAPI.au3> #RequireAdmin WinActivate ("ABC Window") Local $xyzWindow = WinGetHandle ("ABC Window") Local $triangleSpot = FFSnapShot (212, 216, 214, 218, 1, $xyzWindow) ConsoleWrite ($triangleSpot&@CR) Local $triangleData = FFGetRawData (1) Local $splitTriangleData = StringSplit ($triangleData, "00") Local $iMax If isArray ($splitTriangleData) Then $iMax = Ubound ($splitTriangleData) ConsoleWrite ($iMax) EndIf So here's the question...
      If the area I have selected is a total of 4 pixels , why is the UBound return value 26?
      I thought that maybe it was getting values for the 4 along with the surrounding pixels bordering the selected area, even still , it should provide only 16 values(or so I thought). 
      I feel that there is a bit of pixel data or something that I am not fully understanding. If anyone could please provide materials on what is happening I'd really appreciate it. 
      Thank you for your time!
      -Reiz
      PS : I used terms like "triangleSpot" and such because in the actual window there is a small triangle icon that I am trying to gain the pixel data of to then search for others like it on the page. I understand the area that I am selecting is a square/rectangle and not a triangle. 
×