Converting a list of points to an SVG cubic piecewise Bezier curve

2024/11/17 14:20:01

I have a list of points and want to connect them as smoothly as possible. I have a function that I evaluate to get these points. I could simply use more sampling points but that would only increase the SVG file size. I think using a piecewise cubic Bezier curve would be better suited. How do I do this?

I did some research and came across the svgpathtools package, which looked promising. However, I did not find any functionality like this.

Answer

If you ever used Illustrator you certainly remember that the first control points of a bezier is connected with the last control point of the previous one. This line is tangent to the curve. In my code I am using the size of this line to draw the curve.

Also: the first & the last curve are quadratic Bezier (only one control point). All the other curves are cubic Bezier (2 control points).

// size of the tangent
var t = 1 / 5;// points array
var p = [{x: 100,y: 100
}, {x: 250,y: 150
}, {x: 300,y: 300
}, {x: 450,y: 250
}, {x: 510,y: 140
}, {x: 590,y: 250
}, {x: 670,y: 140
}];function controlPoints(p) {// given the points array p calculate the control points for the cubic Bezier curvesvar pc = [];for (var i = 1; i < p.length - 1; i++) {var dx = p[i - 1].x - p[i + 1].x; // difference xvar dy = p[i - 1].y - p[i + 1].y; // difference y// the first control pointvar x1 = p[i].x - dx * t;var y1 = p[i].y - dy * t;var o1 = {x: x1,y: y1};// the second control pointvar x2 = p[i].x + dx * t;var y2 = p[i].y + dy * t;var o2 = {x: x2,y: y2};// building the control points arraypc[i] = [];pc[i].push(o1);pc[i].push(o2);}return pc;
}function drawCurve(p) {var pc = controlPoints(p); // the control points arraylet d =`M${p[0].x},${p[0].y}
Q${pc[1][1].x},${pc[1][1].y}, ${p[1].x},${p[1].y}
`if (p.length > 2) {// central curves are cubic Bezierfor (var i = 1; i < p.length - 2; i++) {d += `C${pc[i][0].x}, ${pc[i][0].y}, ${pc[i + 1][1].x}, ${pc[i + 1][1].y}, ${p[i + 1].x},${p[i + 1].y}`;}// the first & the last curve are quadratic Beziervar n = p.length - 1;d+= `Q${pc[n - 1][0].x}, ${pc[n - 1][0].y}, ${p[n].x}, ${p[n].y}`;}return d
}thePath.setAttribute("d", drawCurve(p))
svg{border:solid; fill:none;stroke:black;}
<svg id = 'svg' viewBox="0 0 800 400"><path id="thePath" />
</svg>

This is a pen where I'm doing the same in canvas https://codepen.io/enxaneta/pen/PqLNLv . Here you can see the tangents.

https://en.xdnf.cn/q/71538.html

Related Q&A

Python Class Inheritance AttributeError - why? how to fix?

Similar questions on SO include: this one and this. Ive also read through all the online documentation I can find, but Im still quite confused. Id be grateful for your help.I want to use the Wand class…

Is it possible to display pandas styles in the IPython console?

Is it possible to display pandas styles in an iPython console? The following code in a Jupyter notebookimport pandas as pd import numpy as npnp.random.seed(24) df = pd.DataFrame({A: np.linspace(1, 10,…

HEAD method not allowed after upgrading to django-rest-framework 3.5.3

We are upgrading django-rest-framework from 3.1.3 to 3.5.3. After the upgrade all of our ModelViewSet and viewsets.GenericViewSet views that utilize DefaultRouter to generate the urls no longer allow …

How do I specify server options?

Im trying to run gRPC server in Python. I found a way to do it like this:import grpc from concurrent import futuresserver = grpc.server(futures.ThreadPoolExecutor(max_workers=100)) ... # add my grpc se…

How to find collocations in text, python

How do you find collocations in text? A collocation is a sequence of words that occurs together unusually often. python has built-in func bigrams that returns word pairs. >>> bigrams([more, i…

How to set size of a Gtk Image in Python

How can I set the width and height of a GTK Image in Python 3.

Numpy Vectorized Function Over Successive 2d Slices

I have a 3D numpy array. I would like to form a new 3d array by executing a function on successive 2d slices along an axis, and stacking the resulting slices together. Clearly there are many ways to do…

MySQL and Python Select Statement Issues

Thanks for taking the time to read this. Its going to be a long post to explain the problem. I havent been able to find an answer in all the usual sources.Problem: I am having an issue with using the …

How to pass variable in url to Django List View

I have a Django generic List View that I want to filter based on the value entered into the URL. For example, when someone enters mysite.com/defaults/41 I want the view to filter all of the values mat…

Django Select Option selected issue

I tried to follow some examples on stackoverflow for option selected in select list but still, I could not get it work.This is my code snippet<select name="topic_id" style="width:90%&…