Skip to content

Instantly share code, notes, and snippets.

@eeropic
Created July 11, 2019 19:42
Show Gist options
  • Save eeropic/d81c34fc44657ab8dc8440b5ef93578f to your computer and use it in GitHub Desktop.
Save eeropic/d81c34fc44657ab8dc8440b5ef93578f to your computer and use it in GitHub Desktop.
catmull rom test
//from https://qroph.github.io/2018/07/30/smooth-paths-using-catmull-rom-splines.html
function getCurve(points,tension,alpha,closed) {
_tension = tension || 0;
_alpha = alpha || 0.5;
_closed = closed || false;
_points = points || [];
const dist = (p0, p1) => {
return Math.sqrt(Math.pow(p1.x - p0.x, 2) + Math.pow(p1.y - p0.y, 2));
};
const ps = _points.slice();
for (let i = ps.length - 1; i > 0; i--) {
if (dist(ps[i], ps[i - 1]) < 1)ps.splice(i, 1);
}
if (_closed && dist(ps[0], ps[ps.length - 1]) < 1) {
ps.splice(ps.length - 1, 1);
}
const numPoints = ps.length;
if (numPoints < 2) return;
if (_closed) {
ps.push(ps[0]);
ps.push(ps[1]);
ps.splice(0, 0, ps[numPoints - 1]);
} else {
const first = {
x: 2 * ps[0].x - ps[1].x,
y: 2 * ps[0].y - ps[1].y
};
const last = {
x: 2 * ps[numPoints - 1].x - ps[numPoints - 2].x,
y: 2 * ps[numPoints - 1].y - ps[numPoints - 2].y
};
ps.splice(0, 0, first);
ps.push(last);
}
var curvePoints=[]
for (let i = 1; i < ps.length - 2; i++) {
const p0 = ps[i - 1];
const p1 = ps[i];
const p2 = ps[i + 1];
const p3 = ps[i + 2];
const t0 = 0;
const t1 = t0 + Math.pow(dist(p0, p1), _alpha);
const t2 = t1 + Math.pow(dist(p1, p2), _alpha);
const t3 = t2 + Math.pow(dist(p2, p3), _alpha);
const m1x = (1 - _tension) * (t2 - t1) * ((p0.x - p1.x) / (t0 - t1) - (p0.x - p2.x) / (t0 - t2) + (p1.x - p2.x) / (t1 - t2));
const m1y = (1 - _tension) * (t2 - t1) * ((p0.y - p1.y) / (t0 - t1) - (p0.y - p2.y) / (t0 - t2) + (p1.y - p2.y) / (t1 - t2));
const m2x = (1 - _tension) * (t2 - t1) * ((p1.x - p2.x) / (t1 - t2) - (p1.x - p3.x) / (t1 - t3) + (p2.x - p3.x) / (t2 - t3));
const m2y = (1 - _tension) * (t2 - t1) * ((p1.y - p2.y) / (t1 - t2) - (p1.y - p3.y) / (t1 - t3) + (p2.y - p3.y) / (t2 - t3));
const ax = 2 * p1.x - 2 * p2.x + m1x + m2x;
const ay = 2 * p1.y - 2 * p2.y + m1y + m2y;
const bx = -3 * p1.x + 3 * p2.x - 2 * m1x - m2x;
const by = -3 * p1.y + 3 * p2.y - 2 * m1y - m2y;
const cx = m1x;
const cy = m1y;
const dx = p1.x;
const dy = p1.y;
const amount = Math.max(10, Math.ceil(dist(p0, p1) / 10));
for (let j = 1; j <= amount; j++) {
const t = j / amount;
const px = ax * t * t * t + bx * t * t + cx * t + dx;
const py = ay * t * t * t + by * t * t + cy * t + dy;
curvePoints.push(new Point(px,py))
}
}
return curvePoints
}
var d=new Tool()
paper.settings.hitTolerance=8
d.on({
mousedown(e){
if(e.count==0){
this.path=new Path({
strokeWidth:2,
strokeColor:"red",
opacity:0.7
})
}
else{
this.path.add(e.point)
var pts=this.path.segments.map(elem => elem.point)
var curve=getCurve(pts,0,1,false)
if(this.test!=null)this.test.remove()
this.test=new Path({
strokeWidth:2,
strokeColor:"green",
segments:curve
})
}
},
mousedrag(e){
var pts=this.path.segments.map(elem => elem.point)
var distX=(e.point.x-e.downPoint.x)
var distY=(e.downPoint.y-e.point.y)
var t=Math.min(1,Math.max(0,distX/100))
var a=Math.min(1,Math.max(0,distY/100))
console.log(t,a)
var curve=getCurve(pts,t,a,false)
if(this.test!=null)this.test.remove()
this.test=new Path({
strokeWidth:2,
strokeColor:"green",
segments:curve
})
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment