//Create delay function const delay = ms => new Promise(res => setTimeout(res, ms)); //Tennis court coordinates //Y: [-5.02m, 5.02m] X: [-11.88m, 11.88m] no Z height var x = [-11.88, 11.88, 11.88, -11.88] var y = [-5.02, -5.02, 5.02, 5.02] //Shift the court slightly up so its not interfering with the grid var z = [0.01, 0.01, 0.01, 0.01] //Face is made up of 2 triangles, both need to be set to the same colour var facecolor = [ 'rgb(30, 175, 0)', 'rgb(30, 175, 0)', ] var court = { name:"Court", x, y, z, facecolor, type: 'mesh3d', } var x_val =new Array(); var y_val =new Array(); var z_val =new Array(); var trajectory = { name: "Trajectory", type: 'scatter3d', mode: 'lines+markers', x: x_val, y: y_val, z: z_val, line: { width: 4, color: '#ff0000', }, marker: { color: '#0000ff', size: 2, symbol: 'circle', }, }; var layout = { title: 'Tennis Ball Trajectory Plot', autosize: true, margin: { autoexpand: true, }, scene:{ xaxis:{ range:[-18,18], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, yaxis:{ range:[-10,10], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, zaxis:{ range:[ 0, 2], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, } }; //COEFF = document.getElementById("cor_plot"); var pointCount = 1600; var coeff_restitution = 0; var velocity_vector_pre = 1; var velocity_vector_post = 1; var bounce_sample = new Array(); var center_bounce = 0; var sample = new Array(); // variables for failed PolynomialRegression attempt //const vector_length = 1; // Determines how many points back to use to calculate average z-velocity //const degree = 3; //var sample_division = new Array(); // Failed implementation for PolynomialRegression library // Implementation using regression to create a function that models all points of bounce // Third order polynomial has 3 zeros and is the minimum number necessary //const regression = new PolynomialRegression(sample, z_val, degree) // for(let point = 0; point < pointCount * 10; point++) // { // //sample_division[point] = regression.predict(point / 10) // if(sample_division[point] > 0.005 && sample_division[point] < 0.015) // // gathers all sub-points within the regression that fall at a "bounce height" // // but this could result in more than one point being recorded. needs to have one centered // // point. gather into array and then take the middle value? // { // bounce_sample.push(point); // } // } // center_bounce = Math.floor((bounce_sample.length - 1) / 2); // find center of sample //make sure that this can be indexed within the regression. Is this 10x the actual array size? // velocity_vector_pre = regression.predict(bounce_sample[center_bounce - 1]); // velocity_vector_post = regression.predict(bounce_sample[center_bounce + 1]); // coeff_restitution = Math.abs(velocity_vector_post) / Math.abs(velocity_vector_pre); var cor_trace1 = { name: "2D Tennis Ball Bounce", type: 'scatter', mode: 'lines+markers', x:sample, y:z_val, }; var data = [cor_trace1,]; var cor_layout = { title: '2D Tennis Ball Bounce Graph', autosize: true, margin: { autoexpand: true, }, scene:{ xaxis:{ range:[0,1800], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, yaxis:{ range:[-10,10], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, } }; //Init plot Plotly.newPlot("secondplot", [trajectory,court] , layout, {responsive: true} ); Plotly.newPlot('cor_plot', data, cor_layout, {responsive: true} ); //Update plot with info from GET call function poll(filename) { var jqueryRequest = $.get("http://129.21.94.11:8000/serve/" + filename) .done(function(data) { Papa.parse(data, { dynamicTyping: true, delimiter: " ", //Only include if the input contains a header row; i.e. the first row is labels. //header: true, worker: true, complete: function(results){ results.data.forEach((element) => { x_val.push(element[2]); y_val.push(element[0]); //Compensate for court offset z_val.push(element[1]+0.01); }); console.log(x_val.length) pointCount = x_val.length; for (let point = 0; point < pointCount; point++) { sample.push(point); // Create a series for just sample count } console.log(sample) Plotly.update("secondplot", [trajectory,court], layout, {responsive: true}); Plotly.update('cor_plot', data, cor_layout, {responsive: true}); console.log(pointCount) }, }); }).fail(function(errorData){ console.error("Backend Request failed! Is the backend running?"); }); } //Get the button from the HTML file var button = document.getElementById("sendPost"); //Get the input field from the HTML file var input_field = document.getElementById("csvSelector"); //If the user presses "enter" on the input field, call to press the button, as this is expected behaviour input_field.addEventListener("keypress",function(event){ if (event.key === "Enter"){ event.preventDefault(); button.click(); } }); //On button click... button.addEventListener("click",function(e){ //Get the file name from the text input var file_name = input_field.value; //Send the text input to the web server $.post("http://129.21.94.11:8000/serve", { file_name }) //Once the POST response comes back .done(function(){ //Wait 2s for image processing to run delay(2000); //Clear current values to graph the new file x_val.length = 0; y_val.length = 0; z_val.length = 0; sample.length = 0; //Run a GET call, with the given file name poll(file_name); //FitCurve(sample, z_val); }); },false); //Failed test implementation for polyfit library //function FitCurve(x, y) //{ // var poly = Polyfit(x, y); // solver = poly.getPolynomial(degree); // console.log(solver(1.17)); //}