微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何制作二维截取函数?

如何解决如何制作二维截取函数?

我正在创建一个 Python 程序,其中追逐者在目标之后运行。我有一个移动目标的函数,我正在尝试制作一个函数,根据自身和目标的位置、目标的方向和速度,输出追逐者需要移动的角度以拦截它自身和目标(它们总是以最高速度运行,它们的速度可能不同,也可能不同)。我发现的下图很好地描述了它的样子,但有一个重要的警告:

enter image description here

需要注意的是,如图所示,我使用的是绝对角度系统。 0 弧度是 3 点钟位置,逆时针方向继续到 2pi 弧度。因此,向上和向右是 pi/4,向前是 pi/2,向下和向右是 7pi/4,等等。

但是,在我的游戏中,有时追逐者在目标后面,有时目标向左移动。这些配置打破了公式。要么追逐者朝错误的方向移动,要么存在反正弦或反余弦的域错误。如果你好奇,我的 WIP 函数试图通过使用许多公式来解决这个问题,但仍然不起作用(它以同样的方式失败)在这文章底部

我的问题是:我如何让它适用于追逐者和目标的所有配置?我见过使用各种技术的解决方案,但它们都以与我相同的方式中断(当配置不是追逐者向右下方移动和目标向右上方移动时,追逐者向错误的方向移动和/或使用反正弦或反余弦引起域错误),或者它们使用相对角度系统。

我认为我使用的绝对角度系统有问题的原因是给定了目标角度,但目标角度与三角形内角度之间的关系根据目标角度是否在0之间而有所不同和 pi/2、pi/2 和 pi、pi 和 3pi/2,或 3pi/2 和 2pi。在我的“PS”中我有一个例子说明我的意思,如果它没有意义。

我的问题很简单:我如何制作这个功能?我做的大部分是正确的,我只需要做一个小的改变吗?我在想这完全错误吗?其他帖子是否与我的代码不同,允许我使用他们的答案(我如何在 python 中使用相对角度)?

感谢任何见解、解决方案或建议!


附言

下面是一个示例,说明为什么我使用的绝对角度测量系统有问题,以及为什么我试图在我的代码中使用许多不同的公式(请参阅我上面链接的图表以获取图表):

我们将 y 轴与连接追踪器和目标的线之间形成的角度称为“角度 Beta”。角度β可以通过获取追逐者和目标在每个方向上的距离来计算——我将这些距离称为deltaY和deltaX——并使用正弦定律。

Beta = arcsin(deltaX/d)

因此,角度 Alpha = pi/2 - targetAngle - Beta

现在,假设我们沿 y 轴翻转图像。突然之间,pi - targetAngle - Beta 什么都不是。在这种配置中,

Alpha = -pi/2 + targetAngle - Beta

公式不同,因为当我们旋转图像时,targetAngle 会发生变化——它有一个绝对引用,而不是相对引用。

我希望对我的问题的解释是清楚的-如果不是,请回复告诉我您不理解的部分,以便我澄清-我也可能是错的!

def chaseRec(self,target):
self.targetxpos = target.xpos
self.targetypos = target.ypos
self.targetspeed = target.speed
self.targetangle = target.currang - m.pi/2
print("target ang:",self.targetangle)
#gets all of the target information

self.deltaY = abs(self.ypos-self.targetypos)
self.deltaX = abs(self.xpos-self.targetxpos)
self.w = m.sqrt((self.deltaY)**2 + (self.deltaX)**2)
self.d = m.asin(self.deltaY/self.w)
self.z = m.pi/2 - self.d + self.targetangle
#Below line gives error
self.x = m.asin((self.targetspeed * m.sin(self.z)) / self.speed)


#Computes the location of (mx,my),the meeting point. Uses this to choose which formula to use to compute self.currang

if self.targetangle >= 0 and self.targetangle <= m.pi/2:
    self.mx = self.targetxpos + self.targetspeed*m.sin((m.pi/2)-self.targetangle)
    self.my = self.targetypos + self.targetspeed * m.cos((m.pi / 2) - self.targetangle)

elif self.targetangle > m.pi/2 and self.targetangle <= m.pi:
    self.mx = self.targetxpos - self.targetspeed * m.sin((3*m.pi / 2) - self.targetangle)
    self.my = self.targetypos + self.targetspeed * m.cos((3*m.pi / 2) - self.targetangle)

elif self.targetangle > m.pi and self.targetangle <= 3*m.pi/2:
    self.mx = self.targetxpos - self.targetspeed * m.sin((3 * m.pi / 2) - self.targetangle)
    self.my = self.targetypos - self.targetspeed * m.cos((3 * m.pi / 2) - self.targetangle)

else:
    self.mx = self.targetxpos + self.targetspeed * m.sin((3 * m.pi / 2) - self.targetangle)
    self.my = self.targetypos - self.targetspeed * m.cos((3 * m.pi / 2) - self.targetangle)

#Computes chaser angle

if self.mx > self.xpos:
    if self.my > self.ypos:
        self.currang = -1* self.d + self.x
    else:
        self.currang = 2*m.pi - self.d + self.x
else:
    self.currang = m.pi + self.d - self.x


#moves the defender according to currang

