Concentrating on Return Point2D.Create( IntersectX, IntersectY ) is where you will get most benefit, that is if likelihood of collisions is high. If so, I would add a cache to the Point2D object so it recycles from a preallocated cache of objects rather than calling New.
if q>0 then changing:
will save some divides.
if q>0 then changing:
Local R# = (A*B - C*D)/Q If R > 1 Return Null If R < 0 Return Null Local C# = (A*E - C*G)/Q If C > 1 Return Null If C < 0 Return Null to: Local R# = (A*B - C*D) If R > q Return Null If R < 0 Return Null Local C# = (A*E - C*G) If C > q Return Null If C < 0 Return Null
will save some divides.