Best approach to incrementally cut a PolygonShape?

Topics: User Forum
Jul 16, 2013 at 6:47 AM
Before I ask my question, I'd like to say thanks for the work you put into Farseer! I'm currently using it for a Monogame/Windows8/F# project and it's working far better than I anything I could make myself.

Now for the question: I'm trying to implement a way of incrementally cutting a Polygon. Rather than requiring that both the start and end location that are both outside the polygon, I would like to be able to make linear cuts anywhere, of any length, even embedded within the shape. The use case is being able to trace out a (potentially curvy) path with your finger, and have the polygon get cut incrementally as the finger is moving.

My initial idea was to simply create small rectangular "negatives" which I can then call YuPengClipper.Difference on. However, I'm uncertain how to get this to work: what do I need to with the List<Vertices> i get back from the Difference call? The Shape object which I cut only has a single Vertices member, and I can't just turn each thing in the List into a new Shape because some of them have holes. Is the "Polygon with holes" data structure returned from Difference un-representable using a single Shape? If so, what would be the best way for me to proceed?
Jul 17, 2013 at 8:27 AM
Edited Jul 17, 2013 at 8:43 AM
So I've been fiddling with this for a while, step #1 trying to do a check-line-segment-for-intersecting-bodies. This is what I have:
            let res = ref true
            world.RayCast(
                fun (fixture: Fixture) (point: Vector2) (normal: Vector2) (fraction: float32) ->
                    if fixture.CollisionGroup <> -1s then
                        res.Value <- false
                    1.0f
                , 
                p1, 
                p2
            )
Sorry for the F#, but it should be reasonably clear what's going on (fun -> makes a delegate ref makes a mutable cell),. The idea is that i'll cast a ray, and if anyone hits it (in the correct collision group) i'll set my accumulator variable to "false". However, it isn't giving me the right answer: it's missing a lot of collisions that should pick up. In particular, I'm trying to use it to replace the following code
                [p1; p2].Select(world.TestPoint)
                        .All(fun x -> x = null || x.CollisionGroup = -1s)
The [p1; p2] just makes an IEnumerable out of the two pints. This does pick up some of the collisions the previous snippet missed (albeit it'll miss some others). Am I doing something wrong? I've read through the docs and code and can't figure out what I'm doing wrong. In theory, the ray being cast should detect every collision the two-point-check does, but that is clearly not happening. Could anyone give me any hints what's going on?

EDIT: I just checked the winding order problem (saw it in other posts) but my polygons are all BodyFactory polygons, so that shouldn't be a problem.