DEV Community

loading...
Cover image for Starry Night with Python Turtle

Starry Night with Python Turtle

taarimalta
・3 min read

In the previous posts we did

  1. Filled Stars
  2. Spirals
  3. Rainbow and clouds

In this article we will draw a night sky with a crescent moon. This will give us an opportunity to play with the random library of Python.

Set up the canvas

Let's set up the screen to a defined size and color it black like the dark of night.

import turtle as t

SCREEN_WIDTH=1000
SCREEN_HEIGHT=1000

t.Screen().screensize(SCREEN_WIDTH,SCREEN_HEIGHT)
t.Screen().setworldcoordinates(-SCREEN_WIDTH,-SCREEN_HEIGHT,SCREEN_WIDTH,SCREEN_HEIGHT)
t.Screen().bgcolor("black")
Enter fullscreen mode Exit fullscreen mode

We are setting up a square grid of coordinates

image

Generate stars

We can approximate stars by simply using white dots

import turtle as t

SCREEN_WIDTH=1000
SCREEN_HEIGHT=1000
STAR_COLOR="white"

t.Screen().screensize(SCREEN_WIDTH,SCREEN_HEIGHT)
t.Screen().setworldcoordinates(-SCREEN_WIDTH,-SCREEN_HEIGHT,SCREEN_WIDTH,SCREEN_HEIGHT)
t.Screen().bgcolor("black")


t.penup()
t.color(STAR_COLOR, STAR_COLOR)

t.goto(100,100)
t.dot(1)
t.goto(20,20)
t.dot(2)
t.goto(-100, -10)
t.dot(1)
t.goto(10,-100)
t.dot(1)

t.hideturtle()
Enter fullscreen mode Exit fullscreen mode

In the code above all we're doing is moving the turtle into different coordinates on the screen to plot dots.

image

Instead of manually defining the coordinates of the stars lets randomly generate them. Here's how we can do that

import random

for _ in range(1000)
    x = random.randint(-1000,1000)
    y = random.randint(-1000,1000)

    print(x,y)

Enter fullscreen mode Exit fullscreen mode

This will print a series of coordinates which are pseudo-random

779 -633
359 357
622 410
-606 -540
-532 517
-67 -378
...
74 220
-953 204
-240 712
57 994
Enter fullscreen mode Exit fullscreen mode

We will use the method above to generate the coordinates of the star. Here is the code

import turtle as t
import random

SCREEN_WIDTH=1000
SCREEN_HEIGHT=1000
STAR_COLOR="white"

t.Screen().tracer(0,0)
t.Screen().screensize(SCREEN_WIDTH,SCREEN_HEIGHT)
t.Screen().setworldcoordinates(-SCREEN_WIDTH,-SCREEN_HEIGHT,SCREEN_WIDTH,SCREEN_HEIGHT)
t.Screen().bgcolor("black")



def random_star():
  t.penup()
  t.color(STAR_COLOR, STAR_COLOR)

  x=random.randint(-SCREEN_WIDTH,SCREEN_WIDTH)
  y=random.randint(-SCREEN_HEIGHT,SCREEN_HEIGHT)

  dot_size=random.random()*3

  t.goto(x,y)
  t.dot(dot_size)


for _ in range(1000):
    random_star()

t.hideturtle()
t.Screen().update()
Enter fullscreen mode Exit fullscreen mode

In the code above we have not only randomized the location of the stars but also the size of the stars (using dot). The size of the dot uses random.random()*3 instead of randint function. This gives us continuous random sizes as opposed to discreet.

Here is the result:

image

Now all we need is a moon

Draw a crescent moon

A direct approach to drawing a moon could be to draw a semicircle, then turn the turtle around and draw another arc to complete the loop. We will use an easier way where we don't have to compute the angles.

Here is the function that draws a moon

def moon(size=100):
  t.penup()
  t.left(20)

  t.color(MOON_COLOR, MOON_COLOR)
  t.dot(size)
  t.forward(size*.25)
  t.color(NIGHT_COLOR, NIGHT_COLOR)
  t.dot(size)
Enter fullscreen mode Exit fullscreen mode

We are simply drawing a large white dot and then overlapping a large black dot on top of it.

One disadvantage of this approach is that some stars that are located outside the sphere of the moon are erased, but maybe no one will notice ;)

Here is the final code:

import turtle as t
import random

SCREEN_WIDTH=1000
SCREEN_HEIGHT=1000
STAR_COLOR="#f0ffff"
MOON_COLOR="#FFFFF0"
NIGHT_COLOR="black"

t.Screen().tracer(0,0)
t.Screen().screensize(SCREEN_WIDTH,SCREEN_HEIGHT)
t.Screen().setworldcoordinates(-SCREEN_WIDTH,-SCREEN_HEIGHT,SCREEN_WIDTH,SCREEN_HEIGHT)
t.Screen().bgcolor(NIGHT_COLOR)

def moon(size=100):
  t.penup()
  t.left(20)

  t.color(MOON_COLOR, MOON_COLOR)
  t.dot(size)
  t.forward(size*.25)
  t.color(NIGHT_COLOR, NIGHT_COLOR)
  t.dot(size)

def random_star():
  t.penup()
  t.color(STAR_COLOR, STAR_COLOR)

  x=random.randint(-SCREEN_WIDTH,SCREEN_WIDTH)
  y=random.randint(-SCREEN_HEIGHT,SCREEN_HEIGHT)

  dot_size=random.random()*3

  t.goto(x,y)
  t.dot(dot_size)


for _ in range(1000):
    random_star()

moon(150)

t.hideturtle()
t.Screen().update()
Enter fullscreen mode Exit fullscreen mode

Note that the location of the moon is going to be random too

image

Yay!!~~

Discussion (0)