The turtle simulator is quite helpful for moving objects but the problem I am facing is that I don't know the pixel value of the screen where the 'turtle arrow' starts its drawing. Also, when it comes to drawing a circle, it becomes difficult to figure out the pixel coordinates of its centre. Here is an example of a code:
import turtle
ob = turtle.Turtle()
ob.right(100)
#Where does the turtle start with its head (pixel coordinates)?
ob.circle(5)
#Now the turtle draws a circle with radius 5, but in which direction will it point at first?
#How do we figure out the centre of this circle?
Could someone please help me with these two problems?
PS: I am using python 3.10
import turtle
ob = turtle.Turtle()
ob.right(100)
Where does the turtle start with its head (pixel coordinates)?
Turtles start out at (0, 0), the origin. Since you didn't move the turtle, it's head is still over the origin.
ob.circle(5)
Now the turtle draws a circle with radius 5, but in which direction will it point at first?
The turtle starts drawing the circle in whatever direction the turtle is currently pointing. For a newly hatched turtle, that's 0 degrees which is right on the screen. (Using mode 'logo' changes this default.)
Since your turtle first turned to the right 100 degrees, it will start drawing at 260 degrees heading (360 - 100), slightly to the left of straight down (i.e. 270 degrees.)
How do we figure out the centre of this circle?
If the circle was drawn with a newly hatched turtle, then the center would be at (0, 5). (To center the circle on (0, 0), for example, we'd move -5 (i.e. -radius) pixels in the Y direction.)
But your turtle started with a heading of 260 degrees. And, by default, circles are drawn counter-clockwise. So we'd expect the center of your circle to be near (5, 0), where a 270 degree heading would draw it. If we do the math, turning 90 degrees towards the center of the circle and projecting a 5 pixel line, we get:
from math import cos, sin, radians
print(5 * cos(radians(260 + 90)), 5 * sin(radians(260 + 90)))
With output: 4.92403876506104 -0.868240888334652
Similarly, we can also get the center position by doing:
ob.left(90)
ob.penup()
ob.forward(5)
print(ob.position())
With output: (4.92,-0.87)
Related
A sphere is moving in a circle.
Later the camera is tilted so as to see this from a side.
From side, it looks like a to and fro motion.
To animate this, I have to make a sphere go in a circle in a 3d plane.
But can't use MoveAlongPath because i have to have control over the angle.
This is for a Physics class. I have to show that circular motion, viewed from sideways is to and fro motion.
I also have to do calculations on the angle , that is why I have to control the angle.
Any suggestions?
I tried to do this
from manim import *
class ThreeDCameraRotation(ThreeDScene):
def construct(self):
self.camera.background_color = WHITE
self.set_camera_orientation(phi=0 * DEGREES, theta=0* DEGREES)
axes = ThreeDAxes()
circle = Circle(radius=1, color=RED)
self.add(circle, axes)
sphere = Sphere(radius=0.1,color=RED).shift(RIGHT)
#completed the setup
self.play(MoveAlongPath(sphere, circle), run_time=3, rate_func=linear)
#circular motion
self.move_camera(phi=90 * DEGREES, theta=0 * DEGREES,run_time =2)
#Camera movement
self.wait()
self.move_camera(phi=0 * DEGREES, theta=0 * DEGREES)
#again camera movement
self.wait()
But the problem with this code is that
The rotation does not continue when the camera view is changed
Is there a way to simultaneously run the animation while the angle is changing?
The angle cant be adjusted.
I want the rotation to stop when the radius is at 45 degrees from the x axis....
Is there any way to do that?
self.set_camera_orientation(phi=0 * DEGREES, theta=0* DEGREES)
axes = ThreeDAxes()
circle = Circle(radius=1, color=RED)
path = Arc(radius=1, angle=45*DEGREES,stroke_width=0.1)
self.add(circle, axes)
sphere = Sphere(radius=0.1,color=RED).shift(RIGHT)
Everything = VGroup()
Everything.add(axes)
Everything.add(circle)
Everything.add(sphere)
Everything.add(path)
self.play(Rotate(Everything,90*DEGREES,np.array([0,1,0])),MoveAlongPath(sphere, path), run_time=3, rate_func=linear)
self.wait()
instead of a camera movement, just put everything in a VGroup and rotate it. This allows you to play it along other animations.
Also for MoveAlongPath, just use an Arc of a circle if you don't want the full rotation.
from turtle import Turtle,Screen
t=Turtle()
s=Screen()
t.left(20)
from cmath import pi
print(pi)
circle=2*pi*40
print("circle=",circle)
t.circle(radius=50,extent=2*pi*50)
turtle docs says that
turtle.circle(radius, extent=None, steps=None)
Draw a circle with given radius. The center is radius units left of the turtle; extent – an angle – determines which part of the circle is drawn. If extent is not given, draw the entire circle. If extent is not a full circle, one endpoint of the arc is the current pen position. Draw the arc in counterclockwise direction if radius is positive, otherwise in clockwise direction. Finally the direction of the turtle is changed by the amount of extent.
As the circle is approximated by an inscribed regular polygon, steps
determines the number of steps to use. If not given, it will be
calculated automatically. May be used to draw regular polygons.
Trying to draw this picture using turtle, just stuck on the last bit of drawing square into a circle. squares to make circle
so far I've tried just drawing out the points of each individual line but takes way to long with some inconsistencies. What I have so far is
def square(side_length):
for i in range(4):
turtle.fd(side_length)
turtle.lt(90)
square (150)
turtle.penup()
####New Square###
turtle.left(90)
turtle.forward(75)
turtle.left(90)
turtle.forward(30)
turtle.right(180)
turtle.right(45)
turtle.pendown()
def square(side_length):
for i in range(4):
turtle.fd(side_length)
turtle.lt(90)
square (150)
This draws two squares. Now I just need to figure out a way to rotate the two squares by, say, 30 degrees clockwise 4 times. Is there a function I can use to do this, or do I just need to do a lot of math and calculate to draw each individual line?
Despite its name, turtle.circle can be used to draw other regular polygons. It also can be used to draw only part of the polygon. Combined with picking the pen up and down, you can easily draw a series of rotated shapes sharing the same center.
For example,
for i in range(19):
turtle.circle(100, 360, 4) # draw a square
turtle.penup()
# "draw" 10 degrees of the same circle, with the pen up, just to move the pen
turtle.circle(100, 10, 4)
turtle.pendown()
(The circle is just a polygon with enough sides to approximate a circle. If you don't specify the third argument explicitly, turtle picks a sufficiently large value based on the radius.)
It's a combination of the two. You need to do a little math to find the starting point for each square. However, once you move the turtle to that point and turn it to the correct heading, your block of statements to draw the four sides will work just fine.
After you draw the last side of a square, the turtle is sitting on the outer circle, facing 45 degrees off a radius to that point.
Turn the turtle 60 degrees to face across a shallow chord of the circle.
Move it the appropriate distance to traverse that chord (this is where your math comes in).
Turn the turtle another 60 degrees. You are now ready to draw the next square.
Repeat those steps for each added square.
I got a simple figure using turtle. But the problem is I dunno how to put that figure inside circle.
Code:
import turtle
painter = turtle.Turtle()
painter.pencolor("blue")
for i in range(50):
painter.forward(100)
painter.left(123*2)
painter.circle(70)
turtle.done()
A bit of trigonometry in my head and I figured the angle. Not sure if I got the radius correct though. Ideally figure out the coordinates of the center instead, but a quick and dirty solution is:
import turtle
painter = turtle.Turtle()
painter.pencolor("blue")
for i in range(50):
painter.forward(100)
painter.left(123*2)
painter.right(123)
painter.right(90)
painter.penup()
painter.forward(10)
painter.left(90)
painter.pendown()
painter.circle(70)
turtle.done()
You will need to move the turtle to the correct starting position. NOTE that's not the circle's center! It starts drawing the circle from its rightmost position - i.e., if you want a circle with radius 70 around (0,0), then move to (70,0), e.g.:
painter.penup()
painter.goto(70,0)
painter.pendown()
painter.circle(70)
FYI: I can't immediately figure out where the center of your drawing is, but I suspect it is NOT at (0,0). In all cases, you should place the turtle to the right of your shape's center, offset by the circle's radius, to make the circle go around it.
Another approach would be to average the positions of your arbitrary image and then use that average as the center of the surrounding circle:
from turtle import Screen, Turtle, Vec2D
CIRCLE_RADIUS = 70
POLYGON_LENGTH = 100
POINTS = 50
screen = Screen()
painter = Turtle()
painter.speed('fastest')
painter.pencolor("blue")
total = Vec2D(0, 0)
for _ in range(POINTS):
painter.forward(POLYGON_LENGTH)
total += painter.position()
painter.left(246)
x, y = total * (1.0 / POINTS) # Vec2D can multiply by scalar but not divide
painter.penup()
painter.goto(x, y - CIRCLE_RADIUS)
painter.setheading(0)
painter.pendown()
painter.circle(CIRCLE_RADIUS)
screen.exitonclick()
I was showing a grandson patterns drawn with Python's Turtle module,
and he asked to see concentric circles.
I thought it would be faster to use the turtle's circle() to draw them
than to write my own code for generating a circle. Ha! I am stuck.
I see that the circle produced begins its circumference at the turtle's
current location and its direction of drawing depends on turtle's current
direction of motion, but I can't figure out what I need to do to get
concentric circles.
I am not at this point interested in an efficient way of producing
concentric circles: I want to see what I have to do to get
this way to work:
def turtle_pos(art,posxy,lift):
if lift:
art.penup()
art.setposition(posxy)
art.pendown()
def drawit(tshape,tcolor,pen_color,pen_thick,scolor,radius,mv):
window=turtle.Screen() #Request a screen
window.bgcolor(scolor) #Set its color
#...code that defines the turtle trl
for j in range(1,11):
turtle_pos(trl,[trl.xcor()+mv,trl.ycor()-mv],1)
trl.circle(j*radius)
drawit("turtle","purple","green",4,"black",20,30)
You can do it like this:
import turtle
turtle.penup()
for i in range(1, 500, 50):
turtle.right(90) # Face South
turtle.forward(i) # Move one radius
turtle.right(270) # Back to start heading
turtle.pendown() # Put the pen back down
turtle.circle(i) # Draw a circle
turtle.penup() # Pen up while we go home
turtle.home() # Head back to the start pos
Which creates the picture below:
Basically it moves the turtle down one radius lenght to keep the center point for all the circles in the same spot.
From the documentation:
The center is radius units left of the turtle.
So wherever the turtle is when you start to draw a circle, the center of that circle is some distance to the right. After each circle, just move left or right some number of pixels and draw another circle whose radius is adjusted for the distance the turtle moved. For example, if you draw a circle with a radius of 50 pixels, then move right 10 pixels, you would draw another circle with a radius of 40, and the two circles should be concentric.
I am not at this point interested in an efficient way of producing
concentric circles: I want to see what I have to do to get this way to
work
To address the OP's question, the change to their original code to make it work is trivial:
turtle_pos(trl, [trl.xcor() + mv, trl.ycor() - mv], 1)
trl.circle(j * radius)
becomes:
turtle_pos(trl, [trl.xcor(), trl.ycor() - mv], 1)
trl.circle(j * mv + radius)
The complete code with the above fix and some style changes:
import turtle
def turtle_pos(art, posxy, lift):
if lift:
art.penup()
art.setposition(posxy)
art.pendown()
def drawit(tshape, tcolor, pen_color, pen_thick, scolor, radius, mv):
window = turtle.Screen() # Request a screen
window.bgcolor(scolor) # Set its color
#...code that defines the turtle trl
trl = turtle.Turtle(tshape)
trl.pencolor(pen_color)
trl.fillcolor(tcolor) # not filling but makes body of turtle this color
trl.width(pen_thick)
for j in range(10):
turtle_pos(trl, (trl.xcor(), trl.ycor() - mv), True)
trl.circle(j * mv + radius)
window.mainloop()
drawit("turtle", "purple", "green", 4, "black", 20, 30)
So now i am giving you the exact code that can draw concentric circles.
import turtle
t=turtle.Turtle()
for i in range(5):
t.circle(i*10)
t.penup()
t.setposition(0,-(i*10))
t.pendown()
turtle.done()