4
\$\begingroup\$

I have it set up so I place my mouse in the center of where I want the spiral to be, then I press enter to start the program, then define the radius initially and how much it grows each time it goes around.

I use \$\sin(\theta)\$ = opposite / hypotenuse and \$\cos(\theta)\$ = adjacent / hypotenuse to find how much my coordinates change based on the degree and the radius of my circle that itself is gradually increasing to create a spiral. There is also some printing at the end that I had just to help with debugging. As simple as I think something is going to be there are always problems.

Converting to int is because NumPy data can't be operated on.

from numpy import sin, cos, pi
import pyautogui as cc
import time
# (x-h)^2 + (y-k)^2 = r^2
# knowling radius and degree, r*sin(deg*pi/180) = rise || cos = run

input('Enter to Begin\n-->')
radius = int(input('What do you want your beginning radius to be?\n-->'))
rate = int(input('How much do you want it to increase by each cycle?\n-->'))
h, k = cc.position()
degree = 0
x = h+radius*(int(cos(degree*pi/180)*10**5)/10**5)
y = k+radius*(int(sin(degree*pi/180)*10**5)/10**5)
cc.moveTo(x, y)
cc.mouseDown()
while True:
    degree += 1
    radius += rate / 360
    x = h+radius*(int(cos(degree*pi/180)*10**5)/10**5)
    y = k+radius*(int(sin(degree*pi/180)*10**5)/10**5)
    cc.moveTo(x, y)
    print('Cords: '+str(x)+'||'+str(y))
    print('radius: '+str(radius))
    print('degree: '+str(degree))
    print()

All feedback is appreciated, but I'm really wondering how I could make this faster in Python.

\$\endgroup\$
3
\$\begingroup\$

The standard way to do this would be to use a tkinter canvas or pygame, but rolling with your method, you only have one huge efficiency problem, you are wasting subpixel precision on your calculations, I added a simple PRECISION constant so that you can decide at will how many degrees you advance per step, you only used 1 degree per step that is really to little, I suggest \$10\$, it looks good and goes fast.

I also added a constant for 10**5 so that you can avoid computing it every cycle (not a big deal) but mainly so that you could explain with a name what that number does.

I also replaced the while loop with a for loop so that the program does not run indefinitely (I was quite trolled by the program taking my mouse cursor for infinite time, it was not easy to shut it down).

Also please put care in your comments, about spelling formatting etc.. and the standard format is a docstring on top of the file.

Removing the printing can also speed up your program a bit.

Enjoy your improved program:

"""
This program takes control of the mouse to draw an ellipse.

(x-h)^2 + (y-k)^2 = r^2
Knowing radius and degree,
rise = r*sin(deg*pi/180) 
run  = r*cos(deg*pi/180)
"""

from numpy import sin, cos, pi
import pyautogui as cc
import time

BIG_NUM = 10**5
PRECISION = 10 # higher is less precision
ITERATIONS = 300

input('Enter to Begin\n-->')
radius = int(input('What do you want your beginning radius to be?\n-->'))
rate = int(input('How much do you want it to increase by each cycle?\n-->'))
h, k = cc.position()
degree = 0
x = h+radius*(int(cos(degree*pi/180)*BIG_NUM)/BIG_NUM)
y = k+radius*(int(sin(degree*pi/180)*BIG_NUM)/BIG_NUM)
cc.moveTo(x, y)
cc.mouseDown()

for i in range(ITERATIONS):
    degree += PRECISION
    degree %= 360
    radius += (PRECISION * rate) / 360
    x = h+radius*(int(cos(degree*pi/180)*BIG_NUM)/BIG_NUM)
    y = k+radius*(int(sin(degree*pi/180)*BIG_NUM)/BIG_NUM)
    cc.moveTo(x, y)
    #print('Cords: '+str(x)+'||'+str(y))
    #print('radius: '+str(radius))
    #print('degree: '+str(degree))
    #print()
\$\endgroup\$
  • \$\begingroup\$ Wow thank you for the input! I see clearly how going in such small increments slowed me down so much without actually contributing to the end product. If I want to get faster, approximate. Not as accurate, but still usable information to build spirals with :) I'm sorry about the script trolling you but I also got a good laugh out of it. pyautogui has a fail safe built in: if you move the mouse quickly to the upper left corner it will end the code. I was taking advantage of that after clicking to take the mouse up and stop drawing. \$\endgroup\$ – Tom Jenkins Nov 20 '17 at 2:20
  • \$\begingroup\$ @TomJenkins Glad to help! It was quite fun to figure out how to shut down the program without remembering the failsafe, I told it to a friend and we got a great laught out of it, so don't worry. I hope you'll remember as a general principle that the human eye can only see so much precision and more is just wasted cycles. Good Luck with your coding man :) \$\endgroup\$ – Caridorc Nov 28 '17 at 18:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.