Skip to content

Instantly share code, notes, and snippets.

@melalj
Created June 30, 2018 21:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save melalj/524fd284d4683738fe9d0cb2680deb9c to your computer and use it in GitHub Desktop.
Save melalj/524fd284d4683738fe9d0cb2680deb9c to your computer and use it in GitHub Desktop.
Convert a Circle shape to a set of Bezier curves (SVG Path string) using Javascript
export default function circleToBezier(cx, cy, r) {
// Inspired by https://codereview.stackexchange.com/questions/141491/calculating-a-circle-with-bezier-curves
function Coord(x, y) {
var self = this;
this.x = parseFloat(x);
this.y = parseFloat(y);
this.offset = function(offsetX, offsetY) {
self.x += offsetX;
self.y += offsetY;
}
}
Coord.prototype.toString = function () {
return `${this.x} ${this.y}`
}
function BezierCurve(x, y, c1, c2) {
var self = this;
this.x = x;
this.y = y;
this.c1 = c1;
this.c2 = c2;
this.offset = function(offsetX, offsetY) {
self.x += offsetX;
self.y += offsetY;
self.c1.offset(offsetX, offsetY);
self.c2.offset(offsetX, offsetY);
}
}
BezierCurve.prototype.toString = function () {
return `${this.c1.toString()} ${this.c2.toString()} ${this.x} ${this.y}`
}
var BEZIER_CONTROL_POINT = 0.552284749831;
var twoR = r * 2;
var offsetX = cx - r;
var offsetY = cy - r;
var controlPointOffset = r * BEZIER_CONTROL_POINT;
// from Middle Left
var firstMove = new Coord(0, r);
// curve to Top Middle
var curve1 = new BezierCurve(r, 0,
new Coord(0, r - controlPointOffset),
new Coord(r - controlPointOffset, 0));
// curve to Middle Right
var curve2 = new BezierCurve(twoR, r,
new Coord(r + controlPointOffset, 0),
new Coord(twoR, r - controlPointOffset));
// curve to Bottom Middle
var curve3 = new BezierCurve(r, twoR,
new Coord(twoR, r + controlPointOffset),
new Coord(r + controlPointOffset, twoR));
// curve back to Middle Left
var curve4 = new BezierCurve(0, r,
new Coord(r - controlPointOffset, twoR),
new Coord(0, r + controlPointOffset));
if (offsetX > 0) {
firstMove.offset(offsetX, offsetY);
curve1.offset(offsetX, offsetY);
curve2.offset(offsetX, offsetY);
curve3.offset(offsetX, offsetY);
curve4.offset(offsetX, offsetY);
}
let output = '';
output += (`M ${firstMove.toString()}`);
output += (`C ${curve1.toString()}`);
output += (`C ${curve2.toString()}`);
output += (`C ${curve3.toString()}`);
output += (`C ${curve4.toString()}`);
output += ("Z");
return output;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment