简体   繁体   中英

snap/raphael/svg - Get the angle at a point (not length)?

I'm working on reimplementing a PHP/GD app in client-side SVG. My initial plan is to use Snap or Raphael for that. One of the features of the original app is drawing "fat" curved arrows, for which I need the outline. This is how the original looked:

原始的PHP和GD弯曲箭头

Originally in PHP, I wrote my own catmull-rom function and calculated a central 'spine' curve between the ends and control points, then figured out a normal vector at each spine point to get the points either side of that at the distance I wanted for my fat line. That worked OK, but it's fairly labour-intensive, and it does strange things on tight turns.

Initially, I rewrote my php curve calculation in javascript, and generated large lists of straight line-segments. That works, but it doesn't remain smooth as you zoom (obviously enough).

逐点计算的catmull-rom样条

So for the next javascript version, I started with an SVG path using the R segment type to get my catmull-rom central curve, and I can get the angle (and therefore normal) at any point based on the distance along the curve. But I wanted to try and be more efficient and let SVG calculate the outline curves, by producing only the control points for two new CR splines passing through control points offset by the normal from the original control points (green in image).

SVG样条线构造带有一些法线点。绿点是控制点

But - how can I get the angle of the curve (or the tangent vector) at a point on the curve (not a length along it)? I know the coordinates (it's the CR control point), just not the angle. There doesn't appear to be a method on SVGPathElement to actually retrieve points arbitrarily, (or say, find the nearest point on the path to a point).

Alternatively, how else can I get the same outline? I'm new to SVG, so if there's a way to just let it draw a line with a strokeWidth of 20 (or whatever the width is) and get the outline of that in a modifiable form (I need to add the outline of the arrowhead, and also in some cases run text along the outside edge of the arrow), then that would also work!

Update: The arrowhead shape is proportional to the width of the line, and the proportions can be adjusted (somewhat) by the user. The width is also specified by the user. I think this makes using markers a problem, but happy to be proved wrong. Some of these arrows will have no fill (ie transparent), just outline.

Extra thought: is there some property of parametric Catmull-Rom splines, such that the control point is always at t=0.5 (for example), so that I can figure out the length to the control point and use the Snap methods to get the angle? [answer - yes, it's t=1.0, but that doesn't help with the length]

Yes, in Snap.svg you can get the angle at a given point by running:

var pt = path.getPointAtLength(x,y);
console.log("Angle at "+[x,y]+":" + pt.alpha);

the return value has a property called "alpha", that is the angle at the given point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM