From: Nathan H. <nj...@nj...> - 2011-08-30 22:21:10
|
On Tue, Aug 30, 2011 at 09:00:46PM +0200, Diederik van Lierop wrote: > Hi all, > > Due to popular demand, I'm thinking of implementing tangential and > perpendicular snapping in Inkscape. Well, at least for the case where > the user draws a straight line or manipulates a guide. So I have a curve > I want to snap to, and some distant point P0. Now I need to find all > points P1, for which the line P0-P1 is either tangential or > perpendicular to the curve. > > I guess I could first convert the path to sbasis, and then call > find_tangents() (see the code snippet below, from sbasis-geometric.cpp). > But a few questions come to mind: > - Can't this be done without having to convert each path to sbasis > first? Converting will take CPU time No more than a matrix multiply. You need to convert it into a form with a suitable algebra. It could be done with bernstein basis (bezier curves) but we currently lack code to do that. > - Am I really the first one to need this functionality? find_tangets() > is not being used anywhere as far as I can tell. Are there other ways to > solve this? lib2geom is full of solutions looking for problems :) > - How do I implement perpendicular snapping? There's no method yet > called find_normals() Ok, there are a bunch of operations that are interesting: * given a direction D, find all points on the curve A that point in that direction: roots(dot(derivative(A), rot90(D))) * given a point P, find all points on the curve A whose tangent passes through P: find_tangents(P, A) * given a point P, find all points on the curve A whose normal passes through P, same as find tangents, but use the dot product: SBasis crs (dot(A - P, derivative(A))); crs = shift(crs*Linear(-1, 0)*Linear(-1, 0), -2); // We know that there is a double root at t=0 so we divide out t^2 // JFB points out that this is equivalent to (t-1)^2 followed by a divide by s^2 (shift) return roots(crs); * given a pair of curves, find the lines which are normal to both curves: collinear_normals * same, but for tangents (fillets): There is no code for this currently, but I'm sure it can be built from collinear_normals. * snap arcs to matching curvature: filet-minion (I particularly like the name of this one :) There are more snappy things, but I can't think of them right now. I'm going away for a few days (no internet!!!), but don't hestitate to ask for more help. njh |