球物理问题Python

发布于 2024-11-14 13:20:28 字数 4964 浏览 3 评论 0原文

我试图让球在盒子内正确弹跳,特别是以特定角度处理角球并正面处理角球。我有一个问题,因为我的球总是从盒子里出来。我有这个函数可以告诉我的球是否开箱即用,并且它可以处理角落和墙壁。代码是这样的:

    if ((self._x > self._Grid.getWidth()) or (self._x < 0)):
        print("RandomNode:outside paramaters: x! self._x = %s , self._velx = %s" % (self._x , self._velx))
    if ((self._y > self._Grid.getLength())  or (self._y < 0)):
        print("RandomNode:outside paramaters: y!")
    if ((self._velx + self._x) > self._Grid.getWidth()):
        diff = self._Grid.getWidth()-self._x
        self._velx *= -1
        if (diff == 0):
            self._x -= self._velx
        else:
            self._x+= diff
        tampered = True
        #print("eqn1: self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))

    if (self._velx + self._x < 0):
        diff = self._x
        self._velx *= -1
        if (diff == 0):
            self._x += self._velx
        else:
            self._x-= diff
        tampered = True
        #print("eqn2: self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))


    if ((self._vely + self._y) > self._Grid.getLength()):
        diff = self._Grid.getLength()-self._y
        self._vely *= -1
        if (diff == 0):
            self._y -= self._vely
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn31:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx - diff)
                    self._y += self._vely
                    #print("eqn32:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn33:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))


        else:
            self._y+= diff
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn31:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx - diff)
                    self._y += self._vely
                    #print("eqn32:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn33:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))

    if (self._vely + self._y < 0):
        diff = self._y
        self._vely *= -1
        if (diff == 0):
            self._y += self._vely
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn41:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx + diff)
                    self._y += self._vely
                    #print("eqn42:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn43:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))

        else:
            self._y-= diff
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn41:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx + diff)
                    self._y += self._vely
                    #print("eqn42:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn43:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
    return tampered

我不知道为什么它不起作用。 x和y显然是它的坐标。 Velx 和 Vely 是其 x 和 y 速度。 Tampered 是一个布尔值,它会阻止球正常移动并且只能在检查范围内移动。

这是我的问题。这段代码有什么问题?或者......是否有一个用Python编写的模板在网络上的某个地方或任何地方,或者您使用过的代码可以完成我想要处理和做的事情?请随意修改代码,请告诉我。任何已解决的链接也都很棒。谢谢。

I am trying to make a ball bounce within a box correctly, specifically handling corners at specific angles and handling a corner head on. I have a problem, because my ball keeps coming out of the box. I have this function that tells if my ball is out of the box and it handles corners and walls. The code is this:

    if ((self._x > self._Grid.getWidth()) or (self._x < 0)):
        print("RandomNode:outside paramaters: x! self._x = %s , self._velx = %s" % (self._x , self._velx))
    if ((self._y > self._Grid.getLength())  or (self._y < 0)):
        print("RandomNode:outside paramaters: y!")
    if ((self._velx + self._x) > self._Grid.getWidth()):
        diff = self._Grid.getWidth()-self._x
        self._velx *= -1
        if (diff == 0):
            self._x -= self._velx
        else:
            self._x+= diff
        tampered = True
        #print("eqn1: self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))

    if (self._velx + self._x < 0):
        diff = self._x
        self._velx *= -1
        if (diff == 0):
            self._x += self._velx
        else:
            self._x-= diff
        tampered = True
        #print("eqn2: self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))


    if ((self._vely + self._y) > self._Grid.getLength()):
        diff = self._Grid.getLength()-self._y
        self._vely *= -1
        if (diff == 0):
            self._y -= self._vely
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn31:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx - diff)
                    self._y += self._vely
                    #print("eqn32:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn33:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))


        else:
            self._y+= diff
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn31:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx - diff)
                    self._y += self._vely
                    #print("eqn32:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn33:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))

    if (self._vely + self._y < 0):
        diff = self._y
        self._vely *= -1
        if (diff == 0):
            self._y += self._vely
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn41:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx + diff)
                    self._y += self._vely
                    #print("eqn42:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn43:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))

        else:
            self._y-= diff
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn41:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx + diff)
                    self._y += self._vely
                    #print("eqn42:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn43:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
    return tampered

I don't know why it is not working. x and y are obviously its coordinates. Velx and Vely are its x and y velocities. Tampered is a Boolean that prevents the ball from moving normally and only being moved within check.

Here is my question. What is wrong with this code? OR....is there a template written in python somewhere on the net or where ever, or a code that you have used that does the exact thing I am trying to handle and do? Please revise the code at will, just let me know. Any links to this already solved would be great as well. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

随风而去 2024-11-21 13:20:28

重写这段代码。对于您要解决的简单问题来说,它太复杂了。

首先,球的 2D 运动只是 2 个 1D 问题。你可以把X和Y完全分开。比如撞角就完全相当于X轴撞墙+Y轴撞墙。在 X 中撞墙只会反转 X 速度(如果你想模拟的话,可能会损失一些能量)。在 Y 方向撞墙会反转 Y 方向的速度。

第二,由于 X 和 Y 的处理非常相似,因此从中提取一个方法

def handle_axis_movement(location, velocity):
    "returns updated location and velocity"
    ...

self.x, self.vel_x = handle_axis_movement(self.x, self.vel_x)
self.y, self.vel_y = handle_axis_movement(self.y, self.vel_y)

,这会将代码量(和错误)减少一半。

第三,不必单独处理 diff==0 和 diff<0。这两种情况都意味着球撞到了墙上,并且应该反转其速度。然后您应该更正位置以考虑到它无法穿过墙壁的事实。

location += velocity
if location > max_bound:
    location = max_bound - (location - max_bound)
    velocity *= -1
if location < min_bound:
    location = min_bound - (location - min_bound)
    velocity *= -1       

Rewrite this code. It is way too complex for the simple problem you're trying to solve.

First, a 2D motion of a ball is just 2 1D problems. You can completely separate X and Y. For example, hitting a corner is completely equivalent of hitting a wall in X axis + hitting a wall in Y axis. Hitting a wall in X just reverses the X velocity (and possibly loses some energy if you want to simulate that). Hitting a wall in Y reverses Y velocity.

Second, since the handling of X and Y is so similar, extract a method out of it

def handle_axis_movement(location, velocity):
    "returns updated location and velocity"
    ...

self.x, self.vel_x = handle_axis_movement(self.x, self.vel_x)
self.y, self.vel_y = handle_axis_movement(self.y, self.vel_y)

This will cut the amount of code (and bugs) in half.

Third, you don't have to treat diff==0 and diff<0 seperately. Both cases mean the ball hit a wall, and should reverse its velocity. Then you should correct the location to account for the fact that it couldn't have passed through the wall.

location += velocity
if location > max_bound:
    location = max_bound - (location - max_bound)
    velocity *= -1
if location < min_bound:
    location = min_bound - (location - min_bound)
    velocity *= -1       
深海夜未眠 2024-11-21 13:20:28

pymunk 为您做的这么好时,您不应该重新发明这个轮子。 ;)

You shouldn't be reinventing this wheel when pymunk does it for you so well. ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文