如何逐列遍历数据并将其馈送到Three.js 3D模型? [英] How to iterate through data column by column and feed them to a three.js 3D model?
问题描述
我正在使用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.
推荐答案
- 浏览器无法处理
.xlsx
文件.预先将其解析为JSON文件(使用node.js).
该脚本从同一目录中获取data.xlsx
并将其输出到data.json
(就文件大小而言,您可以随意提高效率).
- The browser can't handle
.xlsx
files. Parse it to a JSON file (with node.js) beforehand.
This script takesdata.xlsx
from the same directory and outputs it todata.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
}
- 渲染时,通过积分加速度计算当前位置.
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屋!