Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
201 views
in Technique[技术] by (71.8m points)

Formula for detecting if rectangles will overlap (Python Turtle)?

For this program I am looking for it to not draw if it detects it will overlap with another rectangle. What is the simplest way to solve this or the best formula to do this? The program draws randomly sized rectangles randomly inside a 600x500 rectangle. Here is the code:

from draw_house import *

still_making_house = True

screen = Screen()
screen.screensize(10000, 10000)

builder = DrawHouse()

builder.build_house()

builder.build_windows()

from turtle import *
import random

t = Turtle()
t.color("red")
t.speed()


class DrawHouse:
    def build_house(self):
        for i in range(2):
            t.forward(600)
            t.right(90)
            t.forward(500)
            t.right(90)

    def build_windows(self):
        loops = 0
        while loops<50:
            topLeftX = random.randint(0, 601)
            topLeftY = random.randint(-501, 0)

            bottomRightX = random.randint(0, 601)
            bottomRightY = random.randint(-501, 0)

            flag = None

            if(20 <= bottomRightX - topLeftX <= 50 and 15 <= bottomRightY - topLeftY <= 40):
                flag = True
                loops+=1
        
            while(bottomRightX <= topLeftX):
                topLeftX = random.randint(0, 601)
                bottomRightX = random.randint(0, 601)

            if flag == True:
                t.color("green")
                t.penup()
                t.goto(topLeftX, topLeftY)
                t.pendown()
                t.goto(bottomRightX, topLeftY)
                t.goto(bottomRightX, bottomRightY)
                t.goto(topLeftX, bottomRightY)
                t.goto(topLeftX, topLeftY)
question from:https://stackoverflow.com/questions/65517152/formula-for-detecting-if-rectangles-will-overlap-python-turtle

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The first issue with your code is that it really isn't object-oriented, despite defining a class. Your object encapsulation is messed up and there are no instance methds, as self is never used. To solve your overlap issue, we can use this existing doOverlap() code from GeeksForGeeks and coerce your data to fit its logic:

from random import randint

HOUSE_WIDTH, HOUSE_HEIGHT = 600, 500

WINDOWS_COUNT = 50

WINDOW_MINIMUM_WIDTH, WINDOW_MAXIMUM_WIDTH = 20, 50
WINDOW_MINIMUM_HEIGHT, WINDOW_MAXIMUM_HEIGHT = 15, 40

class DrawHouse:
    @staticmethod
    def build_house(t):
        t.color('red')
        t.penup()
        t.goto(-HOUSE_WIDTH/2, HOUSE_HEIGHT/2)
        t.pendown()

        for _ in range(2):
            t.forward(HOUSE_WIDTH)
            t.right(90)
            t.forward(HOUSE_HEIGHT)
            t.right(90)

    @staticmethod
    def build_windows(t):
        t.color('green')

        windows = []

        while len(windows) < WINDOWS_COUNT:
            topLeftX = bottomRightX = 0
            bottomRightY = topLeftY = 0

            while bottomRightX <= topLeftX:
                topLeftX = randint(1 - HOUSE_WIDTH//2, HOUSE_WIDTH/2 - WINDOW_MINIMUM_WIDTH)
                bottomRightX = randint(topLeftX + 1, HOUSE_WIDTH//2 - 1)

            while bottomRightY >= topLeftY:
                topLeftY = randint(WINDOW_MINIMUM_HEIGHT - HOUSE_HEIGHT//2, HOUSE_HEIGHT/2 - 1)
                bottomRightY = randint(1 - HOUSE_HEIGHT//2, topLeftY - 1)

            if WINDOW_MINIMUM_WIDTH < abs(bottomRightX - topLeftX) < WINDOW_MAXIMUM_WIDTH 
                and WINDOW_MINIMUM_HEIGHT < abs(bottomRightY - topLeftY) < WINDOW_MAXIMUM_HEIGHT:

                frame = ((topLeftX, topLeftY), (bottomRightX, bottomRightY))

                for other_frame in windows:
                    if DrawHouse.windows_overlap(frame, other_frame):
                        break
                else:  # no break

                    windows.append(frame)

                    t.penup()
                    t.goto(topLeftX, topLeftY)
                    t.pendown()
                    t.goto(bottomRightX, topLeftY)
                    t.goto(bottomRightX, bottomRightY)
                    t.goto(topLeftX, bottomRightY)
                    t.goto(topLeftX, topLeftY)

    @staticmethod
    def windows_overlap(frame1, frame2):
        ((l1x, l1y), (r1x, r1y)) = frame1
        ((l2x, l2y), (r2x, r2y)) = frame2

        # If one window is on left side of other
        if l1x >= r2x or l2x >= r1x:
            return False

        # If one window is above other
        if l1y <= r2y or l2y <= r1y:
            return False

        return True

if __name__ == '__main__':
    # from draw_house import *
    from turtle import Screen, Turtle

    screen = Screen()
    screen.setup(HOUSE_WIDTH * 1.5, HOUSE_HEIGHT * 1.5)

    turtle = Turtle()
    turtle.speed('fastest')

    builder = DrawHouse()

    builder.build_house(turtle)

    builder.build_windows(turtle)

    turtle.hideturtle()
    screen.exitonclick()

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...