Last active
March 12, 2020 11:37
Revisions
-
hdf revised this gist
Apr 17, 2019 . 1 changed file with 12 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -72,13 +72,20 @@ function epicycles(x, y, rotation, fourier) { return createVector(x, y); } function waves(fourierX) { /*if (fourierX.length < 1) return; let fourier = fourierX.slice(0, 10).sort((a, b) => a.freq - b.freq); let l = fourier.length; colorMode(HSB, l); for (let i = 0; i < l; i++) { beginShape(); for (let i2 = 0; i2 <= (time / TWO_PI) * width; i2++) { vertex(i2, height / 4 + fourier[i].amp + fourier[i].amp * sin(i2 / (TWO_PI * 4) + fourier[i].phase)); stroke(i, l, l); } endShape(); } colorMode(RGB, 255);*/ } function draw() { -
hdf revised this gist
Apr 15, 2019 . 1 changed file with 13 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -72,21 +72,30 @@ function epicycles(x, y, rotation, fourier) { return createVector(x, y); } function waves(fourier) { /*for (let i = 0; i < fourier.length; i++) { beginShape(); for (let i2 = 0; i2 <= (time / TWO_PI) * width; i2++) vertex(i2, height/4 + fourier[i].amp + fourier[i].amp * sin(i2/TWO_PI/4 + fourier[i].phase)); endShape(); }*/ } function draw() { background(0); waves(fourierX); let v = epicycles(width / 2, height / 2, 0, fourierX); path.unshift(v); beginShape(); noFill(); for (let i = 0; i < path.length; i++) { if (lengths.includes(path.length - i)) { endShape(); beginShape(); } vertex(path[i].x, path[i].y); } endShape(); -
hdf revised this gist
Apr 14, 2019 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -80,7 +80,6 @@ function draw() { beginShape(); noFill(); for (let i = 0; i < path.length; i++) { if (lengths.includes(path.length - i - 2)) endShape(); -
hdf revised this gist
Apr 14, 2019 . 2 changed files with 20 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,6 +10,7 @@ let x = []; let fourierX; let time = 0; let path = []; let lengths = []; if (typeof(drawing) == 'undefined') var drawing = []; let w = 300; @@ -27,7 +28,17 @@ window.onhashchange = function() { function setup() { generatePointsFromSvg((window.location.hash ? window.location.hash.substr(1) : 'gh') + '.svg', (r) => { let scale = (w/r[1] < h/r[2]) ? w / (r[1] + 1) : h / (r[2] + 1); drawing = r[0].flat().map((e) => {return {x: e.x * scale, y: e.y * scale}}); lengths = []; // Do not allow large jumps for (let i = 1; i < drawing.length; i++) if (Math.sqrt(Math.pow(drawing[i].x - drawing[i-1].x, 2) + Math.pow(drawing[i].y - drawing[i-1].y, 2)) > 10) lengths.push(i); /*lengths = r[0].map((e) => e.length).slice(0, -1); for (let i = 1; i < lengths.length; i++) lengths[i] += lengths[i-1];*/ setup(); }); @@ -69,8 +80,14 @@ function draw() { beginShape(); noFill(); for (let i = 0; i < path.length; i++) { if (lengths.includes(path.length - i - 2)) endShape(); else if (lengths.includes(path.length - i - 1)) beginShape(); else vertex(path[i].x, path[i].y); } endShape(); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -35,7 +35,7 @@ function generatePointsFromSvg(file, cb, step_point) { delete point.alpha; data_points.push(point); } all_points.push(data_points); } return [all_points, width, height]; } -
hdf revised this gist
Apr 14, 2019 . 2 changed files with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -32,7 +32,7 @@ function setup() { }); createCanvas(w, h); frameRate(60); const skip = 1; for (let i = 0; i < drawing.length; i += skip) { const c = new Complex(drawing[i].x, drawing[i].y); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -27,8 +27,8 @@ function generatePointsFromSvg(file, cb, step_point) { let path = paths[i].getAttribute('d').replace(' ', ','); // get points at regular intervals let data_points = []; let c, l = Raphael.getTotalLength(path), step = step_point * Math.pow(Math.floor(Math.log(l) / Math.log(10)), 2); for (c = 0; c < l; c += step) { let point = Raphael.getPointAtLength(path, c); point.x = (point.x - (width / 2)); point.y = (point.y - (height / 2)); -
hdf revised this gist
Apr 14, 2019 . 2 changed files with 16 additions and 9 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,8 +15,17 @@ if (typeof(drawing) == 'undefined') let w = 300; let h = 300; window.onhashchange = function() { x = []; time = 0; path = []; drawing = []; current_svg_xml = ''; setup(); }; function setup() { generatePointsFromSvg((window.location.hash ? window.location.hash.substr(1) : 'gh') + '.svg', (r) => { let scale = (w/r[1] < h/r[2]) ? w / (r[1] + 1) : h / (r[2] + 1); drawing = r[0].map((e) => {return {x: e.x * scale, y: e.y * scale}}); setup(); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,6 @@ // Based on: https://github.com/Shinao/PathToPoints // To generate text: https://danmarshall.github.io/google-font-to-svg-path/ // Also consider: https://vecta.io/nano let current_svg_xml = ''; @@ -19,21 +21,17 @@ function generatePointsFromSvg(file, cb, step_point) { let paths = doc.getElementsByTagName('path'); // Read each paths from svg let all_points = []; let bbox_path = doc.children[0].getAttribute('viewBox').split(' '); let width = parseFloat(bbox_path[2]), height = parseFloat(bbox_path[3]); for (let i = 0; i < paths.length; ++i) { let path = paths[i].getAttribute('d').replace(' ', ','); // get points at regular intervals let data_points = []; let c, l = Raphael.getTotalLength(path); for (c = 0; c < l; c += step_point) { let point = Raphael.getPointAtLength(path, c); point.x = (point.x - (width / 2)); point.y = (point.y - (height / 2)); delete point.alpha; data_points.push(point); } -
hdf created this gist
Apr 10, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,46 @@ // Coding Challenge 130.3: Drawing with Fourier Transform and Epicycles // Daniel Shiffman // https://thecodingtrain.com/CodingChallenges/130.1-fourier-transform-drawing.html // https://thecodingtrain.com/CodingChallenges/130.2-fourier-transform-drawing.html // https://thecodingtrain.com/CodingChallenges/130.3-fourier-transform-drawing.html // https://youtu.be/7_vKzcgpfvU // https://editor.p5js.org/codingtrain/sketches/ldBlISrsQ class Complex { constructor(a, b) { this.re = a; this.im = b; } add(c) { this.re += c.re; this.im += c.im; } mult(c) { const re = this.re * c.re - this.im * c.im; const im = this.re * c.im + this.im * c.re; return new Complex(re, im); } } function dft(x) { const X = []; const N = x.length; for (let k = 0; k < N; k++) { let sum = new Complex(0, 0); for (let n = 0; n < N; n++) { const phi = (TWO_PI * k * n) / N; const c = new Complex(cos(phi), -sin(phi)); sum.add(x[n].mult(c)); } sum.re = sum.re / N; sum.im = sum.im / N; let freq = k; let amp = sqrt(sum.re * sum.re + sum.im * sum.im); let phase = atan2(sum.im, sum.re); X[k] = { re: sum.re, im: sum.im, freq, amp, phase }; } return X; } LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Discrete Fourier transformation</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.dom.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.8/raphael.min.js"></script> <script src="svg2vec.js"></script> <script src="fourier.js"></script> <script src="sketch.js"></script> </head> <body></body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,75 @@ // Coding Challenge 130.3: Drawing with Fourier Transform and Epicycles // Daniel Shiffman // https://thecodingtrain.com/CodingChallenges/130.1-fourier-transform-drawing.html // https://thecodingtrain.com/CodingChallenges/130.2-fourier-transform-drawing.html // https://thecodingtrain.com/CodingChallenges/130.3-fourier-transform-drawing.html // https://youtu.be/7_vKzcgpfvU // https://editor.p5js.org/codingtrain/sketches/ldBlISrsQ let x = []; let fourierX; let time = 0; let path = []; if (typeof(drawing) == 'undefined') var drawing = []; let w = 300; let h = 300; function setup() { generatePointsFromSvg('gh.svg', (r) => { let scale = (w/r[1] < h/r[2]) ? w / (r[1] + 1) : h / (r[2] + 1); drawing = r[0].map((e) => {return {x: e.x * scale, y: e.y * scale}}); setup(); }); createCanvas(w, h); //frameRate(24); const skip = 1; for (let i = 0; i < drawing.length; i += skip) { const c = new Complex(drawing[i].x, drawing[i].y); x.push(c); } fourierX = dft(x); fourierX.sort((a, b) => b.amp - a.amp); } function epicycles(x, y, rotation, fourier) { for (let i = 0; i < fourier.length; i++) { let prevx = x; let prevy = y; let freq = fourier[i].freq; let radius = fourier[i].amp; let phase = fourier[i].phase; x += radius * cos(freq * time + phase + rotation); y += radius * sin(freq * time + phase + rotation); stroke(255, 100); noFill(); ellipse(prevx, prevy, radius * 2); stroke(255); line(prevx, prevy, x, y); } return createVector(x, y); } function draw() { background(0); let v = epicycles(width / 2, height / 2, 0, fourierX); path.unshift(v); beginShape(); noFill(); for (let i = 0; i < path.length; i++) { vertex(path[i].x, path[i].y); } endShape(); const dt = TWO_PI / fourierX.length; time += dt; if (time > TWO_PI) { time = 0; path = []; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,43 @@ // Based on: https://github.com/Shinao/PathToPoints let current_svg_xml = ''; function generatePointsFromSvg(file, cb, step_point) { if (typeof(step_point) == 'undefined') step_point = 0.5; if (current_svg_xml == '') { let xhr = new XMLHttpRequest(); xhr.open('GET', file, true); xhr.onload = function(e) { current_svg_xml = this.response; cb(generatePointsFromSvg(file, cb, step_point)); }; xhr.send(); return; } let doc = (new DOMParser()).parseFromString(current_svg_xml, "application/xml"); let paths = doc.getElementsByTagName('path'); // Read each paths from svg let all_points = []; let width = 0, height = 0; for (let i = 0; i < paths.length; ++i) { let path = paths[i].getAttribute('d').replace(' ', ','); let bbox_path = doc.children[i].getAttribute('viewBox').split(' '); let w = parseFloat(bbox_path[2]); if (w > width) width = w; let h = parseFloat(bbox_path[3]); if (h > height) height = h; // get points at regular intervals let data_points = []; let c, l = Raphael.getTotalLength(path); for (c = 0; c < l; c += step_point) { let point = Raphael.getPointAtLength(path, c); point.x = (point.x - (w / 2)); point.y = (point.y - (h / 2)); delete point.alpha; data_points.push(point); } all_points = all_points.concat(data_points); } return [all_points, width, height]; }