簡體   English   中英

在 A-Frame 和 Three.js 中使用多平面繪制曲線

[英]Draw a curve using multi plane in A-Frame and Three.js

我正在創建一個 A-Frame 應用程序(使用 Three.js)使用THREE.CatmullRomCurve3繪制一條道路。

該應用程序的概念是繪制一條連接多點的道路,我想繪制一條具有精確寬度的道路(例如:一條寬度為 3 米的道路),我使用THREE.PlaneGeometry連接 2 個點。

我的結果和我的代碼片段

 var scene, camera, renderer; var cube; var controls; function initScene() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 30; renderer = new THREE.WebGLRenderer({ alpha: true }); renderer.setSize(window.innerWidth, window.innerHeight); controls = new THREE.OrbitControls(camera); controls.update(); document.body.appendChild(renderer.domElement); } function render() { requestAnimationFrame(render); // required if controls.enableDamping or controls.autoRotate are set to true controls.update(); renderer.render(scene, camera); } function drawRoadByLine() { //Create a closed wavey loop var curve = new THREE.CatmullRomCurve3([ new THREE.Vector3(-10, 0, 10), new THREE.Vector3(-5, 5, 5), new THREE.Vector3(0, 0, 0), new THREE.Vector3(5, -5, 5), new THREE.Vector3(10, 0, 10) ]); var points = curve.getPoints(50); var geometry = new THREE.BufferGeometry().setFromPoints(points); var material = new THREE.LineBasicMaterial({ color: 0xff0000 }); // Create the final object to add to the scene var curveObject = new THREE.Line(geometry, material); scene.add(curveObject); } function drawRoadByPlane() { //Create a closed wavey loop var curve = new THREE.CatmullRomCurve3([ new THREE.Vector3(-10, 0, 10), new THREE.Vector3(-5, 5, 5), new THREE.Vector3(0, 0, 0), new THREE.Vector3(5, -5, 5), new THREE.Vector3(10, 0, 10) ]); var points = curve.getPoints(50); var group = new THREE.Group(); var currentPos; var nextPos; var distance; var plane; var rotationMatrix; for (var i = 0; i < points.length - 1; i++) { currentPos = new THREE.Vector3(points[i].x, points[i].y, points[i].z); nextPos = new THREE.Vector3(points[i + 1].x, points[i + 1].y, points[i + 1].z); distance = currentPos.distanceTo(nextPos); plane = createPlane(distance); plane.position.set(currentPos.x, currentPos.y, currentPos.z); // rotationMatrix = getRotationMatrix(currentPos, nextPos); // plane.applyMatrix(rotationMatrix); group.add(plane); } scene.add(group); } function createPlane(distance, position) { var geometry = new THREE.PlaneGeometry(1, distance); // Dummy random color each plane, true color is red (0xff0000) var color = Math.floor((Math.random() * 0xffffff) + 1); var material = new THREE.MeshBasicMaterial({ color: color, side: THREE.DoubleSide }); var plane = new THREE.Mesh(geometry, material); return plane; } function getRotationMatrix(v1, v2) { var quaternion = new THREE.Quaternion(); quaternion.setFromUnitVectors(v1, v2); var matrix = new THREE.Matrix4(); matrix.makeRotationFromQuaternion(quaternion); return matrix; } initScene(); drawRoadByPlane(); render();
 body { margin: 0; width: 100%; height: 100%; overflow: hidden; background-color: #000000; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script> <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

我現在的問題是如何使平面連續顯示(兩個平面之間沒有空間)。 我想我需要旋轉每個平面,但我不知道如何計算兩點之間的正確旋轉。

更新:

我剛剛將我的解決方案更改為使用THREE.Face3而不是THREE.PlaneGeometry

這是我的代碼片段

 var scene, camera, renderer; var cube; var controls; function initScene() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 30; renderer = new THREE.WebGLRenderer({ alpha: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); controls = new THREE.OrbitControls(camera, renderer.domElement); controls.update(); } function render() { requestAnimationFrame(render); renderer.render(scene, camera); } function draw() { var dummyPoints = [ new THREE.Vector3(-10, 0, 10), new THREE.Vector3(-5, 5, 5), new THREE.Vector3(0, 0, 0), new THREE.Vector3(5, -5, 5), new THREE.Vector3(10, 0, 10) ]; //Create a closed wavey loop var curve = new THREE.CatmullRomCurve3(dummyPoints); var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors, side: THREE.DoubleSide }); //create a triangular geometry var points = curve.getPoints(100); var roadPoints = []; var length = points.length; for (var i = 0; i < length - 1; i++) { roadPoints = roadPoints.concat(extractRoadPoint(points[i], points[i + 1])); } roadPoints = roadPoints.concat(extractRoadPoint(points[length - 1], points[length - 2])); var geometry = new THREE.Geometry().setFromPoints(roadPoints); // var face = new THREE.Face3(0, 1, 2); //add the face to the geometry's faces array // geometry.faces.push(face); for (var i = 0; i < roadPoints.length - 2; i++) { var face = new THREE.Face3(i, i + 1, i + 2); geometry.faces.push(face); face.color.set(new THREE.Color(Math.random() * 0xffffff - 1)); } //the face normals and vertex normals can be calculated automatically if not supplied above geometry.computeFaceNormals(); geometry.computeVertexNormals(); scene.add(new THREE.Mesh(geometry, material)); } function extractRoadPoint(point1, point2) { var result = []; var vector = { x: point2.x - point1.x, y: point2.y - point1.y, z: point2.z - point1.z, } var uOxz = { x: 0, y: 1, z: 0 }; var vectorVertices = { x: vector.y * uOxz.z - vector.z * uOxz.y, y: vector.z * uOxz.x - vector.x * uOxz.z, z: vector.x * uOxz.y - vector.y * uOxz.x, }; var t = Math.sqrt(1 * 1 / (vectorVertices.x * vectorVertices.x + vectorVertices.y * vectorVertices.y + vectorVertices.z * vectorVertices.z)); var sidePoint11 = { x: point1.x + vectorVertices.x * t, y: point1.y + vectorVertices.y * t, z: point1.z + vectorVertices.z * t, } var sidePoint12 = { x: point1.x - vectorVertices.x * t, y: point1.y - vectorVertices.y * t, z: point1.z - vectorVertices.z * t, } var sidePoint21 = { x: point2.x + vectorVertices.x * t, y: point2.y + vectorVertices.y * t, z: point2.z + vectorVertices.z * t, } var sidePoint22 = { x: point2.x - vectorVertices.x * t, y: point2.y - vectorVertices.y * t, z: point2.z - vectorVertices.z * t, } return [sidePoint11, sidePoint12, sidePoint21, sidePoint22]; } initScene(); draw(); render();
 body { margin: 0; width: 100%; height: 100%; overflow: hidden; background-color: #000000; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script> <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM