How it is possible to be a circle in python? - python

Here is the code In the book Thinkpython 2e.
import turtle
import math
bob = turtle.Turtle()
def polygon(t, n, length):
angle = 360 / n
for i in range(n):
t.fd(length)
t.lt(angle)
def circle(t, r):
circumference = 2 * math.pi * r
n = 50
length = circumference / n
polygon(t, n, length)
circle(bob,50)
turtle.mainloop()
I don't understand how it is possible to be a circle, I think it will be a 50-sides polygon, am i right?

A circle has infinitely many points, a screen has finitely many pixels. You are correct that you can't draw true circles on a screen. This isn't to say that drawing a polygon is the only way to approximate a circle on the screen. As #Qwerty rightly points out in the comments you can also do so with trig functions.
Nevertheless, approximating circles by polygons is an ancient approach and was the classical way in which pi was approximated. Also -- it is a fun exercise for turtles.

I have not programmed in python in a while (specifically with the turtle libraries) but if I remember, there is a way easier
import turtle
circumfrence = 80
turtle = turtle.Turtle()
turtle.shape("circle")
turtle.circle(circumfrence / 2)
It's that Simple!

The odd part about your circle() function to me is that n is fixed at 50. At the extremes of large and small circles, this might not be optimal and maybe should be more dynamic. As far as a 50-sided polygon vs. a circle, let's test using the turtle.circle() command:
from turtle import Turtle, Screen
radius = 100
sides = 50
bob = Turtle(shape="turtle")
bob.width(2)
bob.pencolor("red")
bob.circle(radius)
bob.pencolor("green")
bob.circle(radius, steps=sides)
bob.hideturtle()
screen = Screen()
screen.exitonclick()
The turtle.circle() method uses a polygon approximation but it computes the number of sides as a function of the radius with a maxium of 60. For the radius of 100 above, it actually uses only 28 steps so our 50-sided polygon is potentially more accurate!

Related

The iterating polygons increasing by length of 10 px eachtime don't center perfectly with its inner polygon. What could the maths after line 11 be?

