ZhangZhihui's Blog  

 

 

复制代码
import turtle
import math
from random import uniform
from dataclasses import dataclass


WIDTH = 1200
HEIGHT = 800
MIN_V = 5
MAX_V = 15
MIN_SIZE_FACTOR = 0.7
MAX_SIZE_FACTOR = 4
START_DISTANCE = 600
R = 10
MARGIN = 50
SLEEP_MS = 20


@dataclass
class SimState:
    done: bool

    def set_done(self):
        self.done = True

    @classmethod
    def setup(cls):
        r = cls(False)
        turtle.listen()
        turtle.onkeypress(r.set_done, "space")
        return r


@dataclass
class Ball:
    m: turtle.Turtle
    r: float
    vx: float

    @classmethod
    def create(cls, original_position, size_factor, vx):
        m = turtle.Turtle()
        r = size_factor * R
        m.shape("circle")
        m.shapesize(size_factor)
        m.penup()
        m.goto(original_position, 0)

        return cls(m, r, vx)

    @property
    def mass(self):
        return math.pi * (self.r ** 2)

    def move(self):
        self.m.setx(self.m.xcor() + self.vx)

        if abs(self.m.xcor()) > WIDTH / 2 - self.r:
            self.vx *= -1


def setup_screen(title):
    turtle.setup(WIDTH + MARGIN, HEIGHT + MARGIN)
    turtle.tracer(0, 0)
    turtle.title(title)


def draw_vessel():
    m = turtle.Turtle()
    m.hideturtle()
    m.penup()
    m.goto(-WIDTH / 2, -HEIGHT / 2)
    m.pendown()
    m.sety(HEIGHT / 2)
    m.setx(WIDTH / 2)
    m.sety(-HEIGHT / 2)
    m.setx(-WIDTH / 2)


def balls_collide(b1, b2):
    return abs(b1.m.xcor() - b2.m.xcor()) <= b1.r + b2.r


def process_collision(b1, b2):
    m1, m2 = b1.mass, b2.mass
    v1 = (b1.vx * (m1 - m2) + 2 * m2 * b2.vx) / (m1 + m2)
    v2 = b1.vx + v1 - b2.vx
    
    b1.vx = v1
    b2.vx = v2


sim_state = SimState.setup()
setup_screen("Central collision")
draw_vessel()

ball1 = Ball.create(-START_DISTANCE / 2, uniform(MIN_SIZE_FACTOR, MAX_SIZE_FACTOR), uniform(MIN_V, MAX_V))
ball2 = Ball.create(START_DISTANCE / 2, uniform(MIN_SIZE_FACTOR, MAX_SIZE_FACTOR), -uniform(MIN_V, MAX_V))


def tick():
    if not sim_state.done:
        ball1.move()
        ball2.move()

        if balls_collide(ball1, ball2):
            process_collision(ball1, ball2)

        turtle.update()
        turtle.ontimer(tick, SLEEP_MS)


tick()
turtle.done()
复制代码

 

posted on   ZhangZhihuiAAA  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2023-08-04 grep - useful options
2023-08-04 grep - Meta Characters and Character Classes
 
点击右上角即可分享
微信分享提示