Finally after 136 rewrites, paper paths are now joining and intersecting each other!
You are awesome! :>
Interesting. Do you still use getIntersections() though? I was thinking that ideally it would be built on top of that and CurveLocation, to avoid duplicating code. How were you able to eliminate that? Is the new code online?
Also, there are some questions regarding coding style, scoping and other things that we should discuss when you're ready. Those can happen at the end though, when you've done the pull request.
https://groups.google.com/a/chromium.org/forum/?fromgroups=#!topic/graphics-dev/fZuCeQ2Ach4
> I would like to have the api something along the lines of:
> var result = path1.add( path2 );
> var result = path1.intersect( path2 );
> var result = path1.subtract( path2 );
> var result = path2.subtract( path2 );
I agree. #add() is unfortunate, as it adds points already. #unite() seems to way to go, as that is closer to what it's actually doing (it's not simply adding the path, it's building the union).
So how about:
path1.unite(path2);
path1.intersect(path2);
path1.subtract(path2);
path1.exclude(path2);
CompoundPath#getCurves() is implemented in a way that it returns alls curves of all contained paths, in one long array. Path#getCurves() just returns the curves for the specific path, obviously. PathItem#getIntersections() then just called this, on either CompoundPath or Path, and works for both. I am not sure what other Path related methods you rely on for the boolean operations, so we should start by looking at this, and see if there are ways to abstract those, if there are any.
Sounds good?
> After that I can do a pull request! :)
Very nice! Looking forward to that moment,
On Apr 18, 2013, at 14:12 , Harikrishnan G. <hari.e...@gmail.com> wrote:
Yes, I saw that. The reason still is that the CurveLocations returned by getIntersection don't always have a parameter defined, right? That's the bug I wanted to look into, and where I think we'll get quite a bit of performance improvement from.
as for calculating intersections, i modified the Curve._addIntersections slightly to inject a unique intersectionID. This is because I am using a fully traversible graph structure as the basis of boolean operation. this is quite similar to the graph structure used in vatti's clipping algorithm, except that we cannot use scanline approach, that will work in polygon boolean operations.my attempts at reusing the structure of Path objects failed mainly because of it's dependence on indices rather than absolute references for connectivity information between nodes and links. As far as possible I am reusing the existing code for intersections. You can see the modified function at around line nr. 460 in the same file.
Would you have suggestions as to what should be added to core structures to facilitate this? It would surely make sense.
I agree to unite, sounds better. I forgot about the exisiting add()!also what is the difference between path1.subtract and path1.exclude?
Check this page for all possible boolean operations:
http://www.angelfire.com/mi/kevincharles/inkscape/p7c4.html
Combine = #unite(), Difference = #subtract(). We could also discuss Division = #divide(), which is Difference and Intersection combined.
CompoundPath#getCurves() is implemented in a way that it returns alls curves of all contained paths, in one long array. Path#getCurves() just returns the curves for the specific path, obviously. PathItem#getIntersections() then just called this, on either CompoundPath or Path, and works for both. I am not sure what other Path related methods you rely on for the boolean operations, so we should start by looking at this, and see if there are ways to abstract those, if there are any.I'll look more into this.About other path methods that I use, path.contains(), Curve.getNearectLocation().parameter, comes to mind.
path.contains() is defined for CombinedPath too, so you can call it on both. The big question will be how you will deal with the compound path filling rules.
If I use Path.transform and then get all the curves from a Path, it returns the transformed curves (atleast for translate, it does), so that we can compute intersections on the transformed curves (as expected).However doing so for CompoundPath, doesnot apply the transform immediately (which could be optimal in other cases). So is there a way that I can make sure that CompoundPath.getCurves() will give me all the curves after applying the transform?
Yes, Paths are special in that way: They always directly apply transformations to their segments, rather than storing them in the internal matrix. All other items store them in the matrix. This makes a lot of sense for Group,to allow flash-like behavior of nested coordinate systems, and is the only option for Raster and PlacedItems, but we should use the Path-way of ding things for CompoundPaths too, since they are paths as well. I just committed that change, I hope it helps:
https://github.com/paperjs/paper.js/commit/0ab43e130b06a86d1a6c340b846f91358017ce8b
You received this message because you are subscribed to a topic in the Google Groups "Paper.js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/paperjs/OWiSAoj8w90/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to paperjs+u...@googlegroups.com.


--
You received this message because you are subscribed to a topic in the Google Groups "Paper.js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/paperjs/OWiSAoj8w90/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to paperjs+u...@googlegroups.com.
Progress update:
I updated the Tests/Demo
We should still work towards merging parts of your changes back into CurveLocation. Because the way you currently overload getIntersections, we won't be able to merge this back in since it's returning different values (points instead of locations). So the way to go I think is to add the functionality you require to implement boolean operations through CurveLocation.
So let's make a list of what exactly do you need to be added to CurveLocation, so it can be used as the core to your algorithm:
- Link to the intersecting curve
- ?
I have already added the #_id property, feel free to use it!
Item#id (= Path#id) is read-only since it is supposed to be a unique identifier that is also used internally to link to items, and my previous post to this list explains why setting _id is not normally supported. But CurveLocation is a different animal, and _id is only there for your case right now, so yes you could change it.
But I would like to add support for linking to the intersecting curve in CurveLocation. How about:
CurveLocation#intersection (through the CurveLocation#getIntersection() getter)
Returning another CurveLocation object, pointing to the same location on the other curve. Now this other CurveLocation object could point back to the original one too, through its #intersection property.
Wouldn't this remove the need for mutable _ids? And perhaps even the _id all together?
Another question: Is there a reason why you don't use Path#getIntersections(), but call Curve._addIntersections() directly? Once I would add enough features to CurveLocation I believe more of your code can merge with Path#getIntersections(), right? I'd like to reduce as much code duplication as possible, for obvious reasons.
What is the intersection strategy (as returned by #getIntersections/#Curve._addIntersections) on curves that overlap exactly on top of each other?Is it 'undefined' as of yet?
That's a very good question! I haven't looked into it yet.Is it appropriate to say, that the cures intersect at both start and end of the curve?Right now, this is the main failure case for this algorithm! (at least as far as I can say. It will almost surely fail on such cases!)
I haven't defined its behavior yet, and I think whatever is useful for boolean operations should be the way it behaves. Would the start & end be of use?
Lastly, I have looked into performance, and found that 30% of the time is spent in my #getIntersections() code.
I know that we could speed that up a lot if we did not use the current simple divide and conquer approach, but switched to fat line bezier clipping [1]. Perhaps tackling this next step might be an interesting challenge for you once this is merged in? :)


You received this message because you are subscribed to a topic in the Google Groups "Paper.js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/paperjs/OWiSAoj8w90/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to paperjs+u...@googlegroups.com.

Hi Jürg,
Thanks for the fix. It does it for the issues I submitted. But it now returns duplicate results for curves when they overlap exactly on segments (do you remember the old issue that I posted)
For now I am working around this by adding another pass to filter out the duplicates. So that I can continue working on the pull request.
<PastedGraphic-2.png>