ALGORITHMS

See the Pen ImbJL by Genevieve Smith-Nunes (@readysaltedcode) on CodePen.


              var xScale = d3.scale.linear().domain([-1.7, 1.7]).range([0, 800]);
              var yScale = d3.scale.linear().domain([-1.7, 1.7]).range([800, 0]);
              var radiusScale = d3.scale.linear().domain([5, 0]).range([3, 16]);
              var colorScale = d3.scale.linear().domain([0, 5]).range(['brown', 'yellow']);

              var interpolationScale = d3.scale.linear().domain([0, 205000, 330000]).range([1, 1, 0.02]).clamp(true);
              var depthScale = d3.scale.linear().domain([0, 31000, 47000, 62000, 77000, 94000]).range([0, 1, 2, 3, 4, 5]).clamp(true);
              var alphaScale = d3.scale.linear().domain([0, 330000]).range([0.01, 0.2]).clamp(true);
              var linkAlphaScale = d3.scale.linear().domain([0, 330000]).range([0, 1]).clamp(true);

              var tree = {
                name: 'Spine',
                children: [
                  {
                    name: 'HipCenter',
                    children: [
                      {
                        name: 'HipLeft',
                        children: [
                          {
                            name: 'KneeLeft',
                            children: [
                              {
                                name: 'AnkleLeft',
                                children: [
                                  {
                                    name: 'FootLeft'
                                  }
                                ]
                              }
                            ]
                          }
                        ]
                      },
                      {
                        name: 'HipRight',
                        children: [
                          {
                            name: 'KneeRight',
                            children: [
                              {
                                name: 'AnkleRight',
                                children: [
                                  {
                                    name: 'FootRight'
                                  }
                                ]
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  },
                  {
                    name: 'ShoulderCenter',
                    children: [
                      {
                        name: 'Head'
                      },
                      {
                        name: 'ShoulderLeft',
                        children: [
                          {
                            name: 'ElbowLeft',
                            children: [
                              {
                                name: 'WristLeft',
                                children: [
                                  {
                                    name: 'HandLeft'
                                  }
                                ]
                              }
                            ]
                          }
                        ]
                      },
                      {
                        name: 'ShoulderRight',
                        children: [
                          {
                            name: 'ElbowRight',
                            children: [
                              {
                                name: 'WristRight',
                                children: [
                                  {
                                    name: 'HandRight'
                                  }
                                ]
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  }
                ]
              };

              function getJointsOfSkeleton(json, skeleton) {
                // Transform Kinect data into object
                var joints = {};
                if(json.Skeletons === undefined)
                  return;
                if(skeleton > json.Skeletons.length - 1)
                  return;
                _.each(json.Skeletons[skeleton].Joints, function(joint) {
                  joints[joint.JointType] = joint;
                });
                return joints;
              }

              function initialiseTree() {
                var treeLayout = d3.layout.tree()
                  .size([500, 500]);

                var treeNodesArray = treeLayout(tree);
                var treeLinksArray = treeLayout.links(treeNodesArray);

                // keep tabs on original positions
                treeNodesArray = _.map(treeNodesArray, function(node) {
                  node.startX = node.x,
                  node.startY = node.y
                  return node;
                });

                // convert to object
                treeNodes = {};
                _.each(treeNodesArray, function(node) {
                  treeNodes[node.name] = node;
                })

                treeLinks = treeLinksArray;

                // console.log(treeLinksArray);
              }

              function drawTree() {
                ctx.save();

                ctx.strokeStyle = 'orange';
                ctx.lineWidth = 0.5;

                ctx.translate(300, 100);

                ctx.globalAlpha = linkAlphaScale(Date.now() - startTime);

                _.each(treeLinks, function(link) {
                  var node0 = treeNodes[link.source.name];
                  var node1 = treeNodes[link.target.name];

                  if(node0.depth > depth || node1.depth > depth)
                    return;

                  // console.log(node0);
                  drawLine(ctx, node0.x, node0.y, node1.x, node1.y);
                });

                ctx.globalAlpha = 0.9;
              
                _.each(treeNodes, function(node) {
                  // console.log(node.depth, depth);
                  if(node.depth > depth)
                    return;

                  ctx.fillStyle = colorScale(node.depth);
                  drawCircle(ctx, node.x, node.y, radiusScale(node.depth));
                  // ctx.fillStyle = 'white';
                  // ctx.textAlign = 'center';
                  // ctx.fillText(node.name, node.x, node.y);
                });

                ctx.restore();
              }

              function updateNodes(joints) {
                // Interpolate between treeNodes and joints

                function linearInterpolate(p0, p1, u) {
                  return (1 - u) * p0 + u * p1;
                }

                _.each(joints, function(joint) {
                  var jointType = joint.JointType;
                  var node = treeNodes[jointType];

                  // console.log(joint, node);

                  var u = interpolationScale(Date.now() - startTime);
                  node.x = linearInterpolate(node.startX, xScale(joint.Position.X), u);
                  node.y = linearInterpolate(node.startY, yScale(joint.Position.Y), u);
                });

                // console.log(treeNodes);    
              }
              
              function clear() {
                // ctx.globalAlpha = 0.9;
                var alpha = alphaScale(Date.now() - startTime);
                ctx.fillStyle = "rgba(0,0,0," + alpha + ")";
                ctx.fillRect(0, 0, 1200, 800);
              }

              var canvas = document.getElementById('mycanvas');
              var ctx = canvas.getContext('2d');

              ctx.fillStyle = "rgb(0,0,0)";
              ctx.fillRect(0, 0, 1200, 800);

              var treeNodes, treeLinks;
              var startTime = Date.now();
              var depth = 0;

              initialiseTree();
              drawTree();
            // You can choose one of these to visualise a different dance
            var DATASET_ALGORITHM = 'https://d10u56tzn9e9rq.cloudfront.net/algorithm_';

            var DATASET_BINARY = 'https://d10u56tzn9e9rq.cloudfront.net/binary_';

            var DATASET_WHOLEPIECE = 'https://d10u56tzn9e9rq.cloudfront.net/wholepiece_';

            var dataFetcher = new ChunkedDataFetcher(DATASET_ALGORITHM);
            dataFetcher.drawFunction = function(json) {
                depth = Math.floor(depthScale(Date.now() - startTime));
                  // console.log(depth);

                  var joints = getJointsOfSkeleton(json, 0);
                  if(!joints)
                    return; 

                  ctx.globalAlpha = 1;

                  // console.log(joints)

                  clear();

                  updateNodes(joints);
                  drawTree();
            }