【问题标题】:what am I doing wrong in this equation?我在这个等式中做错了什么?
【发布时间】:2017-05-18 21:27:25
【问题描述】:

我正在尝试制作一个函数,如果一个点在某个圆之外,则该点移动到通过圆心的线与该点发生碰撞的点。代码:

def inside_circle(self, pos):
    if ((pos[0]-self.pos[0])**2 + (pos[1]-self.pos[1])**2) <= teleport_range**2:
        return "inside"#pos
    else:
        pente = (pos[1]-self.pos[1])/(pos[0]-self.pos[0])
        origine = pos[1]-pente*pos[0]
        A = pente**2 + 1
        B = 2 * -self.pos[0] + (origine+self.pos[1])*pente*2
        C = self.pos[0]**2 + (origine+self.pos[1])**2 - teleport_range**2
        if pos[0] > self.pos[0]:
            X = (-B + math.sqrt(B**2 - 4*A*C))/(2*A)
            Y = pente * X + origine
            return "outside bot"#(X,Y)
        elif pos[0] < self.pos[0]:
            X = (-B - math.sqrt(B**2 - 4*A*C))/(2*A)
            Y = pente * X + origine
            return "outside top"#(X,Y)

self.pos 是圆的中心,pos 是我要检查的点所在的位置,两者都是元组

pente 是线的倾斜度(法语对不起)

origin 是直线的 Y 原点(也是法语)

teleport_range 是半径,为常数 300

我想要的实际回报被注释以用于测试目的

当我运行它时,如果它在圆圈内,一切都很好,但如果它在外面,则会出现错误,因为它试图将负数平方根

X = (-B + math.sqrt(B**2 - 4*A*C))/(2*A) ValueError:数学域错误

二次方程中的平方根只有当直线和圆之间没有碰撞点时才为负,但是直线经过圆心和一点,所以应该有两个碰撞点。

我知道当直线为常数时只能有一个碰撞点,但当我理解为什么 (B**2 - 4*A*C) 不应该为负时,我会解决这个问题

我数学不好,如果有人可以帮助我,也不要犹豫告诉我代码是否可以在不失去清晰度的情况下简化

谢谢:)

【问题讨论】:

  • “什么时候不应该” - 检查你的假设。
  • 我认为没有人愿意花时间来破译这一系列可怕的变量。
  • 是的,抱歉,我改了,忘记了一些法语变量:/

标签: math language-agnostic equation


【解决方案1】:

这是一种更简单、更短、更清晰的方法,可以让您在圆上获得所需的点。

theta = math.atan2(pos[0] - self.pos[0], pos[1] - self.pos[1])
X = self.pos[0] + teleport_range * math.cos(theta)
Y = self.pos[1] + teleport_range * math.sin(theta)

此代码首先找到射线从圆心到该点的倾斜角。然后它使用该角度在圆上找到一个具有相同角度的点。

请注意,此代码甚至适用于圆内的点:它找到圆上与圆心成相同角度的点。如果该点是圆的中心,则所需的点是不明确的,但代码会返回一个特定的点。

【讨论】:

  • 谢谢!我实际上正在研究一种类似的方法来解决 pygame Vector2 的内置函数的问题,因为我以前的方法显然太复杂了,不需要二次方程,再次感谢 :)
猜你喜欢
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多