Why don't the iterating polygons not align perfectly. (if I try to make a polygon with 4 sides, it works fine, but any other shape and it aligns a bit differently). Is it something to do from line 11 to line 16?
This is the question I am trying to solve with my function
import turtle
t = turtle.Turtle()
t.speed(5)
def draw_shape(length, sides, colores, times):
for timestotal in range(1, times+1):
for side in range(sides):
t.color(colores)
t.forward(length*timestotal)
t.right(360/sides)
t.penup()
t.back(length*2)
t.left(360/sides)
t.forward(length*2)
t.right(360/sides)
t.pendown()
draw_shape(4, 8, "red", 8)
It doesn't really matter if it is ascending or descending lengths as long as all the shapes are centered as is in the exercise.
Unfortunately if the parameter is anything other than 4 the shapes do not align properly
If I pass different commands between penup() and pendown() for each number from 3 to 13 using if, elif, and else statements, it does align the shapes but each number(length) needs its own sets of code:
Could it be something around this command:
t.goto(-(lengthtimestotal)/2,(lengthtimestotal)/2)
It seems like the problem can be reduced to "draw a regular polygon of n sides from a center point". If you can do that, then you need only iterate with different sizes in the outer loop, all drawing from the same point (the turtle's current location).
I don't think it's easy to draw a regular polygon from a center point using only forward, backward and turning commands. But it's possible to use the classic trig polygon approach to compute the vertices of the polygon around the circle:
import turtle
from math import cos, radians, sin
def draw_shape(length, color, sides, times):
t.color(color)
x, y = t.pos()
side = 360 // sides
for i in range(times):
current_length = length // times * (1 + i)
t.penup()
for angle in range(0, 361, side):
t.goto(
current_length * cos(radians(angle - side / 2)) + x,
current_length * sin(radians(angle - side / 2)) + y
)
t.pendown()
t = turtle.Turtle()
t.speed(5)
draw_shape(length=100, color="red", sides=8, times=5)
turtle.exitonclick()
The angle - side / 2 bit is used to rotate the polygon by half a side to match the spec.
I also see draw_shape(100, "blue", 4, 3) has unusual output. You can get this with current_length = length - (20 * i) which hardcodes the step size. Not very pleasant to have to do, but such it is.

How to use python to move the mouse in circles

I'm trying to write a script in python, to automatically force the movement of the mouse pointer without the user's input (it quits through the keyboard), and experimenting with PyAutoGUI, PyUserInput and ctypes, I've been figuring out ways to move the pointer with constant speed, instead of having it teleport across the screen(I need the user to be able to see the path it makes). However, I need it to be able to perform curves, and particularly, circles, and I haven't found a way to do so with the aforementioned libraries. Does anybody know of a way to code them into making the mouse describe circles across the screen at constant speed, instead of just straight lines? Thank you beforehand for any input or help you may provide.
This is my attempt at making circle at the center of the screen of radius R - also note if I don't pass parameter duration then the mouse pointer moves to the next coordinates instantly. So for a circle divided into 360 parts you can set the pace using a modulus.
import pyautogui
import math
# Radius
R = 400
# measuring screen size
(x,y) = pyautogui.size()
# locating center of the screen
(X,Y) = pyautogui.position(x/2,y/2)
# offsetting by radius
pyautogui.moveTo(X+R,Y)
for i in range(360):
# setting pace with a modulus
if i%6==0:
pyautogui.moveTo(X+R*math.cos(math.radians(i)),Y+R*math.sin(math.radians(i)))
There is a way to do this using sin, cos, and tan. (I haven't been able to test this code yet, It might not work.)
Import math
Import pyautogui
def circle(radius = 5, accuracy = 360, xpos=0, ypos=0, speed = 5):
local y
local x
local angle
angle = 360/accuracy
local CurAngle
CurAngle = 0
x = []
y = []
sped = speed/accuracy
for i in range(accuracy):
x.append(xpos + radius*math.sin(math.radians(CurAngle)))
y.append(ypos + radius*math.cos(math.radians(CurAngle)))
CurAngle += angle
for i in len(x):
pyautogui.moveTo(x[i], y[i], duration = sped)
You put this near the top of your script, and pass arguments like this:
circle(radius, accuracy, xpos, ypos, speed)
Radius controls the width of the circle
Accuracy controls how many equi-distant points the circle is to be broken up into, setting accuracy to 4 will put 4 invisible points along the circle for the mouse to travel tom which will make a square, not a circle, 5 makes a pentagon, 6 a hexagon, etc.. the bigger the radius, the bigger you will want the accuracy
Xpos controls the x position of where the circle is centered
Ypos controls the y position of where the circle is centered
Speed controls how many seconds you want it to take to draw the circle.
Hope this helps :) Would you mind elaborating what you are wanting when you say 'curves'

Unexpected results drawing ellipse using Python Turtle Module

I'm trying to draw an ellipse using Turtle module in Python, my plan is as follow:
Let the starting point be the focal point of the ellipse
Set the initial theta value to 0
Let the turtle forward, let the distance of the forwarding be a*(1-ee)/(1-emath.cos(theta))
Let it turn around and back to the original spot
Make a very small turn, update the theta value
Repeat the above process
Here's my actual code:
import turtle
import math
wn = turtle.getscreen()
wn.bgcolor("red")
My_Turtle = turtle.Turtle()
My_Turtle.penup()
My_Turtle.speed(9)
i=0
j=0
a=200
e=0.5
x_0 = 20
theta = 0
while(i<5000):
#Plotting squares
My_Turtle.penup()
ellipse = a*(1-e*e)/(1-e*math.cos(theta))
My_Turtle.forward(ellipse)
My_Turtle.pendown()
My_Turtle.forward(1)
My_Turtle.left(180)
My_Turtle.penup()
My_Turtle.forward(ellipse+1)
However, the results were really off like this:(Not the complete image but can see that it's already off)
enter image description here
Can anyone explain to me where I get it wrong ? Thank you very much!
I'm used to drawing ellipses from the center, not from one focal point so I read up on ellipse math to get my head around this. Your key formula appears to be correct:
ellipse = a*(1-e*e)/(1-e*math.cos(theta))
The issue is how you do your drawing. First you need to add setheading() to point your turtle in the correct direction. (Remember that by default it's in degrees so we need to either convert or change turtle's default). Second, how you bridge between steps in your drawing isn't sufficient.
I've reworked your code below, and have compared it to a center-based solution to confirm it generates the same ellipse:
import math
from turtle import Turtle, Screen
my_screen = Screen()
my_turtle = Turtle(visible=False)
my_turtle.speed('fastest')
my_turtle.radians()
my_turtle.penup()
e = 0.5 # linear eccentricity
a = 200 # semi major axis
c = e * a # distance from center to focal point
my_turtle.goto(-c, 0) # starting at a focal point
there = (2 * c, 0) # initialize previous point visited
step = 0.1
theta = step # already at starting point, so calculate next point
while theta < math.pi * 2 + step: # overshoot to close curve
# draw ellipse from one focus point
my_turtle.setheading(theta)
distance = a * (1 - e * e) / (1 - e * math.cos(theta))
my_turtle.forward(distance)
here = my_turtle.position()
my_turtle.pendown()
my_turtle.goto(there) # draw line from last position to this one
my_turtle.penup() # comment out to demonstrate algorithm
my_turtle.goto(-c, 0) # return to focal point
there = here
theta += step
my_screen.exitonclick()
OUTPUT
I left the pen down for this illustrution so it's obvious that it's forming the ellipse from one focal point.

Python turtle circle function

So I'm reading a book to learn python and I got to a part about the module turtle.
So after explaining it, it gives you some exercises.
One of them is to define a function that creates regular polygons.
I got this to work.
import turtle
bob = turtle.Turtle()
def polygon(t, l, n):
angle = 360/n
for i in range(n):
t.fd(l)
t.lt(angle)
polygon(bob, 40, 5)
For example this draws a regular pentagon.
The next exercise asks you to draw a "circle" changing the number of sides of the polygon.
The problem is that sometimes it doesn't work and the polygon/circle doesn't close.
I tried to find the solution by changing lots of time both the lenght and the number of sides or only one of the two but I didn't succeed.
For example, lenght = 10 and n°sides = 140 doesn't work, instead lenght = 20 and n°sides = 120 works.
Can someone explain, please?
Found solution.
Being a beginner I forgot about integers and floats.
That's why the "circle" wasn't closing.
Your code works fine in Python 3 but didn't close the polygon in Python 2 due to the difference in how division works. The fix is to simply use 360.0 instead of 360 and then it works fine in both:
from turtle import Turtle, Screen
def polygon(t, l, n):
angle = 360.0 / n
for _ in range(n):
t.fd(l)
t.lt(angle)
bob = Turtle()
polygon(bob, 10, 140)
screen = Screen()
screen.exitonclick()
Python turtle's own circle() method actually draws polygons with the default assumption that 60 sides is sufficient to look like a circle on the screen. Unless the circle is very small (then it uses fewer sides) or the user insists on more (or less) sides via the steps argument.
Try putting 360.0 instead of 360, because the initial value of Python is in integers.
We want to convert it into decimals, that's why we put the .0 after the 360.

I need help forming a circle with cubes, useing blender 2.69 with python engine

Please forgive me, but I only really know how to somewhat code in VB, and python is not what I'm used to. I did try to see if other people have made and or shown an algorithm that I'm trying to accomplish.
I have a visualizer design in my head and What I have been trying to do is get a number of cubes (variable input for now) to be placed a certain distance (maybe 5-10 blender units) from the center of the scene and angle the faces so that there will be one face pointing to the center and one face pointing the opposite direction. I'm trying to just start with 10 cubes because I feel like it will be a fair number to hopefully show a circle shape.
I made an image to help describe what I am trying to do:
All I have been able to figure out so far is that I need to add a cube with a certain rotation, and that rotation needs to be stepped for each cube. so a small equation is needed, something like this.
(10) (36)
360 / numberOfCubes = steppedAngle
That's all I have been able to figure out because I don't know how to program python to do such.
Any help is greatly appreciated, and will be credited in the final render.
Update: 1
Thanks to the help from the answer below, I finally got it to work how i wanted.
img http://vvcap.net/db/bKKUz3Uw4WUqL_WVDU0j.png
and here is the code written in help from the answer below.
'
import bpy
import math
##num of cubes
n = 10
##distange from center
radius = 7
for i in range(1, n + 1):
angle = (i - 1) * math.pi * 2 / n
xcoord=(radius * math.cos(angle))
ycoord=(radius * math.sin(angle))
bpy.ops.mesh.primitive_cube_add(location=(xcoord,ycoord,0),rotation=(0,0,angle))
'
Let's start with cubes in a circle, and we will work our way from there.
You have N cubes, and you want to place them in a circle of radius R around the center of the universe (0,0,0).
Applying basic trigonometry:
Each cube is on one of the radius of the circle, when you divide the circle by N. Therefore, your first cube is at 0 rad, your second cube is at 2*pi/N rad, your third cube is at 2 * 360/N rad, ... your N cube is at (N-1) * 2*pi/N rad. Now we have a formula:
Location of the cube in the circle = (i - 1) * 2*pi/N in radians, for each i from 1 to N.
Now, the location in space coordinates is (r*cos(angle), r*sin(angle), 0) for a circle that is placed on the XY plane and it's center is on (0,0,0).
My Blender Python is very rusty, so I won't provide you a complete solution, but it should be this way:
import math
for i in range(1, N + 1):
angle = (i - 1) * math.pi * 2 / N
x_coord = radius * math.cos(angle)
y_coord = radius * math.sin(angle)
z_coord = 0
cube = place_cube(x_coord, y_coord, z_coord)
This will place the cubes on the right coordinates, but it won't turn them the right way. Fortunately, you can rotate each cube by angle, and get it in the right orientation. So you can do:
import math
for i in range(1, N + 1):
angle = (i - 1) * math.pi * 2 / N
x_coord = radius * math.cos(angle)
y_coord = radius * math.sin(angle)
z_coord = 0
cube = place_cube(x_coord, y_coord, z_coord)
cube.rotate_around_z(angle)
I have not provided the place_cube and rotate_around_z functions because I hardly remember the Blender Python api, but it shouldn't be too hard.

Categories