我正在研究货物计划应用程序,并希望将货物装载到集装箱中。我正在使用threejs为它创建3d模型。我对threejs完全陌生,到目前为止,我们已经设法创建3d对象(货物)并将它们放在容器(另一个3d对象)中。我面临的问题是,当我彼此添加一个容器内的多个三维物体的那些对象重叠。 我无法计算应设置的正确对象位置,以防止出现此重叠问题。
我刚刚尝试使用基本数学来计算对象位置及其在场景中的位置。
这是js小提琴
https://jsfiddle.net/nro48e6u/1/
用于计算对象位置的逻辑写在仅使用基本数学运算的addCargo函数中。这是它的代码
function addCargo(dimension, color, isPallete) {
var dimensionExceed = false; // boolean value that checksifthe cargo dimensions exceed the containerdimension
if (objects.length == 0) {
var geometry = new THREE.BoxGeometry(dimension.width, dimension.height, dimension.length);
var material = new THREE.MeshBasicMaterial({
color: color
});
cargo = new THREE.Mesh(geometry, material);
wireframe = generateWireframe(geometry);
default_box_position = {
x: container_dimension.width / 2 - dimension.width / 2,
y: dimension.height / 2 - container_dimension.height / 2,
z: container_dimension.length / 2 - dimension.length / 2
}
cargo.position.set(default_box_position.x, default_box_position.y, default_box_position.z);
} else {
var geometry = new THREE.BoxGeometry(dimension.width, dimension.height, dimension.length);
var material = new THREE.MeshBasicMaterial({
color: color,
wireframe: false
});
cargo = new THREE.Mesh(geometry, material);
wireframe = generateWireframe(geometry);
cargo.add(wireframe);
var firstObject = objects[0];
var xUpdated = false;
position = {
x: 0,
y: 0,
z: 0
}
var startIndex = 0;
if (palleteDeimension.isSet) {
position.y = palleteDeimension.height;
startIndex = 1;
}
for (var i = startIndex; i < objects.length; i++) {
if (!xUpdated || i == objects.length - 1) {
position.z += parseFloat(objects[i].geometry.parameters.depth);
xUpdated = false;
} else {
xUpdated = false;
position.z += parseFloat(objects[i].geometry.parameters.depth);
}
if (position.z >= container_dimension.length) {
if (position.z - parseFloat(objects[i].geometry.parameters.depth) + parseFloat(dimension.length) <= container_dimension.length) {
position.z -= parseFloat(objects[i].geometry.parameters.depth);
} else {
position.x += parseFloat(objects[i].geometry.parameters.width);
position.z = 0;
}
} else if (position.z + parseFloat(dimension.length) > container_dimension.length) {
xUpdated = true;
position.x += parseFloat(dimension.width);
position.z = 0;
}
if (position.x >= container_dimension.width) {
position.y += parseFloat(objects[i].geometry.parameters.height);
position.x = 0;
position.z = 0;
} else if (position.x + parseFloat(dimension.width) > container_dimension.width) {
position.y += parseFloat(dimension.height);
position.x = 0;
position.z = 0;
}
}
var z_pos = container_dimension.length / 2 - position.z - (dimension.length / 2);
var y_pos = position.y - container_dimension.height / 2 + (dimension.height / 2);
var x_pos = container_dimension.width / 2 - position.x - (dimension.width / 2);
if (Math.abs(z_pos) <= container_dimension.length / 2 && position.x == 0 && position.y == 0) {
cargo.position.set(default_box_position.x, default_box_position.y, z_pos);
if (firstObject.geometry.parameters.width != dimension.width)
cargo.position.x = x_pos;
if (firstObject.geometry.parameters.height != dimension.height)
cargo.position.y = y_pos;
} else if (Math.abs(y_pos) <= container_dimension.height / 2 && position.x == 0) {
cargo.position.set(default_box_position.x, y_pos, z_pos);
if (firstObject.geometry.parameters.width != dimension.width)
cargo.position.x = x_pos;
} else
cargo.position.set(x_pos, y_pos, z_pos);
}
scene.add(cargo);
objects.push(cargo);
initDragCargo();
}
当我在集装箱内添加多件货物时,货物彼此重叠。我注意到,确定如何摆脱这个重叠的问题。
答案 0 :(得分:0)
您可以尝试一种放松方法,即在无限循环中,每个框都更改一个小位,直到所有框都满意为止。
dx = 0.1;
while(overlap_at_all(boxes)) {
foreach(var box in boxes) {
var overlapping_boxes = get_overlapping_boxes(box, boxes);
foreach(var overlapping_box : overlapping_boxes)
push_away_boxes(box, overlapping_box, dx);
}
}
函数“ get_overlapping_boxes”执行碰撞检测检查,并返回与当前框冲突的框。使用BVH(边界体积层次结构,例如动态ABBB树)或其他一些数据结构可以有效地完成此操作。即使是OctTree也可以取得良好的效果。这同样适用于函数“ overlap_at_all”
函数“ push_away_boxes”仅将两个盒子沿相反方向移动一小段距离dx(相对于盒子的大小,可以说是0.1或10或其他可以认为是“小”的数字)。因此,将“ push_away_boxes”累积应用到给定的一对重叠盒中将最终使它们不重叠。一旦没有更多的重叠框,就达到“收敛”。可以通过增大“ dx”距离来提高收敛速度,但是精度会受到影响,dx越大,性能越好,但以牺牲精度为代价。
现在,不考虑容器盒。我们可以引入它作为约束“ push_away_boxes”函数内部的框的运动。但是,鉴于该约束,无法保证该方法的收敛性。因此,我们可以为循环提供最大的迭代次数,以防止无限循环。此解决方案不能保证找到解决方案。
在我的答案中找不到范围最小的最佳布置。