So, what you need is to wire these things down to Bloc.Then whenever you need to test whether point within shape or not, you can convert any path into polygon and perform the test. And of course, you can cache the results of conversion in order to avoid expensive computations every time you need to perform such tests. Once path is converted, the test is relatively cheap and costs something like O(n), where n is number of line segments.
Or maybe, to simplify things, you could extend the shape protocol and introduce #containsPoint:��
or as variant #containsPoint:ifNotAvailable:��
so that if shape implements such feature - it can answer true or false, and if not - evaluating a block. So, you don't have to implement all tests for all kinds of shapes that invented or not yet invented in universe.