I'm learning Python (for fun) through the book ThinkPython. So far I'm really enjoying this new hobby. One of the recent exercise was crafting a Archimedes spiral.In order to test my skills I've been working on making a hyperbolic spiral but have been stumped!
according to the equation r=a+b*theta^(1/c)
when c=1 we see a Archimedes spiral
when c=-1 we should see a hyperbolic spiral
I'm using the following code and would appreciate any help towards the right direction.
Extra points to whoever can help me in the right direction without directly giving away the answer. Unless it's simply a formatting issue.
No points if the answer suggested involves using (x,y) coordinates to draw.
import turtle
import math
def draw_spiral(t, n, length=3, a=0.1, b=0.0002):
"""Draws an Archimedian spiral starting at the origin.
Args:
n: how many line segments to draw
length: how long each segment is
a: how loose the initial spiral starts out (larger is looser)
b: how loosly coiled the spiral is (larger is looser)
http://en.wikipedia.org/wiki/Spiral
"""
theta = 0.1
for i in range(n):
t.fd(length)
dtheta = 1/((a + b * (theta**(1/-1))))
t.lt(dtheta)
theta += dtheta
# create the world and bob
bob = turtle.Turtle()
draw_spiral(bob, n=1000)
turtle.mainloop()
"""Source code from ThinkPython # http://greenteapress.com/thinkpython2/code/spiral.py
edited to attempt a hyperbolic spiral"""
many thanks!
Simply adjusting the constants passed to draw_spiral() as arguments:
def draw_spiral(t, n, length=1, a=0.01, b=60):
I was able to generate a spiral along the lines you describe:
However, it draws from the outside in, not the inside out. So, may not be what you're looking for.
As mentioned in the answer of #cdlane, it is just a matter of the arguments. I'll extend the answer.
For the Archimedean spiral add the argument c to the function draw_spiral:
def draw_spiral(t, n, length=3, a=0.1, b=0.0002, c=-1):
theta = 0.1
for i in range(n):
t.fd(length)
dtheta = 1/((a + b * (theta**(1/c))))
t.lt(dtheta)
theta += dtheta
And use the following arguments, for instance:
draw_spiral(bob, n=1000, length=1, a=0.01, b=0.001, c=1)
Related
i got some turtle homework. but i did not get the circle command to work. i really want to keep using google colab.
(i found other posts with the same problem, but their solution to change the library/file name didn't work for me)
(i also tried different import methods and names, and created a new file, all cause that error)
!pip3 install ColabTurtle
import ColabTurtle.Turtle as t
t.initializeTurtle()
t.forward(25)
t.left(45)
t.circle(70)
forward and left worked, but the t.circle(70) causes the error:
AttributeError: module 'ColabTurtle.Turtle' has no attribute 'circle'
here is an imgur screenshot: https://imgur.com/jvGjwwt
here is the link so you can try around in the online file: https://colab.research.google.com/drive/1WzSV6ZotxMg85BMeiuc8W5Xq3wiYxwev
the circle function is not available in the google colaboratory turtle library.
i kind of recreated the circle with the help of cdlane's function:
circle is supposed to draw a circle with only the radius given
!pip3 install ColabTurtle
import ColabTurtle.Turtle as t
t.initializeTurtle()
from math import pi
def tcircle(radius):
#function could be summarized into:
#regular_polygon(int((2 * pi * radius)/9)),9)
#explained step by step:
"""draws a regular polygon of n sides
that is supposed to appear like a circle.
n is set to 9 for fast drawing time.
it calculates rounded side length from n and radius"""
#circumference (c)= 2*pi*radius
c = 2 * pi * radius
#n = amount of lines or corners, it defines the accuracy of the circle
n = 9 # lower number to decrease drawing time (can be any float or int)
#circumference (c) = ca. l * n
#l = length of individual lines
l = c / n
regular_polygon(int(l),n)
def regular_polygon(l, n):
"""draws a regular polygon of n amount sides of length l
that is supposed to appear like a circle.
function by cdlane from a stackoverflow post"""
for _ in range(n):
t.forward(l)
t.left(360 / n)
#circle_example
t.forward(35)
tcircle(45)
screenshot of my solution, how the circle_example would look like: https://imgur.com/LXgaB4v
Were you supplied with any documentation? As far as I can tell, ColabTurtle has no circle() method and the error message is correct. Looking at the Turtle.py source, the turtle-related methods include:
forward(units)
backward(units)
right(degrees)
face(degrees)
left(degrees)
penup()
pendown()
speed(speed)
setx(x)
sety(y)
getx()
gety()
goto(x, y)
showturtle()
hideturtle()
bgcolor(color)
color(color)
width(width)
But no circle(). This isn't the turtle.py library that comes with Python which has a circle() method and many others. Nor even a proper subset.
However, this doesn't mean you can't draw circles, you just need to define code to do so in terms of the turtle methods you do have. Here's my guess at such, though I'm not in a position to fully test it:
import ColabTurtle.Turtle as t
def polygon(length, n):
for _ in range(n):
t.forward(length)
t.left(360 / n)
t.initializeTurtle()
polygon(10, 60)
Good afternoon,
I have been trying to understand the documentation of the matplotlib quiver function. And my eyes are officially bleeding.
I have attempted to play with the keyword arguments in my simple example below in order to understand how to change the appearance of my arrows, but half of the keyword arguments have no affect and the other half cause errors to be thrown. See below the code for some specific questions.
# ODE for falling object
def field(t, v):
v_dot = 9.8 - (gamma / mass) * v
return v_dot
# gamma is the coefficient for air resistance
gamma = 0.392
mass = 3.2
x = np.linspace(0,50, 11) # time from zero to 50 inclusive
y = np.linspace(0,100, 11)# initial velocities from 0 to 100 inclusive
# meshgrid creates two arrays of shape(len(y), len(x))
# by pairing the values of these two arrays, we create a set
# of ordered pairs that give our coordinates for the location
# of the quiver arrows we wish to plot.
X, Y = np.meshgrid(x, y)
# We know slope is v' = f(t, v), so we can use trig to get
# to the x and y components of our quiver arrow vectors
theta = np.arctan(field(X, Y))
U = np.cos(theta)
V = np.sin(theta)
plt.quiver(X, Y, U, V)
plt.grid()
plt.legend()
plt.show()
Functional Questions
How do I change the width or length of the arrows (supposing that I want to change them all uniformly)?
How do I change length AND/OR width of the arrows (supposing I want them to shrink or grow based on the y (velocity) values)?
What does the "angles" argument do? I thought that the angles were determined by the vector component arguments U and V...
What about the argument "units"? What does this argument do functionally?
If I choose units='width' what width are we referring to here? The documentation says the width of the axis, but that makes no sense to me... And when I choose units='y' nothing changes in the appearance of my graph. So what is the point of this argument?
As you can see, I have a lot of questions, and the documentation here is quite poor in my opinion. Perhaps it is understandable by someone with more advanced knowledge that I do not have.
Any links to good tutorials for beginners would be great. None of the ones I have found do much with the keyword arguments, and those that do are too advanced for me to understand.
I'm trying to create a python program that draws a fractal spiral with user input.
I have looked at other questions very similar to mine but it doesn't quite give me what I would like, and I keep getting error messages.
This is what I have tried:
a = int(input("Size? "))
b = int(input("Angle? "))
c = int(input("How many times do you want to repeat? "))
from turtle import *
def fractalSpiral(size, angle, amount):
for i in range(amount):
forward(size)
left(angle)
forward(size + 50)
left(angle + 10)
fractalSpiral(a, b, c)
Witch the inputs a = 50, b = 60, and c = 9, I get the shape in the attachment, which does not look like a fractal spiral.
Can I have some help please?
From what I see in the second picture, you want a shape that is constructed of triangles where every triangle is a little bigger than the previous one and also set to a little different angle. I thought I would go with an Egyptian 3:4:5 triangle and came up with this:
def spiral(step, angle, max):
for i in range(0, max, step):
turtle.forward(i*3)
turtle.left(126.87)
turtle.forward(i*5)
turtle.left(143.2)
turtle.forward(i*4)
turtle.left(90 + angle)
You can now play with the parameters to get a result that would please you. If you want a different triangle, you would need to recalculate its angles using trigonometry. Remember that to get angle alpha, you need to turn you turtle 180 - alpha.
Is it just me or everyone who is facing so many problems in attempting this question from exercise of Think Python.
I am trying to solve exercises of Chapter 4 but facing so many problem.
Exercise 4.5 says Write a program that draws an Archimedes spiral.
I have this code but its not working in Python.
I need an easy possible solution for this.
Kindly help.
from TurtleWorld import *
world = TurtleWorld()
bob = Turtle()
def polygon(t, length, n):
t = Turtle()
for i in range(n):
fd(t, length)
lt(t, 300 / n)
polygon(bob, 5, 8)
[In the following discussion, I'm using the turtle library that comes with Python, not TurtleWorld, so adjust accordingly.] From the online ThinkPython PDF:
Exercise 4.5. Read about spirals at http://en.wikipedia.org/wiki/Spiral ;
then write a program that draws an Archimedian [sic] spiral (or one
of the other kinds). Solution: http://thinkpython.com/code/spiral.py
If we follow the Wikipedia link from Spiral to Archimedean spiral, we end up with with the formula r = a + b * theta which naturally wants to be computed in polar coordinates and plotted in cartesian coordinates:
def spiral(turtle, rotations=6, a=0.0, b=5):
theta = 0.0
while theta < rotations * 2 * pi:
radius = a + b * theta
x, y = radius * cos(theta), radius * sin(theta)
turtle.goto(x, y)
theta += 0.1
Where a controls the initial angle of the spiral, and b controls the distance between turnings:
But the solution that ThinkPython offers is different:
To get rid of pi, sin() and cos() from math.py, it pictures the turtle on the spiral and what each move along that spiral looks like. It introduces n which is how many line segments to draw, and length the length of those segments. The b variable still means roughly the same thing, though on a different scale, and a represents how tight the initial spiral starts out. Again, we start with:
theta = 0.0
But instead of looping over the number of complete rotations, we loop up to n, the number of segments to draw. So n should be large, e.g. 1000 instead of 5 in your code. Each iteration we move forward length pixels and then calculate a new delta angle to turn based on a, b, and theta:
delta = 1 / (a + b * theta)
We turn by this small amount and also add this amount to theta just before we loop again. In this approach, a and b are typically less than 1 but non-zero:
You can see by the turtle's orientation in the two images that the first is just plotting points so the turtle's orientation isn't significant but in the second we're moving along the spiral so the turtle is always pointing in the direction of the growing spiral. I hope this discussion of the two approaches helps you.
I'm currently working with the turtle library of python.
I'm working on my midterm project for my coding class and my project is to draw cos, sin, and tangent curves using turtle as well as their inverse functions.
My problem is that when I'm coding inverse sin, the graph shows up way too small and is impossible to be seen by the user. I was wondering if there was a zoom function or a way to stretch the graph to make it bigger?
Here is my code for arcsin:
def drawarcsincurve(amplitude, period, horShift, verShift):
turtle.speed(0)
startPoint = -1
turtle.goto(startPoint, math.asin(startPoint))
turtle.pendown()
for angles in range(-1,1):
y = math.asin(angles)
turtle.goto(angles,y)
Your main problem here, I think, is the range over which your are iterating your angles variable. The line
for angles in range(-1,1):
will execute the loop only twice, with angle == 1 and angle == 0 - i.e. it is equivalent to using
for angles in [-1,0]:
Type range(-1,1) in a Python interpreter window to see what I mean.
You might be getting confused over names as well. You call your loop variable angles, but it's actually representing a ratio (the sine value whose inverse you are calculating).
What you probably want really is something that iterates over the range -1 to 1 in fairly small steps. Lets choose 0.01 as our step (that's arbitrary)
I've altered your code directly rather than doing my own implementation.
I've put in a scale factor (plot_scale) which is equivalent to the zoom that I think you want in your original question.
I've left your original function arguments in, although I don't use them. I thought you might want to play with them later.
def drawarcsincurve(amplitude, period, horShift, verShift):
plot_scale = 100 # Arbitrary value - up to you - similar to "zoom"
turtle.speed(1)
turtle.penup()
startPoint = -1
turtle.goto(plot_scale*startPoint, plot_scale*math.asin(startPoint))
turtle.pendown()
for angles in range(-100,100):
sinval = 1.0 * angles / 100 # this will run -1 to 1 in 0.01 steps
y = math.asin(sinval)
turtle.goto(plot_scale*sinval,plot_scale*y)
This outputs: