这个挑战基于我最近不得不为一个简单的游戏编写的实际碰撞检测。
编写一个程序或函数,给定两个对象,该程序或函数将根据两个对象是否发生碰撞(即相交)来返回真实值或虚假值。
您需要支持三种类型的对象:
- 线段:由4个浮点数表示,指示两个端点,即(x 1,y 1)和(x 2,y 2)。您可以假定端点不相同(因此线段不会退化)。
- 圆盘:即实心圆,以3个浮点表示,两个为中心(x,y),一个为(正)半径r。
- 腔:这些是光盘的补充。也就是说,除了由中心和半径指定的圆形区域之外,空腔会填充所有2D空间。
您的程序或函数将以标识整数(您选择的形式)及其3或4个浮点的形式接收两个此类对象。您可以通过STDIN,ARGV或函数参数接受输入。您可以使用任何未经预处理的方便形式来表示输入,例如8到10个单独的数字,两个以逗号分隔的值列表或两个列表。结果可以返回或写入STDOUT。
您可以假设对象至少为10相隔 -10个长度单位或相交那么多,因此您不必担心浮点类型的局限性。
这是代码高尔夫球,因此最短的答案(以字节为单位)获胜。
测试用例
使用基于列表的输入格式,用表示线段,用表示0
圆盘,用表示1
空洞2
,以下内容均应产生真实的输出:
[0,[0,0],[2,2]], [0,[1,0],[2,4]] # Crossing line segments
[0,[0.5,0],[-0.5,0]], [1,[0,0],1] # Line contained in a disc
[0,[0.5,0],[1.5,0]], [1,[0,0],1] # Line partially within disc
[0,[-1.5,0.5],[1.5,0.5]], [1,[0,0],1] # Line cutting through disc
[0,[0.5,2],[-0.5,2]], [2,[0,0],1] # Line outside cavity
[0,[0.5,0],[1.5,0]], [2,[0,0],1] # Line partially outside cavity
[0,[-1.5,0.5],[1.5,0.5]], [2,[0,0],1] # Line cutting through cavity
[1,[0,0],1], [1,[0,0],2] # Disc contained within another
[1,[0,0],1.1], [1,[2,0],1.1] # Intersecting discs
[1,[3,0],1], [2,[0,0],1] # Disc outside cavity
[1,[1,0],0.1], [2,[0,0],1] # Disc partially outside cavity
[1,[0,0],2], [2,[0,0],1] # Disc encircling cavity
[2,[0,0],1], [2,[0,0],1] # Any two cavities intersect
[2,[-1,0],1], [2,[1,0],1] # Any two cavities intersect
而以下所有内容都将导致错误的输出
[0,[0,0],[1,0]], [0,[0,1],[1,1]] # Parallel lines
[0,[-2,0],[-1,0]], [0,[1,0],[2,0]] # Collinear non-overlapping lines
[0,[0,0],[2,0]], [0,[1,1],[1,2]] # Intersection outside one segment
[0,[0,0],[1,0]], [0,[2,1],[2,3]] # Intersection outside both segments
[0,[-1,2],[1,2]], [1,[0,0],1] # Line passes outside disc
[0,[2,0],[3,0]], [1,[0,0],1] # Circle lies outside segment
[0,[-0.5,0.5],[0.5,-0.5]], [2,[0,0],1] # Line inside cavity
[1,[-1,0],1], [1,[1,1],0.5] # Non-intersecting circles
[1,[0.5,0],0.1], [2,[0,0],1] # Circle contained within cavity
[0,[-2,0],[-1,0]], [0,[1,0],[2,0]]