我正在尝试创建一个函数,如果一个点在某个圆之外,该点移动到通过圆心和点的线碰撞的点。代码:
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是线的倾斜(法语抱歉)
origine是该行的Y起源(也是法语)
teleport_range是半径,是一个常数300
我想要的实际回报用于测试目的
当我运行它时,如果它在圆圈内,则一切都很好,但如果它在外面,则会出现错误,因为它试图将阴影平方根
X =( - B + math.sqrt(B ** 2 - 4 * A * C))/(2 * A) ValueError:数学域错误
当线与圆之间没有碰撞点时,二次方程中的平方根只是负数,但是,该线经过圆心和一个点,所以应该有两个碰撞点。 / p>
我知道当线是一个常数时,只有一个碰撞点,但是当我理解为什么(B ** 2 - 4 * A * C)是负的时候我会解决这个问题
我不擅长数学,如果有人可以帮助我,也不要犹豫告诉我代码是否可以简化而不会失去清晰度
谢谢:)
答案 0 :(得分: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)
此代码首先找到从圆的中心到该点的光线的倾斜角度。然后使用该角度在圆上找到具有相同角度的点。
请注意,此代码甚至适用于圆内的点:它在圆上找到与中心角度相同的点。如果该点是圆的中心,则所需的点不明确,但代码返回一个特定点。