如何逐列遍历数据并将其馈送到Three.js 3D模型? [英] How to iterate through data column by column and feed them to a three.js 3D model?

查看:43
本文介绍了如何逐列遍历数据并将其馈送到Three.js 3D模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用three.js开发3D模型,该模型使用加速度计和陀螺仪显示车辆的位置和方向.我有一个xlsx文件,其中包含x,y,z,滚动,偏航和俯仰的数据.到目前为止,我已经在随机生成的数据上运行3D模型,另一方面,我开发了读取xlsx文件并显示数据的代码.

I am developing a 3D model using three.js which show the position and orientation of a vehicle using accelerometer and gyroscope. I have an xlsx file containing the data for x, y, z, roll, yaw and pitch. So far I have the 3D model running on a randomly generated data, on the other hand, I developed the code that read the xlsx file and display the data.

我的计划是,在读取xlsx文件之后,我遍历x列,y列等,并在3D模型代码中使用它们(用实际数据替换随机生成的数据).

My plan is, after reading the xlsx file, I iterate through the x column, y column etc. and use them inside the 3D model code (replacing the random generated data by the real data).

我的xlsx数据格式如下:

My xlsx data format are like below:

这是文件:

单击此处下载数据

这是我从xlsx文件读取的代码:

This is my code to read from the xlsx file:

var parser = new (require('simple-excel-to-json').XlsParser)();
var doc = parser.parseXls2Json('data/TestingWithThresholdXLSX.xlsx');
// convert json to string
var docToString = JSON.stringify(doc)
// parsing the JSON string text into a javascript Object
var json = JSON.parse(docToString);
// Loop through the json string
var text;
for (i = 0; i < 100; i++) {
    text = json[0][i]["TimeId"];
    console.log(text)
  }

这是我制作3D模型的代码:

and this is my code for making the 3D model:

HTML

<!DOCTYPE html>
<html>
 <head>
   <meta charset="UTF-8">
   <link rel="stylesheet" type="css" href="css/style.css">
   <script src="https://threejs.org/build/three.min.js"></script>
   <script src= "https://threejs.org/examples/js/controls/OrbitControls.js"></script>
   <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"> </script>
   <script src="https://requirejs.org/docs/release/2.3.6/comments/require.js" type="text/javascript"></script>
   <script type="module"> import * as THREE from "https://threejsfundamentals.org/threejs/resources/threejs/r122/build/three.module.js"</script>
  </head>

<h1 style="color:red">3D Model Rotation and Translation</h1>
<body>
 <canvas id="canvas" width="1500" height="800" style="border:1px solid #000000;"></canvas>
 <div id="accelPanel"></div>
</body>
<script src="js/index.js"></script>
</html>

JavaScript

function main() {
  const canvas = document.querySelector('#canvas');
  const accelPanel = document.querySelector('#accelPanel');
  const renderer = new THREE.WebGLRenderer({canvas});
  var context = canvas.getContext("2d");
  
  const fov = 60;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 2000;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.set(0, 50, 1.5);
  camera.up.set(0, 0, 1);
  camera.lookAt(0, 0, 0);
  
  const scene = new THREE.Scene();
  {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.PointLight(color, intensity);
    scene.add(light);
  }
  // an array of objects who's rotation to update
  const objects = [];
  const radius = 3;
  const widthSegments = 3;
  const heightSegments = 3;
  const sphereGeometry = new THREE.BoxGeometry(radius, widthSegments, heightSegments);
  const sunMaterial = new THREE.MeshBasicMaterial({color: "green",wireframe: false}); 
  const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial);

  var cubeAxis = new THREE.AxesHelper(10);
    sunMesh.add(cubeAxis);

  sunMesh.scale.set(2, 2, 2);
  scene.add(sunMesh);
  objects.push(sunMesh);

  function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }
  
  function render(speed) {
    speed *= 0.001;

    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight;
      camera.updateProjectionMatrix();
    }

    /* This is where I assume the data should be placed*/
    objects.forEach((obj) => {
      obj.rotation.x = speed+1;
      obj.rotation.y = speed+2;
      obj.rotation.z = speed+34;
      obj.position.x = speed+1;
      obj.position.y = speed+2;
      obj.position.z = speed+2;
      console.log(obj.position.y);
    });   
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
}
main();

您可以找到工作代码 JSFiddle

我尝试将数据读取器代码放在3D模型的javascript代码内,特别是放在objects.forEach((obj)=>之后),但是它没有用,我是javascript的半入门者,所以感谢您为解决此问题提供的帮助.

I tried to play around and placing the data reader code inside the javascript code for 3D model, specifically after objects.forEach((obj) =>, but it never worked and I am a semi-beginner in javascript, so I appreciate any help to guide through this problem.

推荐答案

  1. 浏览器无法处理 .xlsx 文件.预先将其解析为JSON文件(使用node.js).
    该脚本从同一目录中获取 data.xlsx 并将其输出到 data.json (就文件大小而言,您可以随意提高效率).
  1. The browser can't handle .xlsx files. Parse it to a JSON file (with node.js) beforehand.
    This script takes data.xlsx from the same directory and outputs it to data.json (you're free to make it more efficient in terms of file size).

const fs = require('fs')
const path = require('path')
const { XlsParser } = require('simple-excel-to-json')

const SECONDS_PER_DAY = 24 * 60 * 60

const json = (new XlsParser()).parseXls2Json(path.resolve(__dirname, 'data.xlsx'));
const data = json[0].map((item) => ({
    time: item.TimeId * SECONDS_PER_DAY,
    rotX: deg2Rad(item.Gyro_X),
    rotY: deg2Rad(item.Gyro_Y),
    rotZ: deg2Rad(item.Gyro_Z),
    accX: item.Accelero_X,
    accY: item.Accelero_Y,
    accZ: item.Accelero_Z,
}))
fs.writeFileSync(path.resolve(__dirname, 'data.json'), JSON.stringify(data))

function deg2Rad(angle) {
    return angle * Math.PI / 180
}

  1. 渲染时,通过积分加速度计算当前位置.

let currentIndex = 0
let time = data[currentIndex].time
let velocity = new THREE.Vector3()
requestAnimationFrame(render);

function render(dt) {
    dt *= 0.001 // in seconds
    time += dt
    document.querySelector("#time").textContent = time.toFixed(2)

    // Find datapoint matching current time
    while (data[currentIndex].time < time) {
        currentIndex++
        if (currentIndex >= data.length) return
    }
    const { rotX, rotY, rotZ, accX, accY, accZ } = data[currentIndex]
    const acceleration = new THREE.Vector3(accX, accY, accZ)
    object.rotation.set(rotX, rotY, rotZ)
    object.position.add(velocity.clone().multiplyScalar(dt)).add(acceleration.clone().multiplyScalar(0.5 * dt ** 2))
    velocity.add(acceleration.clone().multiplyScalar(dt))

    resizeToClient();
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}

您可以在我创建的GitHub存储库中找到所有内容: https://github.com/Josef37/threejs-from-xlsx

You can find everything in a GitHub repo I created: https://github.com/Josef37/threejs-from-xlsx

这篇关于如何逐列遍历数据并将其馈送到Three.js 3D模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