如何使用图形绘制炮弹
你好,我现在需要写一个类来绘制炮弹的飞行轨迹。我写了这段代码,但似乎无法在图表上绘制出炮弹。我需要根据每个时间间隔来绘制炮弹。
from graphics import*
from math import sin, cos, radians
class Tracker:
def __init__(self,window,objToTrack):
self.objToTrack = objToTrack
self.circ = Circle(Point(objToTrack.getX(), objToTrack.getY()), 2)
self.circ.draw(window)
def update(self):
point = self.circ.getCenter()
x = point.getX()
y = point.getY()
self.circ.move(self.objToTrack.getX() - x, self.objToTrack.getY() - y)
class Projectile:
def __init__(self, angle, velocity, height):
self.xpos = 0.0
self.ypos = height
theta = radians(angle)
self.xvel = velocity * cos(theta)
self.yvel = velocity * sin(theta)
def update(self, time):
self.xpos = self.xpos + time * self.xvel
yvel1 = self.yvel - 9.8 * time
self.ypos = self.ypos + time * (self.yvel + yvel1) / 2.0
self.yvel = yvel1
def getY(self):
return self.ypos
def getX(self):
return self.xpos
def getInputs():
a = eval(input("Enter the launch angle (in degrees): "))
v = eval(input("Enter the initial velocity (in meters/sec): "))
h = eval(input("Enter the initial height (in meters): "))
t = eval(input("Enter the time interval between position calculations: "))
return a,v,h,t
def main():
angle, vel, h0, time = getInputs()
cball = Projectile(angle, vel, h0)
while cball.getY() >= 0:
cball.update(time)
print("\nDistance traveled: {0:0.1f} meters.".format(cball.xpos))
Tracker(GraphWin("Tracker",500,500),cball)
if __name__ == "__main__":
main()
1 个回答
0
首先,考虑以下问题和提示:
- Tracker.update() 什么时候会被调用?
- 你的窗口是什么时候创建的?
- 你什么时候真的在窗口上画了一个圆?
- 看看 观察者模式
你的 Tracker 类没有收到关于它对象更新的通知。而且你是在炮弹飞行的模拟之后才创建 Tracker 和窗口。现在你调用 Tracker(GraphWin("Tracker",500,500),cball)
只会在炮弹的最终位置上进行一次绘制。
要绘制出曲线,你需要这样做:
def main():
angle, vel, h0, time = getInputs()
cball = Projectile(angle, vel, h0)
win = GraphWin("Tracker",500,500,autoflush=False)
while cball.getY() >= 0:
cball.update(time)
Tracker(win,cball)
print("\nDistance traveled: {0:0.1f} meters.".format(cball.xpos))
input("Ready to close? Type any key")
win.close()
现在你在每次更新后创建一个 Tracker,这样就会在图形窗口上画一个圆。这会导致很多圆重叠在一起,从而绘制出曲线。不过,绘制的图像还是颠倒的,所以你需要再想想你的坐标系统。此外,要在 Tracker 对象外部创建窗口,否则一旦 Tracker 对象被删除,窗口就会关闭。
为了让炮弹动画能够正常运行,你需要修改你的 main() 函数,让 Tracker 知道发生了变化。对于更复杂的情况,观察者模式会很有用,但在这个情况下,只需在炮弹更新后调用 Tracker::update():
import time as sleeper
def main():
angle, vel, h0, time = getInputs()
cball = Projectile(angle, vel, h0)
win = GraphWin("Tracker",500,500)
win.setCoords(0, 0, 500, 500) #fixed coordinates
tracker = Tracker(win,cball)
while cball.getY() >= 0:
sleeper.sleep(0.1) # wait 0.1 seconds for simple animation timing
cball.update(time)
tracker.update()
print("\nDistance traveled: {0:0.1f} meters.".format(cball.xpos))
input("Ready to close? Type any key") #keep the window open
win.close()