添加小车路径追踪

This commit is contained in:
2026-01-23 15:39:24 +08:00
parent 90bc171da0
commit 51f91b4cc9

View File

@@ -10,7 +10,6 @@
</template>
<script>
/* eslint-disable */
import * as THREE from 'three'
import { mapGetters } from 'vuex'
// import { points } from '@/config/point.js'
@@ -43,7 +42,6 @@ export default {
// 小车相关
vehicleImage: require('@/images/new/agv.png'),
carMovementEnabled: true,
carSize: 30,
// 视图控制
isDragging: false,
previousTouchX: 0,
@@ -64,13 +62,22 @@ export default {
isLoading: true,
reconnectTimer: null, // 重连计时器
animationFrameId: null,
updateInterval: 50,
// 优化相关参数
updateThrottle: 50, // 数据更新节流间隔(ms)
lastUpdateTime: 0,
// resizeHandler: null // 存储resize事件处理函数
hasYellowDot: false,
yellowDotSprite: null,
yellowDotInitialPos: null
yellowDotInitialPos: null,
// 小车路径追踪相关
carPath: [], // 存储小车历史位置
pathPoints: [], // 存储路径点Three对象
pathMaterial: null, // 路径点的材质
pathGeometry: null, // 路径点的几何体
maxPathPoints: 3000, // 最大路径点数(避免内存泄漏)
pathUpdateInterval: 100, // 路径点更新间隔ms避免记录过于密集
lastPathUpdateTime: 0, // 上次更新路径的时间
pathNeedsUpdate: false // 标记路径是否需要更新
}
},
computed: {
@@ -80,6 +87,7 @@ export default {
carPosition: {
handler(newVal) {
this.updateCarPosition(newVal)
this.addPathPoint(newVal)
},
deep: true
}
@@ -95,6 +103,10 @@ export default {
if (this.reconnectTimer) clearTimeout(this.reconnectTimer)
if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId)
this.closeWebSocket()
// 清理路径相关资源
this.clearPathResources()
// 清理Three.js资源
if (this.renderer) {
this.renderer.dispose();
@@ -121,6 +133,14 @@ export default {
this.scene.remove(this.yellowDotSprite);
this.yellowDotSprite = null;
}
if (this.pathMaterial) {
this.pathMaterial.dispose()
this.pathMaterial = null
}
if (this.pathGeometry) {
this.pathGeometry.dispose()
this.pathGeometry = null
}
if (this.scene) {
this.scene.clear();
this.scene = null;
@@ -146,6 +166,21 @@ export default {
this.allPoints = [];
this.pointCount = 0;
},
clearPathResources() {
if (this.pathPoints) {
this.scene.remove(this.pathPoints)
if (this.pathPoints.material) {
this.pathPoints.material.dispose()
}
this.pathPoints = null
}
if (this.pathGeometry) {
this.pathGeometry.dispose()
this.pathGeometry = null
}
this.carPath = []
this.pathNeedsUpdate = false
},
initThreeJS() {
// 初始化Three.js场景
const container = this.$refs.canvasContainer;
@@ -179,6 +214,7 @@ export default {
this.updateRendererSize();
this.createPointCloud();
this.createCar();
this.initPathSystem(); // 初始化路径系统
this.setupEventListeners();
this.animate();
},
@@ -420,6 +456,12 @@ export default {
isCameraUpdated = true;
}
// 检查并更新路径
if (this.pathNeedsUpdate) {
this.updatePathDisplay();
this.pathNeedsUpdate = false;
}
if (isCameraUpdated) {
this.camera.updateProjectionMatrix();
}
@@ -627,6 +669,98 @@ export default {
// const arr = points2.data
// this.updatePointCloud(arr);
// }, 2000)
},
// 初始化路径系统
initPathSystem() {
// 创建路径点材质
this.pathMaterial = new THREE.PointsMaterial({
size: 3, // 路径点大小比普通点云点大一些
color: 0xFFD700, // 金黄色
sizeAttenuation: false,
transparent: true,
opacity: 0.8,
depthWrite: false // 避免遮挡问题
})
// 创建路径几何体
this.pathGeometry = new THREE.BufferGeometry()
const pathPoints = new THREE.Points(this.pathGeometry, this.pathMaterial)
this.scene.add(pathPoints)
},
// 添加路径点
addPathPoint(position) {
const now = Date.now()
if (now - this.lastPathUpdateTime < this.pathUpdateInterval) {
return
}
this.lastPathUpdateTime = now
if (this.carPath.length > 0) {
const lastPoint = this.carPath[this.carPath.length - 1]
const isSamePosition = this.arePositionsEqual(position, lastPoint)
if (isSamePosition) {
return
}
}
this.carPath.push({
x: position.x,
y: position.y,
angle: position.angle,
timestamp: now
})
if (this.carPath.length > this.maxPathPoints) {
this.carPath.shift()
}
// this.updatePathDisplay()
this.pathNeedsUpdate = true
},
arePositionsEqual(pos1, pos2) {
if (!pos1 || !pos2) return false
const dx = Math.abs(pos1.x - pos2.x)
const dy = Math.abs(pos1.y - pos2.y)
return dx < 0.001 && dy < 0.001
},
// 更新路径显示
updatePathDisplay() {
if (this.carPath.length === 0) return
const positions = new Float32Array(this.carPath.length * 3)
for (let i = 0; i < this.carPath.length; i++) {
const point = this.carPath[i]
positions[i * 3] = point.x
positions[i * 3 + 1] = point.y
positions[i * 3 + 2] = 1
}
try {
if (!this.pathGeometry) return
if (!this.pathGeometry.attributes.position) {
this.pathGeometry.setAttribute(
'position',
new THREE.BufferAttribute(positions, 3)
)
} else if (this.pathGeometry.attributes.position.array.length !== positions.length) {
this.pathGeometry.deleteAttribute('position')
this.pathGeometry.setAttribute(
'position',
new THREE.BufferAttribute(positions, 3)
)
} else {
this.pathGeometry.attributes.position.array.set(positions)
this.pathGeometry.attributes.position.needsUpdate = true
}
} catch (error) {
console.error('更新路径显示时出错:', error);
// 出错时重新创建整个几何体
if (this.pathGeometry) {
this.pathGeometry.dispose()
}
this.pathGeometry = new THREE.BufferGeometry()
this.pathGeometry.setAttribute(
'position',
new THREE.BufferAttribute(positions, 3)
)
}
}
}
}