BenjaminT
BenjaminT

Reputation: 65

How do I generate random dots inside my turtle circle and rectangle?

Inside turtle graphics, I drew a rectangle and a circle. How can I put 10 random dots in each of my shapes? This is the code I have:

import turtle
import math
import random 

# draw a rectangle at a specific location
def drawRectangle(x = -75, y = 0, width = 100, height = 100): 
    turtle.penup() # Pull the pen up
    turtle.goto(x + width / 2, y + height / 2)
    turtle.pendown() # Pull the pen down
    turtle.right(90)
    turtle.forward(height)
    turtle.right(90)
    turtle.forward(width)
    turtle.right(90)
    turtle.forward(height)
    turtle.right(90)
    turtle.forward(width)    


# Draw a circle at a specific location
def drawCircle(x = 50, y = 0, radius = 50): 
    turtle.penup() # Pull the pen up
    turtle.goto(x, -50)
    turtle.pendown() # Pull the pen down
    turtle.begin_fill() # Begin to fill color in a shape
    turtle.circle(radius) 

Upvotes: 1

Views: 8715

Answers (1)

mattapet
mattapet

Reputation: 36

Generating random dots inside of a rectangle, is fairy simple. You just generate a random x coordinate, in range from the origin position of (-75 in your case), until the end of it, which would be the origin + width (-75 + 100). Then, you would do the same for the y coordinate. Afterwards, you move to the generated position and draw a dot.

My code:

# draw random dots inside of rectangle
# @param origin: is a touple, containing `x` and `y` coordinates
# @param number_of_dots: int, number of dots
# @param size:   is a touple, containing `width` and `height` of rectangle
def draw_random_dots_in_rectangle(origin, number_of_dots, size=RECTANGLE_SIZE):
    # loops number_of_dots times
    for _ in range(number_of_dots):
        # generate a random position inside of given rectangle
        # using min/max, because of possible negative coordinates
        # weakness - does also place dots on the edges of the rectangle
        rand_x = randint(min(origin[0], origin[0] + size[0]), max(origin[0], origin[0] + size[0]))
        rand_y = randint(min(origin[1], origin[1] + size[1]), max(origin[1], origin[1] + size[1]))
        # moves to the random position
        move_turtle_to((rand_x, rand_y))
        # creates a dot
        t.dot(DOT_DIAMETER)

However, doing the same with circle is not possible. It's far more complex and requires knowledge of analytic geometry. In your case, you need equation of circles. With that you can calculate, if the generated position is, or is not inside of the given circle.

My code:

# draw random dot inside of circle
# @param origin: is a touple, containing `x` and `y` coordinates
# @param number_of_dots: int, number of dots
# @param radious: int, radious of circle
def draw_random_dots_in_circle(origin, number_of_dots, radius=CIRCLE_RADIOUS):
    # loops number_of_dots times
    for _ in range(number_of_dots):
        # loops until finds position inside of the circle
        while True:
            # generates random x position
            # subtracting radious and adding double of radious to simulate bounds of square
            # which would be large enought to fit the circle
            rand_x = randint(min(origin[0] - radius, origin[0] + radius * 2),
                             max(origin[0] - radius, origin[0] + radius * 2))
            # generated random y position
            # adding  double of radious to sumulate bounds of square
            # which would be large enought to fit the circle
            rand_y = randint(min(origin[1], origin[1] + radius * 2),
                             max(origin[1], origin[1] + radius * 2))

            # test if the generated position is in the radious
            if (origin[0] - rand_x) ** 2 + (origin[1] + radius - rand_y) ** 2 < radius ** 2:
                # if it is, move to the position
                move_turtle_to((rand_x, rand_y))
                # draw dot
                t.dot(DOT_DIAMETER)
                # break out from the infinite loops
                break

Essentially it is the same process as before, but with that equational check.
I hope this helps at least a little bit. I myself have struggled many times figuring out how to do certain thing in computer science and many time I found out, that analytic geometry was the answer. So I highly recommend checking it out at least a little bit.
My hole code:

#!/usr/bin/env python3

import turtle
from random import randint

RECTANGLE_SIZE = 60, 80
CIRCLE_RADIOUS = 10
DOT_DIAMETER   = 3

t = turtle.Turtle() # turtle object
t.speed(0)          # set the fastest drawing speed

# move turtle to position without drawing
# @param: position is a touple containing `x` and `y` coordinates
def move_turtle_to(position):
    t.up()   # equivalent to .penuo()
    t.goto(position[0], position[1])
    t.down() # equivalent to .pendown()


# draws a rectangle from given origin with given size
# @param origin: is a touple, containing `x` and `y` coordinates
# @param size:   is a touple, containing `width` and `height` of rectangle
def draw_rectangle(origin, size=RECTANGLE_SIZE):
    # movese to the origin
    move_turtle_to(origin)

    # simple way of drawing a rectangle
    for i in range(4):
        t.fd(size[i % 2])
        t.left(90)

# draws a circle from given origin with given radious
# @param origin: is a touple, containing `x` and `y` coordinates
# @param radious: int, radious of circle
def draw_circle(origin, radius=CIRCLE_RADIOUS):
    # moves to the origin
    move_turtle_to(origin)
    # draws the circle
    t.circle(radius)


# Now to what you asked
# draw random dots inside of rectangle
# @param origin: is a touple, containing `x` and `y` coordinates
# @param number_of_dots: int, number of dots
# @param size:   is a touple, containing `width` and `height` of rectangle
def draw_random_dots_in_rectangle(origin, number_of_dots, size=RECTANGLE_SIZE):
    # loops number_of_dots times
    for _ in range(number_of_dots):
        # generate a random position inside of given rectangle
        # using min/max, because of possible negative coordinates
        # weakness - does also place dots on the edges of the rectangle
        rand_x = randint(min(origin[0], origin[0] + size[0]),     max(origin[0], origin[0] + size[0]))
        rand_y = randint(min(origin[1], origin[1] + size[1]),     max(origin[1], origin[1] + size[1]))
        # moves to the random position
        move_turtle_to((rand_x, rand_y))
        # creates a dot
        t.dot(DOT_DIAMETER)

# draw random dot inside of circle
# @param origin: is a touple, containing `x` and `y` coordinates
# @param number_of_dots: int, number of dots
# @param radious: int, radious of circle
def draw_random_dots_in_circle(origin, number_of_dots, radius=CIRCLE_RADIOUS):
    # loops number_of_dots times
    for _ in range(number_of_dots):
        # loops until finds position inside of the circle
        while True:
            # generates random x position
            # subtracting radious and adding double of radious to simulate bounds of square
            # which would be large enought to fit the circle
            rand_x = randint(min(origin[0] - radius, origin[0] + radius * 2),
                             max(origin[0] - radius, origin[0] + radius * 2))
            # generated random y position
            # adding  double of radious to sumulate bounds of square
            # which would be large enought to fit the circle
            rand_y = randint(min(origin[1], origin[1] + radius * 2),
                             max(origin[1], origin[1] + radius * 2))

            # test if the generated position is in the radious
            if (origin[0] - rand_x) ** 2 + (origin[1] + radius - rand_y) ** 2 < radius ** 2:
                # if it is, move to the position
                move_turtle_to((rand_x, rand_y))
                # draw dot
                t.dot(DOT_DIAMETER)
                # break out from the infinite loops
                break


# example code
draw_rectangle((0, 0))

draw_random_dots_in_rectangle((0, 0), 50)

draw_circle((-20, -20))

draw_random_dots_in_circle((-20, -20), 20)

input()

Upvotes: 2

Related Questions