点云
This commit is contained in:
5114
src/config/point.js
5114
src/config/point.js
File diff suppressed because it is too large
Load Diff
5107
src/config/point1.js
5107
src/config/point1.js
File diff suppressed because it is too large
Load Diff
5076
src/config/point2.js
5076
src/config/point2.js
File diff suppressed because it is too large
Load Diff
@@ -137,6 +137,7 @@ export default {
|
|||||||
...mapGetters(['isTop'])
|
...mapGetters(['isTop'])
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
|
document.removeEventListener('keydown', this.handleKeydown);
|
||||||
if (this.intervalId) {
|
if (this.intervalId) {
|
||||||
clearTimeout(this.intervalId)
|
clearTimeout(this.intervalId)
|
||||||
}
|
}
|
||||||
@@ -149,9 +150,17 @@ export default {
|
|||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.initGuide()
|
this.initGuide()
|
||||||
})
|
})
|
||||||
|
document.addEventListener('keydown', this.handleKeydown);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
handleKeydown(event) {
|
||||||
|
// 仅在对话框可见时响应Enter键
|
||||||
|
if (this.dialogVisible && event.key === 'Enter') {
|
||||||
|
event.preventDefault(); // 阻止默认行为
|
||||||
|
this.stationConfirm();
|
||||||
|
}
|
||||||
|
},
|
||||||
initGuide() {
|
initGuide() {
|
||||||
const config = {
|
const config = {
|
||||||
// allowClose: false,
|
// allowClose: false,
|
||||||
|
|||||||
@@ -33,6 +33,13 @@ export default {
|
|||||||
allPoints: [],
|
allPoints: [],
|
||||||
pointCount: 0,
|
pointCount: 0,
|
||||||
maxPoints: 1000000, // 最大点数限制
|
maxPoints: 1000000, // 最大点数限制
|
||||||
|
// 点云坐标范围配置(根据实际数据调整)
|
||||||
|
pointCloudRange: {
|
||||||
|
minX: 0, // 点云X轴最小值
|
||||||
|
maxX: 10, // 点云X轴最大值
|
||||||
|
minY: 0, // 点云Y轴最小值
|
||||||
|
maxY: 10 // 点云Y轴最大值
|
||||||
|
},
|
||||||
// 小车相关
|
// 小车相关
|
||||||
vehicleImage: require('../../images/new/agv.png'),
|
vehicleImage: require('../../images/new/agv.png'),
|
||||||
carMovementEnabled: true,
|
carMovementEnabled: true,
|
||||||
@@ -43,11 +50,15 @@ export default {
|
|||||||
previousTouchY: 0,
|
previousTouchY: 0,
|
||||||
cameraX: 0,
|
cameraX: 0,
|
||||||
cameraY: 0,
|
cameraY: 0,
|
||||||
|
zoomRange: {
|
||||||
|
min: 0.1, // 最小缩放(最多缩小到1/10原尺寸)
|
||||||
|
max: 2 // 最大缩放(最多放大到10倍原尺寸)
|
||||||
|
},
|
||||||
cameraZoom: 1,
|
cameraZoom: 1,
|
||||||
initialPinchDistance: null,
|
initialPinchDistance: null,
|
||||||
initialZoom: null,
|
initialZoom: null,
|
||||||
// UI控制
|
// UI控制
|
||||||
pointSize: 1.5,
|
pointSize: 2,
|
||||||
// WebSocket相关
|
// WebSocket相关
|
||||||
socket: null,
|
socket: null,
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
@@ -125,15 +136,20 @@ export default {
|
|||||||
// 初始化Three.js场景
|
// 初始化Three.js场景
|
||||||
const container = this.$refs.canvasContainer;
|
const container = this.$refs.canvasContainer;
|
||||||
const aspectRatio = container.clientWidth / container.clientHeight;
|
const aspectRatio = container.clientWidth / container.clientHeight;
|
||||||
const pointRange = 1000; // 点云范围 -500 到 500
|
|
||||||
const viewHeight = pointRange;
|
let viewSize = 10; // 默认初始大小
|
||||||
const viewWidth = viewHeight * aspectRatio;
|
if (this.allPoints.length > 0) {
|
||||||
|
const actualRangeX = this.pointCloudRange.maxX - this.pointCloudRange.minX;
|
||||||
|
const actualRangeY = this.pointCloudRange.maxY - this.pointCloudRange.minY;
|
||||||
|
viewSize = Math.max(actualRangeX, actualRangeY) * 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
this.scene = new THREE.Scene();
|
this.scene = new THREE.Scene();
|
||||||
this.camera = new THREE.OrthographicCamera(
|
this.camera = new THREE.OrthographicCamera(
|
||||||
-viewWidth / 2,
|
-viewSize * aspectRatio / 2,
|
||||||
viewWidth / 2,
|
viewSize * aspectRatio / 2,
|
||||||
viewHeight / 2,
|
viewSize / 2,
|
||||||
-viewHeight / 2,
|
-viewSize / 2,
|
||||||
0.1,
|
0.1,
|
||||||
2000
|
2000
|
||||||
);
|
);
|
||||||
@@ -182,10 +198,10 @@ export default {
|
|||||||
});
|
});
|
||||||
this.carMesh = new THREE.Sprite(carMaterial);
|
this.carMesh = new THREE.Sprite(carMaterial);
|
||||||
|
|
||||||
const container = this.$refs.canvasContainer;
|
const actualRangeY = this.pointCloudRange.maxY - this.pointCloudRange.minY;
|
||||||
const containerHeight = container.clientHeight;
|
const carScale = actualRangeY / 5;
|
||||||
const scale = this.carSize / containerHeight * 1000;
|
|
||||||
this.carMesh.scale.set(scale * 1.5, scale * 1.5, 1);
|
this.carMesh.scale.set(carScale * 1.5, carScale * 1.5, 1);
|
||||||
this.carMesh.position.set(this.carPosition.x, this.carPosition.y, 5);
|
this.carMesh.position.set(this.carPosition.x, this.carPosition.y, 5);
|
||||||
this.carMesh.rotation.z = this.carPosition.angle;
|
this.carMesh.rotation.z = this.carPosition.angle;
|
||||||
this.scene.add(this.carMesh);
|
this.scene.add(this.carMesh);
|
||||||
@@ -194,6 +210,13 @@ export default {
|
|||||||
updatePointCloud(points) {
|
updatePointCloud(points) {
|
||||||
if (!points || !Array.isArray(points) || points.length === 0) return;
|
if (!points || !Array.isArray(points) || points.length === 0) return;
|
||||||
|
|
||||||
|
// 计算新点的范围
|
||||||
|
const newRange = this.calculateNewPointsRange(points);
|
||||||
|
|
||||||
|
// 检查是否需要扩展现有范围
|
||||||
|
const rangeExpanded = this.expandPointCloudRange(newRange);
|
||||||
|
|
||||||
|
|
||||||
const pointSet = new Set();
|
const pointSet = new Set();
|
||||||
this.allPoints.forEach(point => {
|
this.allPoints.forEach(point => {
|
||||||
const key = `${point.x},${point.y}`;
|
const key = `${point.x},${point.y}`;
|
||||||
@@ -205,15 +228,93 @@ export default {
|
|||||||
pointSet.add(key);
|
pointSet.add(key);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
if (newUniquePoints.length === 0) return;
|
|
||||||
|
if (newUniquePoints.length === 0 && !rangeExpanded) return;
|
||||||
|
|
||||||
this.allPoints.push(...newUniquePoints);
|
this.allPoints.push(...newUniquePoints);
|
||||||
|
|
||||||
if (this.allPoints.length > this.maxPoints) {
|
if (this.allPoints.length > this.maxPoints) {
|
||||||
this.allPoints.splice(0, this.allPoints.length - this.maxPoints);
|
this.allPoints.splice(0, this.allPoints.length - this.maxPoints);
|
||||||
}
|
}
|
||||||
this.pointCount = this.allPoints.length;
|
this.pointCount = this.allPoints.length;
|
||||||
|
|
||||||
this.updatePointCloudGeometry();
|
this.updatePointCloudGeometry();
|
||||||
|
|
||||||
|
if (rangeExpanded) {
|
||||||
|
this.adjustCameraToNewRange();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 计算新点的范围
|
||||||
|
calculateNewPointsRange(points) {
|
||||||
|
if (!points || points.length === 0) return null;
|
||||||
|
|
||||||
|
let minX = Infinity, maxX = -Infinity;
|
||||||
|
let minY = Infinity, maxY = -Infinity;
|
||||||
|
|
||||||
|
points.forEach(point => {
|
||||||
|
const x = point.x || 0;
|
||||||
|
const y = point.y || 0;
|
||||||
|
|
||||||
|
minX = Math.min(minX, x);
|
||||||
|
maxX = Math.max(maxX, x);
|
||||||
|
minY = Math.min(minY, y);
|
||||||
|
maxY = Math.max(maxY, y);
|
||||||
|
});
|
||||||
|
|
||||||
|
return { minX, maxX, minY, maxY };
|
||||||
|
},
|
||||||
|
|
||||||
|
// 扩展现有范围(如果新点超出了当前范围)
|
||||||
|
expandPointCloudRange(newRange) {
|
||||||
|
if (!newRange) return false;
|
||||||
|
|
||||||
|
let expanded = false;
|
||||||
|
|
||||||
|
// 初始化范围(如果是首次)
|
||||||
|
if (this.allPoints.length === 0) {
|
||||||
|
this.pointCloudRange = { ...newRange };
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查并扩展X范围
|
||||||
|
if (newRange.minX < this.pointCloudRange.minX) {
|
||||||
|
this.pointCloudRange.minX = newRange.minX;
|
||||||
|
expanded = true;
|
||||||
|
}
|
||||||
|
if (newRange.maxX > this.pointCloudRange.maxX) {
|
||||||
|
this.pointCloudRange.maxX = newRange.maxX;
|
||||||
|
expanded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查并扩展Y范围
|
||||||
|
if (newRange.minY < this.pointCloudRange.minY) {
|
||||||
|
this.pointCloudRange.minY = newRange.minY;
|
||||||
|
expanded = true;
|
||||||
|
}
|
||||||
|
if (newRange.maxY > this.pointCloudRange.maxY) {
|
||||||
|
this.pointCloudRange.maxY = newRange.maxY;
|
||||||
|
expanded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return expanded;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增:根据新范围调整相机
|
||||||
|
adjustCameraToNewRange() {
|
||||||
|
// 保持当前相机的缩放比例,但调整视野以适应新范围
|
||||||
|
this.updateRendererSize();
|
||||||
|
|
||||||
|
// 可选:如果希望在范围扩展时自动将新区域纳入视野
|
||||||
|
// 可以计算新的中心点并调整相机位置
|
||||||
|
const centerX = (this.pointCloudRange.minX + this.pointCloudRange.maxX) / 2;
|
||||||
|
const centerY = (this.pointCloudRange.minY + this.pointCloudRange.maxY) / 2;
|
||||||
|
|
||||||
|
// 平滑过渡到新中心(如果需要)
|
||||||
|
this.cameraX = centerX;
|
||||||
|
this.cameraY = centerY;
|
||||||
|
},
|
||||||
|
|
||||||
updatePointCloudGeometry() {
|
updatePointCloudGeometry() {
|
||||||
const positions = new Float32Array(this.pointCount * 3);
|
const positions = new Float32Array(this.pointCount * 3);
|
||||||
|
|
||||||
@@ -279,12 +380,18 @@ export default {
|
|||||||
const width = container.clientWidth;
|
const width = container.clientWidth;
|
||||||
const height = container.clientHeight;
|
const height = container.clientHeight;
|
||||||
const aspectRatio = width / height;
|
const aspectRatio = width / height;
|
||||||
const viewHeight = 1000;
|
|
||||||
const viewWidth = viewHeight * aspectRatio;
|
let viewSize = 10; // 默认大小
|
||||||
this.camera.left = -viewWidth / 2 / this.cameraZoom;
|
if (this.allPoints.length > 0) {
|
||||||
this.camera.right = viewWidth / 2 / this.cameraZoom;
|
const actualRangeX = this.pointCloudRange.maxX - this.pointCloudRange.minX;
|
||||||
this.camera.top = viewHeight / 2 / this.cameraZoom;
|
const actualRangeY = this.pointCloudRange.maxY - this.pointCloudRange.minY;
|
||||||
this.camera.bottom = -viewHeight / 2 / this.cameraZoom;
|
viewSize = Math.max(actualRangeX, actualRangeY) * 1.1; // 增加10%的边距
|
||||||
|
}
|
||||||
|
|
||||||
|
this.camera.left = -viewSize * aspectRatio / 2 / this.cameraZoom;
|
||||||
|
this.camera.right = viewSize * aspectRatio / 2 / this.cameraZoom;
|
||||||
|
this.camera.top = viewSize / 2 / this.cameraZoom;
|
||||||
|
this.camera.bottom = -viewSize / 2 / this.cameraZoom;
|
||||||
this.camera.updateProjectionMatrix();
|
this.camera.updateProjectionMatrix();
|
||||||
this.renderer.setSize(width, height);
|
this.renderer.setSize(width, height);
|
||||||
},
|
},
|
||||||
@@ -315,8 +422,8 @@ export default {
|
|||||||
if (Math.abs(deltaX) < 1 && Math.abs(deltaY) < 1) return;
|
if (Math.abs(deltaX) < 1 && Math.abs(deltaY) < 1) return;
|
||||||
|
|
||||||
// 移动相机(反转方向以获得自然拖动效果)
|
// 移动相机(反转方向以获得自然拖动效果)
|
||||||
this.cameraX -= deltaX * 2 / this.cameraZoom;
|
this.cameraX -= deltaX * 0.3 / this.cameraZoom;
|
||||||
this.cameraY += deltaY * 2 / this.cameraZoom;
|
this.cameraY += deltaY * 0.3 / this.cameraZoom;
|
||||||
|
|
||||||
this.previousTouchX = e.touches[0].clientX;
|
this.previousTouchX = e.touches[0].clientX;
|
||||||
this.previousTouchY = e.touches[0].clientY;
|
this.previousTouchY = e.touches[0].clientY;
|
||||||
@@ -339,12 +446,19 @@ export default {
|
|||||||
this.initialPinchDistance = currentDistance;
|
this.initialPinchDistance = currentDistance;
|
||||||
this.initialZoom = this.cameraZoom;
|
this.initialZoom = this.cameraZoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1. 计算新的缩放比例
|
||||||
|
let newZoom = this.initialZoom * (currentDistance / this.initialPinchDistance);
|
||||||
|
|
||||||
|
// 2. 强制限制在缩放范围内
|
||||||
|
newZoom = Math.max(this.zoomRange.min, Math.min(this.zoomRange.max, newZoom));
|
||||||
|
|
||||||
|
// 3. 更新缩放并刷新视图
|
||||||
|
if (newZoom !== this.cameraZoom) {
|
||||||
|
this.cameraZoom = newZoom;
|
||||||
|
this.updateRendererSize();
|
||||||
|
}
|
||||||
|
|
||||||
// 计算缩放比例
|
|
||||||
const zoomFactor = currentDistance / this.initialPinchDistance;
|
|
||||||
this.cameraZoom = Math.max(0.2, Math.min(5, this.initialZoom * zoomFactor));
|
|
||||||
|
|
||||||
this.updateRendererSize();
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -369,8 +483,8 @@ export default {
|
|||||||
|
|
||||||
if (Math.abs(deltaX) < 1 && Math.abs(deltaY) < 1) return;
|
if (Math.abs(deltaX) < 1 && Math.abs(deltaY) < 1) return;
|
||||||
|
|
||||||
this.cameraX -= deltaX * 2 / this.cameraZoom;
|
this.cameraX -= deltaX * 0.3 / this.cameraZoom;
|
||||||
this.cameraY += deltaY * 2 / this.cameraZoom;
|
this.cameraY += deltaY * 0.3 / this.cameraZoom;
|
||||||
|
|
||||||
this.previousTouchX = e.clientX;
|
this.previousTouchX = e.clientX;
|
||||||
this.previousTouchY = e.clientY;
|
this.previousTouchY = e.clientY;
|
||||||
@@ -388,11 +502,19 @@ export default {
|
|||||||
// 鼠标滚轮缩放
|
// 鼠标滚轮缩放
|
||||||
canvas.addEventListener('wheel', (e)=> {
|
canvas.addEventListener('wheel', (e)=> {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// 优化:减小缩放步长
|
// 1. 计算新的缩放比例(步长保持1.05,即每次滚动缩放5%)
|
||||||
this.cameraZoom = e.deltaY < 0
|
let newZoom = e.deltaY < 0
|
||||||
? Math.min(5, this.cameraZoom * 1.05)
|
? this.cameraZoom * 1.05 // 滚轮向上:放大
|
||||||
: Math.max(0.2, this.cameraZoom / 1.05);
|
: this.cameraZoom / 1.05; // 滚轮向下:缩小
|
||||||
this.updateRendererSize();
|
|
||||||
|
// 2. 强制限制在缩放范围内
|
||||||
|
newZoom = Math.max(this.zoomRange.min, Math.min(this.zoomRange.max, newZoom));
|
||||||
|
|
||||||
|
// 3. 更新缩放并刷新视图
|
||||||
|
if (newZoom !== this.cameraZoom) {
|
||||||
|
this.cameraZoom = newZoom;
|
||||||
|
this.updateRendererSize();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
initWebSocket() {
|
initWebSocket() {
|
||||||
|
|||||||
Reference in New Issue
Block a user