Smooth transitions in Bézier paths
Hi,
I hope you don't mind if I increase the traffic on inkscape-devel even more ;-)
At some point an idea popped up to only snap to nodes at discontinuities in paths, and not to nodes at smooth transitions from one Bézier segment to another. This is more intuitive (less "Hey, what it is Inkscape snapping to now?") and might increase performance.
Problem is that in the object-snapper I only have access to SPCurve, which is a wrapper for "old-style" NArtBpath. It's easy to find out whether a point is inbetween two Bézier segments, but how do I find out if a transition is smooth? I guess that should be done by comparing the control points, or is there an easier way? With the transition to lib2geom, will the NArtBpath be deprecated in favor of the Path class? (that would make this rather exercise useless in the long run).
Any pointers would be appreciated here,
Diederik
Hoi Diederik,
Very nice idea! In notepath.cpp from line 4051 onwards, the node type is determined. This is saved in sodipodi:nodetypes attribute, but I don't know whether you can rely on that if it is present. I think 2geom will replace all path representations in the end, but I don't know. (I think 2geom paths also contain no information about the nodes, only about segments, correct me if I'm wrong!). Maybe if you only calculate the nodetypes when a path is loaded or changed, the speed penalty will not be that large?
Perhaps I can interest you in some other snapping business? ;-) Right now, guide-grid intersections do not snap. Another thing is angled snap lines. Angled guides are often requested, and the axonometric grid can also use those snaplines. Let me know if you want to hear what I've thought up. I won't have the time to implement it soon.
Grtz, Johan
On Tue, 2007-08-21 at 20:10 +0200, Diederik van Lierop wrote:
Hi,
I hope you don't mind if I increase the traffic on inkscape-devel even more ;-)
At some point an idea popped up to only snap to nodes at discontinuities in paths, and not to nodes at smooth transitions from one Bézier segment to another. This is more intuitive (less "Hey, what it is Inkscape snapping to now?") and might increase performance.
Problem is that in the object-snapper I only have access to SPCurve, which is a wrapper for "old-style" NArtBpath. It's easy to find out whether a point is inbetween two Bézier segments, but how do I find out if a transition is smooth? I guess that should be done by comparing the control points, or is there an easier way? With the transition to lib2geom, will the NArtBpath be deprecated in favor of the Path class? (that would make this rather exercise useless in the long run).
Any pointers would be appreciated here,
Diederik
This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Inkscape-devel mailing list Inkscape-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/inkscape-devel
Something even more annoying: node doesn't snap to path intersection. Draw horizontal and vertical lines to make a cross-like simplified shape. Drag node from some other shape along that lines. It will snap to either line but not both at the same time. (I think I've opened a bug report a long time ago for this one)
There's no visualization of snapping (pervert request -- I know it wouldn't be easy to implement) :)
And don't know about that how hard would be to implement this one... There was some mentioning of current svn version slowness when dragging shapes over the canvas (with complex drawing) because it wants to snap to everything. Would it be even possible to determine how fast user wants to move something? Like the incorruptible redrawing bulia implemented. It would work like this: User drags object. If he/she stops/slows down, try if it's some of possible snapping condition is satisfied and snap!
Vlada
On Wednesday 22 August 2007 14:33:22 Johan Engelen wrote:
Hoi Diederik,
Very nice idea! In notepath.cpp from line 4051 onwards, the node type is determined. This is saved in sodipodi:nodetypes attribute, but I don't know whether you can rely on that if it is present. I think 2geom will replace all path representations in the end, but I don't know. (I think 2geom paths also contain no information about the nodes, only about segments, correct me if I'm wrong!). Maybe if you only calculate the nodetypes when a path is loaded or changed, the speed penalty will not be that large?
Perhaps I can interest you in some other snapping business? ;-) Right now, guide-grid intersections do not snap. Another thing is angled snap lines. Angled guides are often requested, and the axonometric grid can also use those snaplines. Let me know if you want to hear what I've thought up. I won't have the time to implement it soon.
Grtz, Johan
On Tue, 2007-08-21 at 20:10 +0200, Diederik van Lierop wrote:
Hi,
I hope you don't mind if I increase the traffic on inkscape-devel even more ;-)
At some point an idea popped up to only snap to nodes at discontinuities in paths, and not to nodes at smooth transitions from one Bézier segment to another. This is more intuitive (less "Hey, what it is Inkscape snapping to now?") and might increase performance.
Problem is that in the object-snapper I only have access to SPCurve, which is a wrapper for "old-style" NArtBpath. It's easy to find out whether a point is inbetween two Bézier segments, but how do I find out if a transition is smooth? I guess that should be done by comparing the control points, or is there an easier way? With the transition to lib2geom, will the NArtBpath be deprecated in favor of the Path class? (that would make this rather exercise useless in the long run).
Any pointers would be appreciated here,
Diederik
Vladimir Savic wrote:
Something even more annoying: node doesn't snap to path intersection.
Well, that would be possible, but unfortunately far from easy to implement though.
There's no visualization of snapping (pervert request -- I know it wouldn't be easy to implement) :)
Bulia and I had a discussion about this some time ago. We could have a an icon in the statusbar that lights up when you're snapped and grays out when not. From what I've heard this is the way Xara does it. We could also have a dot blinking for a second, on the canvas, at the position where the snapping occurred... That would really be cool, but maybe this is also a bit too much eye-candy. It certainly wouldn't improve the responsiveness I guess.
And don't know about that how hard would be to implement this one... There was some mentioning of current svn version slowness when dragging shapes over the canvas (with complex drawing) because it wants to snap to everything. Would it be even possible to determine how fast user wants to move something?
That would be a possible work around, but I'd rather fight the cause itself instead of just the symptoms. I think there's still room for improvement in the object-snapper. On top of that, the new lib2geom is expected to improve the snapping responsiveness significantly. Don't know when that is due though...
On Wednesday 22 August 2007 14:33:22 Johan Engelen wrote:
In notepath.cpp from line 4051 onwards, the node type is determined.
As far as I can tell this class is not being used in the object-snapper, so I guess we'll have to do without this.
I think 2geom will replace all path representations in the end, but I don't know.
Well, this is also what I expect, so I'll leave it as it is now. It's more efficient to implement "only snap to non-smooth nodes" when the transition to lib2geom has completed. That might be a while...
Right now, guide-grid intersections do not snap. Another thing is angled snap lines. Angled guides are often requested, and the axonometric grid can also use those snaplines.
It's on my to-do list:
- snapping to objects while dragging guides - improve object-snapper performance (e.g. don't look for snapping candidates and collect all paths/nodes for every single point to snap) - implement constrained-snapping to objects - snapping of grid/guide intersections (for this the snappers should not simply return a snapped point, but sometimes return a snapped line. In the snap-manager we can then combine multiple snapped lines to get an intersection) - angled snap-lines - visual feedback on snapping - only snap to non-smooth nodes (after transition to lib2geom)
Diederik
On 8/22/07, Diederik en Rezi <mail@...1689...> wrote:
In notepath.cpp from line 4051 onwards, the node type is determined.
As far as I can tell this class is not being used in the object-snapper, so I guess we'll have to do without this.
It's very easy just to borrow the math from there. Basically a node is smooth when its handles and itself all lie on one line.
It's on my to-do list:
- snapping to objects while dragging guides
- improve object-snapper performance (e.g. don't look for snapping
candidates and collect all paths/nodes for every single point to snap)
Someone here suggested a great idea: in seltrans, snap only if the current move/scale etc. is "small enough" and skip snapping otherwise. The "small enough" can be defined as a fraction of the current snapping distance. This way fast moves will be more responsive and only small slow movements will snap.
On Wed, 22 Aug 2007 17:28:13 -0300, "bulia byak" <buliabyak@...400...> wrote:
On 8/22/07, Diederik en Rezi <mail@...1689...> wrote:
In notepath.cpp from line 4051 onwards, the node type is determined.
As far as I can tell this class is not being used in the object-snapper, so I guess we'll have to do without this.
It's very easy just to borrow the math from there. Basically a node is smooth when its handles and itself all lie on one line.
(Of course, by "borrow the math", we mean factor it out into a function which can be used in both the original and places, not simply copy and pasting it.)
Someone here suggested a great idea: in seltrans, snap only if the current move/scale etc. is "small enough" and skip snapping otherwise. The "small enough" can be defined as a fraction of the current snapping distance. This way fast moves will be more responsive and only small slow movements will snap.
It's probably better to define it based on speed (distance/time) rather than just on distance -- compared to mice, tablets tend to send more events closer together, partly as a result of having finer spatial resolution. A purely distance-based threshold which works well with mice might not work well with tablets, and vice-versa.
GDK input events come with timestamps attached, so this should be relatively easy to do (aside from the necessary care to sample only event times that occur far enough apart to avoid underflow/overflow).
-mental
MenTaLguY wrote:
(Of course, by "borrow the math", we mean factor it out into a function which can be used in both the original and places, not simply copy and pasting it.)
Of course. I'll have a try...
Someone here suggested a great idea: in seltrans, snap only if the current move/scale etc. is "small enough" and skip snapping otherwise. The "small enough" can be defined as a fraction of the current snapping distance. This way fast moves will be more responsive and only small slow movements will snap.
That will certainly help increasing the responsiveness and I will look into this, but I'll first try to improve the speed of the snapper itself: there's some low-hanging fruit there :-)
Diederik
On 8/22/07, MenTaLguY <mental@...3...> wrote:
GDK input events come with timestamps attached, so this should be relatively easy to do (aside from the necessary care to sample only event times that occur far enough apart to avoid underflow/overflow).
I don't think seltrans needs to fiddle with GDK events. The tool context already took care of them, lumping them together as appropriate based on movement speed and redraw speed. Seltrans just needs to compare the new position with the previous and skip snapping if they are too far apart. (Although it will need access to the desktop zoom factor to find out this distance in screen pixels.)
On Wed, 22 Aug 2007 18:19:56 -0300, "bulia byak" <buliabyak@...400...> wrote:
On 8/22/07, MenTaLguY <mental@...3...> wrote:
GDK input events come with timestamps attached, so this should be relatively easy to do (aside from the necessary care to sample only event times that occur far enough apart to avoid underflow/overflow).
I don't think seltrans needs to fiddle with GDK events. The tool context already took care of them, lumping them together as appropriate based on movement speed and redraw speed.
Ah, okay. If the speed is normalized by the tool context, then that should be fine.
-mental
On Wed, 22 Aug 2007 17:28:13 -0300, "bulia byak" <buliabyak@...400...> wrote:
As far as I can tell this class is not being used in the object-snapper, so I guess we'll have to do without this.
It's very easy just to borrow the math from there. Basically a node is smooth when its handles and itself all lie on one line.
Incidentally, I think your idea of using the smoothness test is a better approach than the earlier idea of using sodipodi:nodetypes, because it doesn't require the user to have set cusp versus smooth nodes correctly (as far as I know, the automatic type assignment is only used when loading a path that isn't already annotated with node types?).
Do you think it would be a good idea to use a slightly looser tolerance when determining smoothness for snapping purposes?
-mental
MenTaLguY wrote:
Do you think it would be a good idea to use a slightly looser tolerance when determining smoothness for snapping purposes?
-mental
Yes. It could be very annoying if we falsely decide not to snap to a node. If we snap to more nodes than needed than that's not a big problem, so we should try to be safe here.
Diederik
Hi,
Way back in time, someone suggested that snapping should only occur at the end of a movement or only at low mouse-speeds, as this would make Inkscape more responsive. I finally got to implementing this and apparently it works nicely, but I think it could use some testing on other systems, for example by users with a tablet. Let me first shortly explain what I implemented:
Inkscape now has a hard-coded speed limit above which no snapping will occur. The speed is calculated after each GDK_MOTION_NOTIFY event (in sp_canvas_motion). When trying to stop my mouse movements as fast as possible I measured speeds up to 1 pixel per millisecond at the last event in line. The speed limit should be above this value, otherwise snapping might not occur when breaking hard. When moving slowly though, almost all motion events will cause snapping when we use such a high speed limit, which wouldn't help in making Inkscape more responsive. I solved this by using both a watchdog timer and a relatively low speed-limit of 0.1 px/msec. The watchdog ensures that Inkscape will always snap at the end of a movement, even when we break abruptly. It will bark when no event comes in below the speed limit, within 100 msec after the last event. In such a case the last event will be repeated with snapping enabled.
There might be some issues though: 1) Is it good practice to resend an event? Or might this have side effects of which I'm not aware? 2) Someone mentioned in another thread that tablets will show jitter or noise. If the noise-level of the measured speed is above our speed limit, then Inkscape will not snap predictably. Could someone with a tablet (or a more expensive mouse) please uncomment line 1615 in sp-canvas.cpp and report to me what speed is measured? 3) When moving at speeds around the speed limit, Inkscape might snap for one motion event but not for the next, which will make the object that's being dragged jump from the snapped position to the mouse position and back again. That could be annoying, but I don't see an easy way around this.
Any comment is appreciated!
Diederik
On Sat, Oct 25, 2008 at 10:22 AM, Diederik van Lierop <mail@...1689...> wrote:
Way back in time, someone suggested that snapping should only occur at the end of a movement or only at low mouse-speeds, as this would make Inkscape more responsive. I finally got to implementing this and apparently it works nicely, but I think it could use some testing on other systems, for example by users with a tablet.
I'm not a heavy snapping user, but I have a tablet and from some superficial testing, I think snapping works as before, while being somewhat more responsive and fluid. Thanks for the great improvement!
Hi Diederik,
Seems to work great!! Very nice work.
A long standing wish of me...: The snapping points should depend a bit on where the user clicks. If I want some point to snap to some gridpoint, I tend to click close to that point and drag it close to where I want it to snap. Does that make sense? I do not have a clear idea how to go about this; perhaps some "rating" of possible snaps with better rating for snaps occuring short distances away from the mouse cursor...
Cheers, Johan
-----Original Message----- From: Diederik van Lierop [mailto:mail@...1689...] Sent: zaterdag 25 oktober 2008 15:22 To: inkscape-devel Subject: [Inkscape-devel] Snapping should only occur at the end of a movement
Hi,
Way back in time, someone suggested that snapping should only occur at the end of a movement or only at low mouse-speeds, as this would make Inkscape more responsive. I finally got to implementing this and apparently it works nicely, but I think it could use some testing on other systems, for example by users with a tablet. Let me first shortly explain what I implemented:
Inkscape now has a hard-coded speed limit above which no snapping will occur. The speed is calculated after each GDK_MOTION_NOTIFY event (in sp_canvas_motion). When trying to stop my mouse movements as fast as possible I measured speeds up to 1 pixel per millisecond at the last event in line. The speed limit should be above this value, otherwise snapping might not occur when breaking hard. When moving slowly though, almost all motion events will cause snapping when we use such a high speed limit, which wouldn't help in making Inkscape more responsive. I solved this by using both a watchdog timer and a relatively low speed-limit of 0.1 px/msec. The watchdog ensures that Inkscape will always snap at the end of a movement, even when we break abruptly. It will bark when no event comes in below the speed limit, within 100 msec after the last event. In such a case the last event will be repeated with snapping enabled.
There might be some issues though:
- Is it good practice to resend an event? Or might this have
side effects of which I'm not aware? 2) Someone mentioned in another thread that tablets will show jitter or noise. If the noise-level of the measured speed is above our speed limit, then Inkscape will not snap predictably. Could someone with a tablet (or a more expensive mouse) please uncomment line 1615 in sp-canvas.cpp and report to me what speed is measured? 3) When moving at speeds around the speed limit, Inkscape might snap for one motion event but not for the next, which will make the object that's being dragged jump from the snapped position to the mouse position and back again. That could be annoying, but I don't see an easy way around this.
Any comment is appreciated!
Diederik
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Inkscape-devel mailing list Inkscape-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/inkscape-devel
Dear Johan,
I'm not sure if this is quite what you were thinking of but I wondered if either of these suggestions might help:
1. In Corel Draw each type of snap is either on or off for the whole document (like inkscape), but it is possible to override this by holding down a keypress as the point is selected. So 'N' removes all snapping except Node snapping (E for endpoing, I for intersection etc.) and the cursor jumps to the _nearest_ node snap with a much larger snap radius. If the N is released it goes back to normal with all active snaps working and a smaller snap radius. This allows a rapid way to force the snap for a single point only.
2. Alternatively, how about using a key like 'TAB' to cycle between all the possible snaps within some radius of the cursor. The shape of the snap indicator, together with the tooltip text below could show which is being applied as the cursor jumps to the snap.
Hope this may have helped!
Kindest Regards, Alex
On Sun, 26 Oct 2008, J.B.C.Engelen@...1578... wrote:
Hi Diederik,
Seems to work great!! Very nice work.
A long standing wish of me...: The snapping points should depend a bit on where the user clicks. If I want some point to snap to some gridpoint, I tend to click close to that point and drag it close to where I want it to snap. Does that make sense? I do not have a clear idea how to go about this; perhaps some "rating" of possible snaps with better rating for snaps occuring short distances away from the mouse cursor...
Cheers, Johan
On 10/26/2008 12:53 PM, A.J. Carter wrote:
- In Corel Draw each type of snap is either on or off for the whole
document (like inkscape), but it is possible to override this by holding down a keypress as the point is selected. So 'N' removes all snapping except Node snapping (E for endpoing, I for intersection etc.) and the cursor jumps to the _nearest_ node snap with a much larger snap radius. If the N is released it goes back to normal with all active snaps working and a smaller snap radius. This allows a rapid way to force the snap for a single point only.
That's indeed an elegant way to create some more flexibility. If however this is only to select what we snap _to_, then we could still use something that gives us more control of what we snap _from_. For the latter we could still use Johan's proposal.
- Alternatively, how about using a key like 'TAB' to cycle between
all the possible snaps within some radius of the cursor. The shape of the snap indicator, together with the tooltip text below could show which is being applied as the cursor jumps to the snap.
Elegant too, but would require more coding effort and might not be very deterministic. What happens if we have a set of snapping candidates and use tab to cycle through them, but move the mouse a bit in the meantime? Then the set of snapping candidates might change, which should be handled gracefully. It would also require storing the snapping candidates across multiple motion events, as currently all snapping is handled within only a single event.
This brings me to some other point though: Hasn't any one ever thought of using the tab key to cycle through the items which are to be selected? Now we can use left-click and alt-left-click to select an item on the canvas, but this is still tricky when there are many overlapping items. Modern 3D CAD programs show a list of all available items near the mouse pointer when left-clicking, through which the user can cycle with the tab key, including highlighting on canvas! Now wouldn't that be cool too?
Diederik
Hope this may have helped!
Kindest Regards, Alex
On Sun, 26 Oct 2008, J.B.C.Engelen@...1578... wrote:
Hi Diederik,
Seems to work great!! Very nice work.
A long standing wish of me...: The snapping points should depend a bit on where the user clicks. If I want some point to snap to some gridpoint, I tend to click close to that point and drag it close to where I want it to snap. Does that make sense? I do not have a clear idea how to go about this; perhaps some "rating" of possible snaps with better rating for snaps occuring short distances away from the mouse cursor...
Cheers, Johan
Dear Diederik,
Many thanks for your comments. Regarding the TAB to cycle between snaps: as you say I can see that this may cause problems with predictability. How about holding down CTRL and then using TAB to cycle. As soon as CTRL is pressed the current cursor position would be 'locked' and it would cycle each time tab is pressed irregardless of how the mouse moves until CTRL is next released. This still only requires a single hand and so would still be reasonably elegant.
In addition to holding down keys like N, E (as mentioned before) to provide a temporary over-ride to the global snap, I think an indicator of which snaps are globally active in the status bar may be useful.
That's indeed an elegant way to create some more flexibility. If however this is only to select what we snap _to_, then we could still use something that gives us more control of what we snap _from_. For the latter we could still use Johan's proposal.
In terms of selecting 'from' using snaps, the resizing handles of inkscape are already slightly outside the boundary of the object, so could regular snapping not be used to pick the item 'from' already somehow?
I've prepared a PDF mock up (using corel screenshots) of how this may work. I'm not sure how whether the mailing list handles attachments, so I will e-mail it directly to you. I wondered if it might be possible to place it online as a suggestion?
Re: using tab to cycle through selections as you suggested - I agree that this would be very useful!
Kindest Regards, Alex
This brings me to some other point though: Hasn't any one ever thought of using the tab key to cycle through the items which are to be selected? Now we can use left-click and alt-left-click to select an item on the canvas, but this is still tricky when there are many overlapping items. Modern 3D CAD programs show a list of all available items near the mouse pointer when left-clicking, through which the user can cycle with the tab key, including highlighting on canvas! Now wouldn't that be cool too?
Diederik
On 10/26/2008 03:56 PM, A.J. Carter wrote:
How about holding down CTRL and then using TAB to cycle. As soon as CTRL is pressed the current cursor position would be 'locked' and it would cycle each time tab is pressed irregardless of how the mouse moves until CTRL is next released. This still only requires a single hand and so would still be reasonably elegant.
That looks quite awkward to me; I think most problems could be overcome by giving preference to nodes near the cursor combined with easily accessible toggles (being either icons, keys, or both).
In addition to holding down keys like N, E (as mentioned before) to provide a temporary over-ride to the global snap, I think an indicator of which snaps are globally active in the status bar may be useful.
That indicator should also be a toggle IMO. Maybe I will have a stab at this (and at cleaning up the snapping dialogs, long due too) within a few months, because it looks like most snapping bugs have been solved and the snapping code is settling down.
I've prepared a PDF mock up (using corel screenshots) of how this may work. I'm not sure how whether the mailing list handles attachments, so I will e-mail it directly to you. I wondered if it might be possible to place it online as a suggestion?
You could create a "blueprint" in Launchpad (see https://blueprints.launchpad.net/inkscape). I think that your proposal gives indeed excellent control for translations, but what about scaling and stretching? You're not using the handles for this, so how is Inkscape to know which transformation to use? BTW, perpendicular and tangent snapping will be difficult with our current mechanisms, but the other modes are either already there or easily implemented.
Diederik
gives indeed excellent control for translations, but what about scaling and stretching? You're not using the handles for this, so how is Inkscape to know which transformation to use? BTW, perpendicular and tangent snapping will be difficult with our current mechanisms, but the other modes are either already there or easily implemented.
I'm not sure I understand the distinction; if the cursor is above the snap point it will translate the object. If it is above a handle (which is why these have to be outside the perimeter of the object) it will either scale or stretch.
I can only speak for the this approach which corel uses, but it seems to work very well. A second click on the object switches to rotation mode, and the centre of rotation is represented by a circle which can be moved again using existing snapping points
The only thing which you can't do is to mirror an object using an arbitrary line - only x or y flips are possible. In CAD software the mirror line usually has to be drawn after the mirror tool is selected I think.
Kindest Regards, Alex
On 10/26/2008 09:57 PM, A.J. Carter wrote:
gives indeed excellent control for translations, but what about scaling and stretching? You're not using the handles for this, so how is Inkscape to know which transformation to use? BTW, perpendicular and tangent snapping will be difficult with our current mechanisms, but the other modes are either already there or easily implemented.
I'm not sure I understand the distinction; if the cursor is above the snap point it will translate the object. If it is above a handle (which is why these have to be outside the perimeter of the object) it will either scale or stretch.
This way you will have full control of which node snaps, but only for translations. Snapping in other transformations (scaling, stretching) will still behave unpredictably, meaning that it's hard to tell beforehand which node will snap. I would prefer to have a solution for any transformation, although translations are most used of course.
Diederik
As Krzysztof was describing, in Corel only the point directly below the cursor is active for snapping, and this applies equally to all transformations (including scaling and stretching). In other words only the node or handle you are moving is considered for snapping to other objects; no other points on that object do. If you want a different handle to snap you simply stretch it from that handle.
Kindest Regards, Alex
On Sun, 26 Oct 2008, Diederik van Lierop wrote:
On 10/26/2008 09:57 PM, A.J. Carter wrote:
gives indeed excellent control for translations, but what about scaling and stretching? You're not using the handles for this, so how is Inkscape to know which transformation to use? BTW, perpendicular and tangent snapping will be difficult with our current mechanisms, but the other modes are either already there or easily implemented.
I'm not sure I understand the distinction; if the cursor is above the snap point it will translate the object. If it is above a handle (which is why these have to be outside the perimeter of the object) it will either scale or stretch.
This way you will have full control of which node snaps, but only for translations. Snapping in other transformations (scaling, stretching) will still behave unpredictably, meaning that it's hard to tell beforehand which node will snap. I would prefer to have a solution for any transformation, although translations are most used of course.
Diederik
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Inkscape-devel mailing list Inkscape-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/inkscape-devel
On 10/26/2008 10:31 PM, A.J. Carter wrote:
As Krzysztof was describing, in Corel only the point directly below the cursor is active for snapping, and this applies equally to all transformations (including scaling and stretching). In other words only the node or handle you are moving is considered for snapping to other objects; no other points on that object do. If you want a different handle to snap you simply stretch it from that handle.
Wait a minute. Maybe I'm misunderstanding you here, but what about a rectangle that has been rotated let's say 15 degrees. Is it possible at all to snap its rotated corners in Coreldraw to a grid for example? These corners are not at a handle. So basically it's just boundingbox snapping that Coreldraw does then, plus some special points like intersections and quadrant points and such.
PS: Won't reply tonight, bedtime!
Dear Diederik,
In the case you mentioned of rotating a rectangle: you can rotate the shape by 15 degrees, and then as a seperate action translate it _from_ the new corner to a given gridpoint. You can't rotate the shape such that the rotated corner snaps to a gridpoint in a single motion though no. Only the point directly below the cursor snaps as it moves, irregardless of the type of transform.
All snapping points rotate with the object and are still accessible in the new oreintation no matter what transformation you perform on it, so I would say it's not really just boundary box snapping only no.
The bounding box is actually a subtlety in Corel Designer since it doesn't have to be the smallest rectangle which contains each object as in most programs. You can actually tell it to use different shapes for the 'object coordinates' - e.g. the bounding shape can actually be set to be the smallest ellipse (or polygon, square etc.) which contains a given object or group, and you then position this ellipse relative to the page, and set the width or height of the ellipse to resize the object. It's not something I've used myself but corel have a free designer X4 trial if you wanted a play!
I was thinking last night - if you wanted a fully general way to use snapping with _any_ transformation I guess it depends on what you are doing. Rotations require a 'centre', scalings require a 'point' (not necessarily on the bounding box of the shape !) and stretches require a 'line' (most non CAD systems assume this to be the opposite side of the selection, but it can be any distance away as long as you drag perpendicular to it). One way to do this would be to have a point or line associated with each shape (which can be moved using regular snapping like any other shape) to define the origin of the transformation. The problem is then that a different tool would need to be selected for each type of transform (in corel it automatically switches to rotation mode if an object is clicked twice, then a circle appears in the centre defining the point of rotation and this can be dragged as with any other point, before using the handle to do the actual rotating).
Hope this has made sense !!
Kindest Regards, Alex
Wait a minute. Maybe I'm misunderstanding you here, but what about a rectangle that has been rotated let's say 15 degrees. Is it possible at all to snap its rotated corners in Coreldraw to a grid for example? These corners are not at a handle. So basically it's just boundingbox snapping that Coreldraw does then, plus some special points like intersections and quadrant points and such.
Hello Alex,
Just downloaded a trial version of Coreldraw X4 and tried the snapping. Finally things are dawning on me.
When using the handles to transform (scaling/stretching/skewing/rotating), only the handles themselves snap. This is pretty limited because in many cases the handle is at a position that has little to do with the position of the nodes. I think the nodes should snap instead of the handles, as Inkscape does. A downside of this is that it's not always obvious which node is snapping, but this should be improved by preferring nodes closes to the mouse pointer over other nodes.
Consequently, nodes (and midpoints, intersections, centers, etc.) only snap when translating. Why's that? The only reasons I can think of is that they wanted to keep things simple.
Finally, the tangent and perpendicular snapping are only available when drawing lines, not when transforming. So they basically only have point to point/path snapping (just as Inkscape), and don't offer real line-to-line snapping either. Overall they provide a clean user experience, but it looks a bit restrictive in what can be done and the level of configurability is low. Let's try to do better!
Regards,
Diederik
-----Original Message----- From: A.J. Carter [mailto:ajc200@...1930...] Sent: 2008 okt 27 14:35 To: Diederik van Lierop Cc: inkscape-devel@lists.sourceforge.net Subject: Re: [Inkscape-devel] Snapping should only occur at the end of a movement
Dear Diederik,
In the case you mentioned of rotating a rectangle: you can rotate the shape by 15 degrees, and then as a seperate action translate it _from_ the new corner to a given gridpoint. You can't rotate the shape such that the rotated corner snaps to a gridpoint in a single motion though no. Only the point directly below the cursor snaps as it moves, irregardless of the type of transform.
All snapping points rotate with the object and are still accessible in the new oreintation no matter what transformation you perform on it, so I would say it's not really just boundary box snapping only no.
The bounding box is actually a subtlety in Corel Designer since it doesn't have to be the smallest rectangle which contains each object as in most programs. You can actually tell it to use different shapes for the 'object coordinates' - e.g. the bounding shape can actually be set to be the smallest ellipse (or polygon, square etc.) which contains a given object or group, and you then position this ellipse relative to the page, and set the width or height of the ellipse to resize the object. It's not something I've used myself but corel have a free designer X4 trial if you wanted a play!
I was thinking last night - if you wanted a fully general way to use snapping with _any_ transformation I guess it depends on what you are doing. Rotations require a 'centre', scalings require a 'point' (not necessarily on the bounding box of the shape !) and stretches require a 'line' (most non CAD systems assume this to be the opposite side of the selection, but it can be any distance away as long as you drag perpendicular to it). One way to do this would be to have a point or line associated with each shape (which can be moved using regular snapping like any other shape) to define the origin of the transformation. The problem is then that a different tool would need to be selected for each type of transform (in corel it automatically switches to rotation mode if an object is clicked twice, then a circle appears in the centre defining the point of rotation and this can be dragged as with any other point, before using the handle to do the actual rotating).
Hope this has made sense !!
Kindest Regards, Alex
Wait a minute. Maybe I'm misunderstanding you here, but what about a rectangle that has been rotated let's say 15 degrees. Is it possible at all to snap its rotated corners in Coreldraw to a grid for example? These corners are not at a handle. So basically it's just boundingbox snapping that Coreldraw does then, plus some special points like intersections and quadrant points and such.
Hi Diederik,
Thanks for your message on thursday and apologies for not replying sooner; I've just been away on holiday.
Having thought about it I agree that the corel way does have its limitations, but at the same time I think it does encompass 99% of common translations by simply snapping at the handle, and I think it may be less than obvious what is happening otherwise as you say. Rather than 'preferring nodes' close to the mouse pointer though, I wonder about having the handles snap in the corel way but then introduce a new set of 'geometric transform' buttons in the upcoming 'Geometric constructions toolbar'.
These could work in a CAD like way. For example, once the 'Geomtric stretch' tool was selected inkscape would prompt for two consecutive inputs. First the user draws the line about which the stretch is to occur (this need not be within the shape in general), and second the point the shape is to be stretched from (which would use 'normal' node snapping). This would allow the transform to occur from any point, but also allow the flexibility to define different lines/points/grids about which the transform is to occur, and may work better with unusual (e.g. isometric) grids for stretching.
http://mathworld.wolfram.com/Stretch.html
The first input draws the invariant line, and the second provides the scale factor (which could of course be typed as a number alternatively) if it were a seperate tool.
Similarly the geometric rotation tool would first prompt for the 'centre of rotation' and then the point to 'pick up' from using standard node snapping (or a typed angle).
Incidently, what do you think about the snapping indicators they (corel) use?
Best Wishes, Alex
On Thu, 6 Nov 2008, Diederik van Lierop wrote:
Hello Alex,
Just downloaded a trial version of Coreldraw X4 and tried the snapping. Finally things are dawning on me.
When using the handles to transform (scaling/stretching/skewing/rotating), only the handles themselves snap. This is pretty limited because in many cases the handle is at a position that has little to do with the position of the nodes. I think the nodes should snap instead of the handles, as Inkscape does. A downside of this is that it's not always obvious which node is snapping, but this should be improved by preferring nodes closes to the mouse pointer over other nodes.
Consequently, nodes (and midpoints, intersections, centers, etc.) only snap when translating. Why's that? The only reasons I can think of is that they wanted to keep things simple.
Finally, the tangent and perpendicular snapping are only available when drawing lines, not when transforming. So they basically only have point to point/path snapping (just as Inkscape), and don't offer real line-to-line snapping either. Overall they provide a clean user experience, but it looks a bit restrictive in what can be done and the level of configurability is low. Let's try to do better!
Regards,
Diederik
On Sun, Oct 26, 2008 at 10:21 AM, Diederik van Lierop <mail@...1689...> wrote:
This brings me to some other point though: Hasn't any one ever thought of using the tab key to cycle through the items which are to be selected? Now we can use left-click and alt-left-click to select an item on the canvas, but this is still tricky when there are many overlapping items. Modern 3D CAD programs show a list of all available items near the mouse pointer when left-clicking, through which the user can cycle with the tab key, including highlighting on canvas! Now wouldn't that be cool too?
I don't really think "cool" will be the applicable to a situation where you click and then have to select something from a list, instead of immediate action :)
But if anyone wants to implement that, let's discuss the details. Of course it should be optional, for most people and drawings click and alt-click works just fine.
I'm in favor of emulating the Corel Draw approach to snapping. It's one of the features I liked there (the ones I didn't like included the fact that it's hard to create an alpha gradient). Xara approach (snap indicator in the statusbar) is just completely bogus, please don't do this.
Diederik van Lierop wrote:
That's indeed an elegant way to create some more flexibility. If however this is only to select what we snap _to_, then we could still use something that gives us more control of what we snap _from_. For the latter we could still use Johan's proposal.
In Corel Draw this is handled by allowing one to drag a node or the center of an object in the selector tool. The thing you're dragging is automatically considered to be the only thing you want to snap, even though the entire object moves. Same with rotation, you can rotate by dragging a node. In addition to being easier to use, this approach reduces the mathematical complexity of snapping, because you have 1xN distances to compute instead of MxN distances. I think this is a very intelligent solution.
With regards to visual snapping indication, Corel Draw does it right too: a small static crosshair is being displayed, and additionally a small textual description of what is being snapped to appears (e.g. "node", "center", "quarter" (of a circle), "line", "baseline" (of a text), "intersection" etc.
Regards, Krzysztof Kosiński
Hay! It was me. I thought you've forgotten that one. Aside from technical details, which are not common to me, this improvement will be noticeable even more as our renderer start to gain some more speed.
Building now... Built.
Some thoughts: 1) If "Always snap" is on, turn off detection of motion speed. 2) Wait a few milliseconds when snapping occurs to avoid re-snapping glitches 3) Works fine with wacom graphire3 tablet :)
Vlada
Diederik van Lierop wrote:
Hi,
Way back in time, someone suggested that snapping should only occur at the end of a movement or only at low mouse-speeds, as this would make Inkscape more responsive. I finally got to implementing this and apparently it works nicely, but I think it could use some testing on other systems, for example by users with a tablet. Let me first shortly explain what I implemented:
Inkscape now has a hard-coded speed limit above which no snapping will occur. The speed is calculated after each GDK_MOTION_NOTIFY event (in sp_canvas_motion). When trying to stop my mouse movements as fast as possible I measured speeds up to 1 pixel per millisecond at the last event in line. The speed limit should be above this value, otherwise snapping might not occur when breaking hard. When moving slowly though, almost all motion events will cause snapping when we use such a high speed limit, which wouldn't help in making Inkscape more responsive. I solved this by using both a watchdog timer and a relatively low speed-limit of 0.1 px/msec. The watchdog ensures that Inkscape will always snap at the end of a movement, even when we break abruptly. It will bark when no event comes in below the speed limit, within 100 msec after the last event. In such a case the last event will be repeated with snapping enabled.
There might be some issues though:
- Is it good practice to resend an event? Or might this have side
effects of which I'm not aware? 2) Someone mentioned in another thread that tablets will show jitter or noise. If the noise-level of the measured speed is above our speed limit, then Inkscape will not snap predictably. Could someone with a tablet (or a more expensive mouse) please uncomment line 1615 in sp-canvas.cpp and report to me what speed is measured? 3) When moving at speeds around the speed limit, Inkscape might snap for one motion event but not for the next, which will make the object that's being dragged jump from the snapped position to the mouse position and back again. That could be annoying, but I don't see an easy way around this.
Any comment is appreciated!
Diederik
On Wednesday 22 August 2007 21:49:36 Diederik en Rezi wrote:
Vladimir Savic wrote:
Something even more annoying: node doesn't snap to path intersection.
Well, that would be possible, but unfortunately far from easy to implement though.
Unfortunately.. :(
There's no visualization of snapping (pervert request -- I know it wouldn't be easy to implement) :)
Bulia and I had a discussion about this some time ago. We could have a an icon in the statusbar that lights up when you're snapped and grays out when not. From what I've heard this is the way Xara does it. We could also have a dot blinking for a second, on the canvas, at the position where the snapping occurred... That would really be cool, but maybe this is also a bit too much eye-candy. It certainly wouldn't improve the responsiveness I guess.
I'm completely against icon blinking thing. Reason is really simple, I think?! Snapping job is precise operation and occupies someones attention for a short amount of time. Think that there would be too much eye movements all over the screen.
And don't know about that how hard would be to implement this one... There was some mentioning of current svn version slowness when dragging shapes over the canvas (with complex drawing) because it wants to snap to everything. Would it be even possible to determine how fast user wants to move something?
That would be a possible work around, but I'd rather fight the cause itself instead of just the symptoms. I think there's still room for improvement in the object-snapper. On top of that, the new lib2geom is expected to improve the snapping responsiveness significantly. Don't know when that is due though...
You're right till some point. It's symptom! But I don't really see the point of insane speed dragging trying to snap to someting. This wont exclude necessary object-snapper improvements at other places, but will speed up things even when lib2geom comes on stage. No?
Vlada
Diederik
Vladimir Savic wrote:
I'm completely against icon blinking thing. Reason is really simple, I think?! Snapping job is precise operation and occupies someones attention for a short amount of time. Think that there would be too much eye movements all over the screen.
Good point. The problem I was trying to solve here was that it is not always clear which point is snapping, even if you're paying attention. That could be solved by an visual clue at the specific point, but that it indeed has it downsides also.
You're right till some point. It's symptom! But I don't really see the point of insane speed dragging trying to snap to someting. This wont exclude necessary object-snapper improvements at other places, but will speed up things even when lib2geom comes on stage. No?
You're absolutely right. That's why I've put both on my To-do list. Improving the bare performance _and_ adding some intelligence.
Diederik
Diederik van Lierop wrote:
Vladimir Savic wrote:
There's no visualization of snapping (pervert request -- I know it wouldn't be easy to implement) :)
Bulia and I had a discussion about this some time ago. We could have a an icon in the statusbar that lights up when you're snapped and grays out when not. From what I've heard this is the way Xara does it. We could also have a dot blinking for a second, on the canvas, at the position where the snapping occurred...
I think having some kind of on-canvas indicator of snap status would greatly improve the usability of snapping in Inkscape. I've found the Xara approach of having an icon in the toolbar very difficult to use. You need to keep one eye on the pointer while trying to align it with the snap target and one eye on the snap indicator in the status bar. This works ok if you have a small display but becomes more and more difficult with larger displays, and forget about it if you are using multiple monitors.
I tend to think AutoCAD does snapping pretty well. It places a small static indicator at the point that will be snapped to, given the current mouse location and snap settings. In Inkscape I could imagine highlighting the target node or bounding box. A video of snapping in AutoCAD can be seen here: http://www.youtube.com/watch?v=PNGsZ3aZuck. You can skip to ~6:20 when they start using running snaps which would probably be most appropriate for a tool like Inkscape.
Cheers,
Jed
2007. 08. 23, csütörtök keltezéssel 14.06-kor Jed Frechette ezt írta:
I tend to think AutoCAD does snapping pretty well. It places a small static indicator at the point that will be snapped to, given the current mouse location and snap settings. In Inkscape I could imagine highlighting the target node or bounding box. A video of snapping in AutoCAD can be seen here: http://www.youtube.com/watch?v=PNGsZ3aZuck. You can skip to ~6:20 when they start using running snaps which would probably be most appropriate for a tool like Inkscape.
It is just amazing. The on-canvas indicator would be really awesome.
Khiraly
On Friday 24 August 2007 1:33 pm, Diederik van Lierop wrote:
The object snapper in ACAD is a bit different: if only snaps after clicking the left mousebutton; this way ACAD can show what point will be snapped to before doing the actual snapping. Inkscape however snaps instantly while dragging: it cannot show what it will snap to, because it already has snapped by that time. The only thing we could do is show afterwards where it has snapped, which is only useful in cases where this is not immediately obvious. For example in selections with a large number of nodes, nodes being very close to each other, or at low snapping sensitivity.
Good point, but I still think an on canvas "post"-snap indicator could be useful. I seem to run in to the non-obvious corner cases pretty regularly. Is my node snapping to the path or a node on the path? Is the upper left corner of the bounding box snapping to something on the edge of my drawing or is the invisible center of rotation snapping to something else? etc. Sometimes I have no clue what is being snapped to. I suspect bugs in in these cases but I haven't been sure how to debug them, if anyone has any hints I would be glad to followup.
In practice, whenever I'm using snap heavily I simply keep the snap dialog open and constantly adjust the settings to get what I want. I suspect I would still need to do this even with a snap indicator but hopefully to a lesser extent. Of course, I don't know how typical my usage is and unfortunately I don't have any time to look at the code myself so take my opinions for what they are worth.
Best,
Jed Frechette wrote:
Good point, but I still think an on canvas "post"-snap indicator could be useful. I seem to run in to the non-obvious corner cases pretty regularly. Is my node snapping to the path or a node on the path? Is the upper left corner of the bounding box snapping to something on the edge of my drawing or is the invisible center of rotation snapping to something else? etc. Sometimes I have no clue what is being snapped to.
Good to hear it's not just me :-). Maybe I should just try to build a post-snap indicator and see if it helps. Off by default of course, because of possible distraction and performance hit.
I suspect bugs in in these cases but I haven't been sure how to debug them, if anyone has any hints I would be glad to followup.
Most of the snapping bugs should have been solved by now in SVN, but if you find another one then please let me know!
Diederik
On Sunday 26 August 2007 1:33 am, Diederik van Lierop wrote:
Maybe I should just try to build a post-snap indicator and see if it helps. Off by default of course, because of possible distraction and performance hit.
That would be awesome. I wonder if it would be worthwhile to only show the indicator in outline mode? In addition to better performance it might make it easier to design unambiguous indicators that aren't distracting. Besides the folks obsessing about accurate placement are probably more likely to be using outline mode anyway.
Best,
participants (11)
-
unknown@example.com
-
A.J. Carter
-
bulia byak
-
Diederik en Rezi
-
Diederik van Lierop
-
Jed Frechette
-
Johan Engelen
-
Khiraly
-
Krzysztof Kosiński
-
MenTaLguY
-
Vladimir Savic