I am an artist. I have Python installed. It works. What I am trying to do is to create images on a white screen (window) based on reiterative algorithms. I can't seem to get anything to put dots on a window. If I could just get a bit of python code that, and the library(s) that contain that code, based on an x,y coordinate, that could draw a dot in that window I pretty much could figure out the rest. Also would be nice to vary the color of the dot.
So flow control would look like:
Calculate an x,y coordinate (my equations would do that)
Specify a dot color (this might always be the same color)
Draw the dot at the specified coordinate.
Pump the x y answers from 1 above back into equation and calculate a new x,y coordinate.
Loop to 2 above a specified number of times.
I can pretty much figure all this out but the "draw the colored dot" is beyond me.
I believe the dot() method in the turtle library that comes with Python is your simplest solution:
from random import randint, choice
from turtle import Turtle, Screen
COLORS = ['red', 'green', 'blue', 'magenta', 'yellow', 'cyan']
screen = Screen()
width, height = screen.window_width(), screen.window_height()
turtle = Turtle(visible=False)
turtle.speed('fastest')
turtle.penup()
for _ in range(randint(10, 100)):
radius = randint(5, 45)
x = randint(radius - width//2, width//2 - radius)
y = randint(radius - height//2, height//2 - radius)
turtle.setposition(x, y)
turtle.dot(radius * 2, choice(COLORS))
screen.exitonclick()
Turtle also has a circle() method but it draws from the edge of a circle (based on a radius instead of a diameter) not the center like the dot() method. One advantage of circle() is the outline and fill can be different colors unlike dot().
Related
Is it possible for a turtle to detect whether it is touching a specific colour, or not, without using a grid system (i.e. allocating each cell a colour.) I am trying to create a pixelated world that a creature will navigate, and interact with, depending on what sort of tile it is touching, which will be determined based on the tile's colour.
The best you could try to replicate this Scratch project in Python would be a grid based system using the python framework, pygame.
This would mean you need to code the background, user, interface, commands, collisions. A bigger feat to do all by your own hands.
My files indicate that this would be a good video series to get started:
Setup: https://youtu.be/VO8rTszcW4s
Creating The Game: https://youtu.be/3UxnelT9aCo
I hope your endeavor is fruitful!
We can force turtle to do this by dropping down to the tkinter level. Although we think of things that the turtle draws as dead ink (as opposed to shaped turtles or stamps), they are in fact live ink from tkinter's point of view -- which is why we can clear an individual turtle's drawings and call undo(). Here's a fragile example that does this:
from turtle import Screen, Turtle
from random import random
WIDTH, HEIGHT = 800, 800
DIAMETER = 200
def chameleon(x, y):
turtle.ondrag(None)
overlapping = canvas.find_overlapping(x, -y, x, -y) # adjust to tkinter coordinates
if overlapping:
color = canvas.itemcget(overlapping[0], "fill")
if color:
turtle.fillcolor(color)
turtle.goto(x, y)
turtle.ondrag(chameleon)
screen = Screen()
screen.setup(WIDTH, HEIGHT)
canvas = screen.getcanvas()
turtle = Turtle()
turtle.hideturtle()
turtle.speed('fastest')
turtle.penup()
for x in range(-WIDTH//2, WIDTH//2, DIAMETER):
for y in range(-HEIGHT//2, HEIGHT//2, DIAMETER):
turtle.goto(x + DIAMETER/2, y + DIAMETER/2)
color = random(), random(), random()
turtle.dot(DIAMETER - 1, color)
turtle.home()
turtle.shape('turtle')
turtle.shapesize(2)
turtle.showturtle()
turtle.ondrag(chameleon)
screen.mainloop()
As you drag the turtle around the screen, it will pick up color from things drawn on the screen. This isn't a clear turtle that you're seeing through, it's reading the ink, which you can confirm for yourself as you move over the background. This code may be turtle implementation specific.
I'm not sure how well this will scale up (or more likely scale down towards pixel size objects) but should give you an idea what's possible if you're willing to embrace turtle's tkinter underpinnings, or simply use tkinter itself.
This is my first question on StackOverflow, so bear with me. I am trying to have my turtle's shape be a small circle. However, the default circle is too big for my project. Is there a way to make it smaller? My company won't let me load a gif file to be the shape of a turtle.
What I've tried so far is with a gif file where I do:
import turtle
screen = turtle.Screen()
screen.register_shape('circle1', 'circle.gif')
t = turtle.Turtle()
t.shape('circle1')
t.forward(10)
This works but uses a gif file, which my company doesn't allow. Is there a way I can do this without a gif?
Working with the set of cursors that Python provides, including 'circle', you can adjust the size of the cursor using the shapesize() method (aka turtlesize):
from turtle import Screen, Turtle
screen = Screen()
turtle = Turtle()
turtle.shape('circle')
turtle.shapesize(0.5) # make the cursor half the default size
turtle.forward(100)
screen.exitonclick()
Above, we resized it relative to it's default size. If we want to size it to a specific pixel size, we start with the knowledge that the provided cursors are based on a 20px by 20px square, and adjust accordingly:
from turtle import Screen, Turtle
CURSOR_SIZE = 20
screen = Screen()
turtle = Turtle()
turtle.shape('circle')
turtle.shapesize(15 / CURSOR_SIZE) # make the cursor 15 pixels diameter
turtle.color('black', 'white') # make it an open circle this time
turtle.forward(100)
screen.exitonclick()
What you can do is input the polynomial corresponding to the size of the circle you want.
register_shape takes in more than just a file name, it can also take in coordinates.
i.e. screen.register_shape(name, coordinates) is another way of using that function.
If you want to make the circle smaller, draw the circle with the corresponding size and append it to a list. Then convert that list into a tuple and that can be your new shape.
In general you can draw any shape, append the coordinates and use that.
Here is an example for a circle:
Specific Example
import turtle
def drawCircle(radius,iterations, t): # returns tuples
coords = []
for i in range(iterations):
t.forward(radius)
t.right(360.0/iterations)
coords.append((t.xcor(), t.ycor()))
return tuple(coords)
t = turtle.Turtle()
screen = turtle.Screen()
screen.register_shape('myCircle', drawCircle(1, 72, t))
t.shape('myCircle')
General Example
import turtle
def drawShape(t):
coords = []
while # turtle move
coords.append((t.xcor(), t.ycor()))
return tuple(coords)
t = turtle.Turtle()
screen = turtle.Screen()
screen.register_shape('myShape', drawShape(t))
t.shape('myShape')
Note that when you do have a custom shape, then turtle will automatically fill it in for you. So this won't be a circle, but a filled-in circle instead.
For a school project, I'm using Python Turtle to make an "avatar". I have curly hair, so I wrote some code to draw a black half-circle, every 10-ish degrees it stops, and makes a much smaller circle of the same color, then resumes.
The code works? It does what it's supposed to do for the first 3 smaller circles, but it seems to be random on the 4th smaller circle. I've even set the degrees to draw the half-circle to 10000 and it only completed the 4th smaller circle by 3/4ths.
import turtle
t = turtle.Turtle() #defining Turtle
def drawHair():
##debug, getting turtle to needed pos.
t.color("Moccasin")
for x in range (90):
t.forward(2.5)
t.left(1)
t.setheading(90)
##
t.color("Black")
cTime = 0 #"Timer" to determine a smaller "Curl"
for x in range (180): #SUPPOSED to draw a half-circle
t.forward(2.5) #
t.left(1) #
cTime = cTime + 1 ##For every "Degree" in the main half-circle,
##add 1 to the "Timer"
print("circle = " + str(cTime)) #debug
if cTime == 10: #If "Timer has reached it's limit"
cTime = 0 #Reset timer
for x in range (360): #Draw a full, smaller circle
t.forward(-0.4) #
t.left(1) #
I know this is more complicated than it should be. I simply want to know why this problem happens and how to fix it.
EDIT : https://imgur.com/a/uYe6UAb (Proof)
You are doing way too many draws, which repl.it seems to not like. There is actually a circle method in Turtle that draws circles (and semicircles) for you! This is a lot faster than drawing it with for loops.
Using this, and a bit of maths, I have come up with this code:
import turtle
from math import cos, sin, pi
t = turtle.Turtle() #defining Turtle
def drawHair():
##debug, getting turtle to needed pos.
t.color("Moccasin")
t.radians()
t.setheading(-pi / 2)
t.circle(140, extent=pi) # bottom semi circle
t.color("Black")
t.circle(140, extent=pi) # top semi circle
for x in range(19):
t.penup()
t.goto(cos(x*pi/18)*180+140, sin(x*pi/18)*180) # position for each curl
t.setheading(x*pi/18 + pi/2)
t.pendown()
t.circle(20)
drawHair()
I've basically used the parametric form of the equation for a circle. This is the result:
Tne problem may be that you're drawing circles that are too detailed for repl.it -- although your code should work, even Python turtle's own circle() function uses only 60 segments, not 360, to draw a circle. Even less for small circles.
Here's a rework of your code to draw all your circles in fewer segments, synchronized with your desire to draw the smaller circles every 10 degrees:
import turtle
def drawHair():
# get turtle to needed position
t.color("Moccasin")
for x in range(15):
t.forward(15)
t.left(6)
t.color("Black")
for x in range(36): # draw a half-circle
t.forward(12.5)
t.left(5)
if x % 2 == 0: # every other segment of the outer circle
for _ in range(72): # Draw a full, smaller circle
t.forward(-2)
t.left(5)
t.color("Moccasin") # finish the face outline
for x in range(15):
t.forward(15)
t.left(6)
t.hideturtle()
t = turtle.Turtle()
drawHair()
turtle.done()
I seems to work on repl.it for me. (Though repl.it does have lengthy pauses.) And the circles still appear round despite the reduced segments:
I assumed that you weren't allowed to use the turtle.circle() method, but if you can, as #Sweeper assumes, then this becomes a much simpler program:
import turtle
def drawHair():
# get turtle to needed position
t.color("Moccasin")
t.circle(143, 90)
t.color("Black")
for x in range(18): # draw a half-circle
t.circle(143, 5)
t.circle(-23) # draw a full, smaller circle
t.circle(143, 5)
t.color("Moccasin")
t.circle(143, 90)
t.hideturtle()
t = turtle.Turtle()
drawHair()
turtle.done()
You'll see the circles are slightly cruder than my first example but you can tune this using the steps parameter of turtle.circle().
My task is to write a function, drawCircle(radius,fillColor), that asks a user for the specific radius of the circle and which color they'd like the circle to be filled.
I have the circle-drawing down, but I'm struggling with getting the circle to fill with the user-defined color. Any help would be greatly appreciated.
import turtle
def drawCircle(radius, fillColor):
x=360/300 #This gives the angle
r=radius#This is the radius of the circle.
c=fillColor
c=str("")
z=1 #Placeholder for the while loop.
win=turtle.Screen()
tom=turtle.Turtle()
fillColor=tom.color()
tom.begin_fill()
while (z<=300):
tom.forward(r)
tom.right(x)
tom.forward(r)
z=z+1
win.exitonclick()
tom.end_fill()
This is my function call: drawCircle(1,"red")
There are several problems with your code:
You call win.exitonclick before tom.end_fill, so programm exits before filling (as it happens on end_fill)
You do "fillColor=tom.color()" with gets you current color. Instead use "tom.fillcolor(fillColor)"
Unnecessary copying of variables radius->r and fillColor->c
This is python. Use for whenever possible. Instead of counting using z use:
for _ in range(300):
My final code:
import turtle
def drawCircle(radius, fillColor):
x = 360/300 # This gives the angle
win = turtle.Screen()
tom = turtle.Turtle()
tom.fillcolor(fillColor)
tom.begin_fill()
for _ in range(300):
tom.forward(radius)
tom.right(x)
tom.forward(radius)
tom.end_fill()
win.exitonclick()
drawCircle(1, "red")
I have the circle-drawing down
Before addressing your fill issue, I'd argue that your premise isn't true, you don't have circle-drawing down. As #Mysak0CZ shows, your circle of radius 1 is huge -- 1 what? You're drawing a circle but have no real control over its size.
As a professional turtle wrangler, I'd go about the problem as follows. Not only your angle needs to be divided by the number of segments you plan to draw, but you need to compute a circumference based on the requested radius and chop that up as well. I do so below and include a call to turtle's own .circle() method to show that we're in the right ballpark. And I fix your minor fill issue:
import math
from turtle import Turtle, Screen # force object-oriented turtles
SEGMENTS = 60 # how many lines make up the circle
def drawCircle(radius, fillColor):
distance = math.pi * radius * 2 / SEGMENTS # circumference / SEGMENTS
angle = 360 / SEGMENTS
turtle.fillcolor(fillColor)
turtle.begin_fill()
for _ in range(SEGMENTS):
turtle.forward(distance)
turtle.left(angle) # left for .circle() compatibility
turtle.end_fill()
screen = Screen()
turtle = Turtle()
drawCircle(100, 'red')
turtle.circle(100) # for comparison
screen.exitonclick()
Here is my code for a pink circle if you are going through the same Python learning resource. I think the original code was missing an argument.
import turtle
def drawPolygon(t, sideLength, numSides):
t.goto(0, 0)
turnAngle = 360 / numSides
for i in range(numSides):
t.forward(sideLength)
t.right(turnAngle)
def drawCircle(anyTurtle, radius):
circumference = 2 * 3.1415 * radius
sideLength = circumference / 360
drawPolygon(anyTurtle, sideLength, 360)
def drawFilledCircle(anyTurtle, radius, color):
anyTurtle.fillcolor(color)
anyTurtle.begin_fill()
drawCircle(anyTurtle, radius)
anyTurtle.end_fill()
anyTurtle.hideturtle()
wn = turtle.Screen()
wheel = turtle.Turtle()
drawFilledCircle(wheel, 80, "pink")
wn.exitonclick()
So far I have this and it makes two circles but one is off-screen. I want to center it and have them separate from each other. Right now it does two loops but I want it to do one small circle then go on to make a larger one around the first in the middle of the screen. Both need to be diff. colors.
def sun_and_earth():
import turtle #allows me to use the turtles library
turtle.Turtle()
turtle.Screen() #creates turtle screen
turtle.window_height()
turtle.window_width()
turtle.bgcolor('grey') #makes background color
turtle.color("red", "green")
turtle.circle(2, 360) #draws a (size, radius) circle
turtle.circle(218, 360)
turtle.exitonclick() #exits out of turtle window on click of window
I think you may have some misunderstanding with regard to some of the functions in the turtle library. Firstly, turtle.window_height() and turtle.window_width() return the height and width of the window, so (as these values are not being assigned) those two lines do nothing. Similarly, turtle.Screen() returns an object, so again that line does nothing.
In order to centre your circles, you need to change where the turtle starts by using the turtle.setpos() function. This will change the x and y coordinates of where your turtle is. If you start the turtle one radius down, this will effectively centre the circle at (0, 0), because the center of the circle is (from the documentation) one radius to the left.
Remember to take your pen off the page when you are moving so that you don't draw lines between the two points by accident, and to put the pen back down again when you want to draw again.
Try this code:
import turtle
turtle.Turtle()
turtle.bgcolor('grey')
# decide what your small circle will look like
smallColour = "red"
smallRadius = 5
# draw the small circle
turtle.color(smallColour)
turtle.penup()
turtle.setpos(0, -smallRadius)
turtle.pendown()
turtle.circle(smallRadius)
# decide what your large circle will look like
largeColour = "white"
largeRadius = 100
# draw the large circle
turtle.color(largeColour)
turtle.penup()
print(turtle.pos())
turtle.setpos(0, -largeRadius)
print(turtle.pos())
turtle.pendown()
turtle.circle(largeRadius)
turtle.penup()
turtle.setpos(0, 0)
I hope this helps, but I think that you have a few misunderstandings about the use of the turtle, it might be a good idea to look at a tutorial or maybe take a look at the documentation
Best of luck