Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

smooth svg path connection

I have a random set of points and want to create a smooth svg shape with raphaeljs. To connect the points I am using a catmull-rom-spline. The problem is that the point where the path is closed is not smooth.

This is an example path out of my projcet:

M125,275R 125,325 175,325 225,325 275,325 225,275 175,275 125,275Z

I've also created a jsfiddle: http://jsfiddle.net/ry8kT/

Can this be achieved with catmull curves? If not, can you please give me an example how to get a completely smoothed shape?

Much thanks in advance, McFarlane

like image 299
McFarlane Avatar asked Feb 02 '12 22:02

McFarlane


People also ask

What is Moveto SVG?

The "moveto" commands. The "moveto" commands (M or m) must establish a new initial point and a new current point. The effect is as if the "pen" were lifted and moved to a new location. A path data segment (if there is one) must begin with a "moveto" command.

Is it possible to draw any path in SVG?

It can draw anything! I've heard that under the hood all the other drawing elements ultimately use path anyway. The path element takes a single attribute to describe what it draws: the d attribute.

How do I center an SVG path?

You can change the svg viewBox attribute to center the path. This is especially useful if you have several paths in the svg, so you do not have to add a transform to each one. In your example that would be viewBox="0 15.674 144 144" , getting the y-offset the same way as in Pauls answer.


2 Answers

In your first example, the path started at 125,275 and was at 125,275 again, before closing. Because 'Z' creates another smooth path segment connecting start and end point, you get that small loop. If you close it before returning to the startingpoint, you get the desired smooth shape touching all given points.

This is the corrected version of the example path:

M125,275R 125,325 175,325 225,325 275,325 225,275 175,275Z
like image 108
Cody Avatar answered Oct 22 '22 14:10

Cody


I fixed it myself:

Instead of using the catmull rom spline I am using quadratic curves and calculated midpoints. Note, that this solution will only work if you want to draw a smoothed shape but not if the path has to go directly through the points.

This is how it works:

first: set the line start to the first point followed immediately by a moveTo command

M point1.x,point1.y M 

this is important for closing the path without an edge.

now loop throug every point you have and add the calculated midpoint bewtween the current and next point followed by the quadratic curve with the next point as control:

mid.x,mid.y C next.x,next.y

you calculate the midpoint M between A and B using this:

M.x = (A.x-B.x)/2 + B.x
M.y = (A.y-B.y)/2 + B.y

after looping through all points you have to create a quadratic curve to the midpoint of the first and second point with the first one as control:

C first.x,first.y mid.x, mid.y

now close your path using Z so you can fill the shape:

Z

this connection is not visible because of the two moveTo commands at the beginning of the path.

to see the result and source code of my solution visit the updated jsfiddle: http://jsfiddle.net/ry8kT/1/

like image 30
McFarlane Avatar answered Oct 22 '22 14:10

McFarlane