python tkinter中的圆和线碰撞检测

时间:2014-01-18 00:01:59

标签: python math python-3.x tkinter collision-detection

我编写了一个python程序,其中一个圆圈从用户绘制的线条反弹。有多个圆圈从墙上反弹。对于每一个,应计算距圆心和球的最短距离。我更喜欢这个代码是非常有效的,因为我目前的算法经常落后于计算机。如果a点是起点,点b是终点,点c是中心,r是半径,我如何计算球之间的最短距离?如果球的X坐标超出了段AB中的x坐标范围,该算法也应该有效。

请发布python代码

任何帮助将不胜感激!

这是我到目前为止所拥有的:

lineList是一个包含4个值的列表,其中包含用户绘制的行的开始和结束坐标

中心是球的中心

global lineList, numobjects
        if not(0 in lineList):

            beginCoord = [lineList[0],lineList[1]]

            endCoord = [lineList[2]-500,lineList[3]-500]

            center = [xCoordinate[i],yCoordinate[i]+15]

            distance1 = math.sqrt((lineList[1] - center[1])**2 + (lineList[0] - center[0])**2)

            slope1 = math.tan((lineList[1] - lineList[3]) / (lineList[0] - lineList[2]))

            try:
                slope2 = math.tan((center[1] - beginCoord[1])/(center[0]-beginCoord[0]))

                angle1 = slope2 + slope1

                circleDistance = distance1 * math.sin(angle1)

            except:

                #If the circle is directly above beginCoord
                circleDistance = center[1] - lineList[1]


            global numbounces

            if circleDistance < 2 and circleDistance > -2:

                print(circleDistance)

                b = False

                b2=False

                if xCoordinate[i] < 0:

                    xCoordinate[i] += 1

                    speed1[i] *= -1

                    b=True


                elif xCoordinate[i] > 0:

                    xCoordinate[i] -= 1

                    speed1[i] *= -1

                    b=True


                if yCoordinate[i] < 0:

                    yCoordinate[i] += 1

                    speed2[i] *= -1

                    b2=True


                elif yCoordinate[i] > 0:

                    yCoordinate[i] -= 1

                    speed2[i] *= -1

                    b2=True


                if b and b2:

                 #Only delete the line if the ball reversed directions

                    numbounces += 1

                    #Add a ball after 5 bounces

                    if numbounces % 5 == 0 and numbounces != 0:

                        numobjects = 1

                        getData(numobjects)
                    canvas.delete("line")

                    lineList = [0,0,0,0]

Diagram of circles

1 个答案:

答案 0 :(得分:1)

我不知道球之间的最短距离的平均值是什么,但是如果你想计算圆圈与线接触的点,你可以用sympy来计算公式:

from sympy import *
from sympy.geometry import *
x1, y1, x2, y2, xc, yc = symbols("x1,y1,x2,y2,xc,yc")
p1 = Point(x1, y1)
p2 = Point(x2, y2)
pc = Point(xc, yc)

line = Line(p1, p2)
pline = line.perpendicular_line(pc)
p = line.intersection(pline)[0]
cse(p, symbols=numbered_symbols("t"))

输出是:

([(t0, x1 - x2), (t1, y1 - y2), (t2, x1*y2 - x2*y1), (t3, t0**2 + t1**2)],
 [Point((t0**2*xc + t0*t1*yc - t1*t2)/t3, (t0*t1*xc + t0*t2 + t1**2*yc)/t3)])

这意味着您可以将垂直点计算为:

t0 = x1 - x2
t1 = y1 - y2
t2 = x1*y2 - x2*y1
t3 = t0**2 + t1**2

xp = (t0**2*xc + t0*t1*yc - t1*t2)/t3
yp = (t0*t1*xc + t0*t2 + t1**2*yc)/t3