self.xpos += ((self.speed * framelength) / 2) * m.cos(self.currang)
print("Xpos:",self.xpos)
self.ypos += ((self.speed * framelength) / 2) * m.sin(self.currang)
print("Ypos:",self.ypos)

编辑:我几乎已经解决了这个问题,但是当追逐者比目标快时,我的功能就会中断,等等。因此,以下只是部分答案。

我想我只是让我的功能正常工作。我使用了 Jeffery Hantin 对这篇文章回复中的公式:

2d game : fire at a moving target by predicting intersection of projectile and unit

下面是我的新函数,有兴趣的朋友,附上很多我用来调试的无用的打印语句。该函数考虑了python中角度是绝对的这一事实。我还没有对它进行过广泛的测试,但我还没有能够打破它。当它追不上时,它就向前跑。

    def chaseRec(self,target):
    self.targetxpos = target.xpos
    self.targetypos = target.ypos
    self.targetspeed = target.speed
    self.targetangle = target.currang
    print("target ang:",self.targetangle)
    print("Xpos1:",self.xpos)
    print("Ypos1:",self.ypos)
    self.dX = False
    self.dY = False
    print('ds: ',self.dX,self.dY)
    #gets all of the target information

    #Calculates abs(deltaY)
    if self.targetangle <= m.pi/2:
        self.deltaY = self.targetspeed * m.sin(self.targetangle) # 23 * 1

    elif self.targetangle <=m.pi:
        self.deltaY = self.targetspeed * m.sin(m.pi-self.targetangle)
        self.dX = True

    elif self.targetangle <=3*m.pi/2:
        self.deltaY = self.targetspeed * m.sin(self.targetangle-m.pi)
        #If deltaY,deltaX is actually negative
        self.dY = True
        self.dX = True

    else:
        self.deltaY = self.targetspeed * m.sin(self.targetangle - 3*m.pi/2)
        self.dY = True

    #Calculates abs(deltaX)
    self.deltaX = m.sqrt(self.targetspeed**2 - self.deltaY**2)

    #Quadratic Parameters
    self.a = self.deltaX**2 + self.deltaY**2 - self.speed**2
    self.b = 2 * (self.deltaX * (self.targetxpos - self.xpos) + self.deltaY * (self.targetypos - self.ypos))
    self.c = (self.targetxpos - self.xpos)**2 + (self.targetypos - self.ypos)**2

    self.disc = self.b**2 - (4* self.a * self.c)

    print('data:',self.disc,self.a,self.b,self.c)
    print('data2:',self.deltaX,self.deltaY)

    #Selects root,then finds where to aim
    if self.disc < 0:
        self.currang = m.pi/2
        print('data:',self.c)
        print('data2:',self.deltaY)

    else:
        self.r1 = (-1  *self.b + m.sqrt(self.disc)) / (2 * self.a)
        self.r2 = (-1 * self.b - m.sqrt(self.disc)) / (2 * self.a)

        print('rs: ',self.r1,self.r2)
        if self.r1 < 0 and self.r2 <0:
            self.currang = m.pi/2
        elif self.r1 <= self.r2:
            if self.dX and self.dY:
                self.mx = -1 * self.r1 * self.deltaX + self.targetxpos
                self.my = -1 * self.r1 * self.deltaY + self.targetypos
            elif self.dX:
                self.mx = -1 * self.r1 * self.deltaX + self.targetxpos
                self.my = self.r1 * self.deltaY + self.targetypos
            elif self.dY:
                self.mx = self.r1 * self.deltaX + self.targetxpos
                self.my = -1 * self.r1 * self.deltaY + self.targetypos
            else:
                self.mx = self.r1 * self.deltaX + self.targetxpos
                self.my = self.r1 * self.deltaY + self.targetypos

        else:
            if self.dX and self.dY:
                self.mx = -1 * self.r2 * self.deltaX + self.targetxpos
                self.my = -1 * self.r2 * self.deltaY + self.targetypos
            elif self.dX:
                self.mx = -1 * self.r2 * self.deltaX + self.targetxpos
                self.my = self.r2 * self.deltaY + self.targetypos
            elif self.dY:
                self.mx = self.r2 * self.deltaX + self.targetxpos
                self.my = -1 * self.r2 * self.deltaY + self.targetypos
            else:
                self.mx = self.r2 * self.deltaX + self.targetxpos
                self.my = self.r2 * self.deltaY + self.targetypos

            #computes currang

        print("meeting point: ",self.mx,self.my)
        self.theta = m.atan(abs(self.my - self.ypos) / abs (self.mx - self.xpos))
        print('theta: ',self.theta)

        if self.mx > self.xpos:
            if self.my > self.ypos:
                self.currang = self.theta
            else:
                self.currang = 2 * m.pi - self.theta
        else:
            if self.my > self.ypos:
                self.currang = m.pi - self.theta
            else:
                self.currang = m.pi + self.theta

    print("Chaser ang:",self.currang)
    #finds self.currang,while avoiding domain errors

    self.xpos += ((self.speed * framelength) / 2) * m.cos(self.currang)
    print("Xpos:",self.xpos)
    self.ypos += ((self.speed * framelength) / 2) * m.sin(self.currang)
    print("Ypos:",self.ypos)
    #moves the defender according to currang

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。