2D Collision Detection
APL, 279 208 206 203

s←1 ¯1
f←{x←⊣/¨z←⍺⍵[⍋⊣/¨⍺⍵]
2 2≡x:∧/0∧.=⌊(2⊃-⌿↑z)⌹⍣(≠.×∘⌽/x)⍉↑x←s×-/2⊢/↑z
2≡2⌷x:∨/((2⊃z)∇2,x[1]×(2⌷⊃z)+,∘-⍨⊂y÷.5*⍨+.×⍨y←⌽s×⊃-/y),x[1]=(×⍨3⊃⊃z)&gt;+.×⍨¨y←(s↓⌽↑z)-2⌷⊃z
~x∨.∧x[1]≠(.5*⍨+.×⍨2⊃-⌿↑z)&lt;-/⊢/¨z×s*1⌷x}


Line breaks in the function f are for clarity. They should be replaced with the statement separator ⋄

It has been so long since I last made such a complex APL program. I think the last time was this but I am not even sure that was as complex.

Input format
Basically same as the OP, except using 0 for cavity, 1 for disc and 2 for line segment.

Major update

I managed to golf a lot of chars using a different algorithm. No more g bulls**t!!

The main function f is divided into cases:



2 2≡x: Segment-segment

In this case, calculate the vector from the end points of each line and solve a system of linear equations to check if the intersection is contained within the vectors.

Caveats:


The end point of a vector is not considered as a part of the vector (while its origin is). However, if only the tip of a vector is on the other one, the input is invalid according to spec.
Non-degenerate parallel segments always returns false, regardless of collinearity.
If one of the segments is degenerate, always return false. If both segments are degenerate, always return true.


Examples: (Note caveat 1 in action in the figure on the right)





2≡2⌷x: Segment-other

In this case, the other object is a circular one. Check if the end points of the segment is within the circle using distance check.

In the disc case, also construct a line segment of the diameter perpendicular to the given segment. Check if the segments collide by recursion.
In the cavity case, sneak in a "times 0" in the construction of the said segment to make it degenerate. (See why I use 0 for cavity and 1 for disc now?) As the given segment is not degenerate, the segment-segment collision detection always return false.

Finally combine the results of the distance checks and the collision detection. For the cavity case, negate the results of the distance checks first. Then (in both cases) OR the 3 results together.

Regarding the segment-segment caveats, numbers 3 is addressed (and exploited). Number 2 is not a problems as we are intersecting perpendicular segments here, which are never parallel if they are not degenerate. Number 1 takes effect only in the disc case, when one of the given end points is on the constructed diameter. If the end point is well inside the circle, the distance checks would have taken care of it. If the end point is on the circle, since the constructed diameter is parallel to the given segment, the latter must be tangent to the circle with only one point touching the disc, which is not valid input.

Examples:







Default case: Other-other

Calculate the distance between the centers. Disc-disc collision occurs if and only if the distance is smaller than the sum of radii. Disc-cavity collision occurs if and only if the distance is greater than the difference in radii.

To take care of the cavity-cavity case, negate the result of the distance check, AND with each of the identifying integers and then OR them together. Using some logic, one can show that this process returns true if and only if both identifying integers are falsy (Cavity-cavity case), or if the distance check returned true