编辑切片副本

时间:2017-04-01 01:13:30

标签: javascript three.js

我正在尝试保存Geometry对象顶点原始坐标的副本。我尝试复制对象的方式是我在stackoverflow上找到了很多答案。

// create a Geometry object from a BufferGeometry
cityGeometry = new THREE.Geometry().fromBufferGeometry( child.geometry );

// properly copy the cityGeometry.vertices array
var originalPositions = cityGeometry.vertices.slice(0);

// change an element of the copy
originalPositions[0].z = 1000;
console.log(originalPositions[0]);
console.log(cityGeometry.vertices[0]);

// now change the original object
cityGeometry.vertices[0].z = 123;
console.log(originalPositions[0]);
console.log(cityGeometry.vertices[0]);

但是,如果我这样做,两个对象总是同时改变。控制台输出显示为:

Vector3 {x: 0.8206260204315186, y: -0.4336470067501068, z: 1000}
Vector3 {x: 0.8206260204315186, y: -0.4336470067501068, z: 1000}
Vector3 {x: 0.8206260204315186, y: -0.4336470067501068, z: 123}
Vector3 {x: 0.8206260204315186, y: -0.4336470067501068, z: 123}

我在这里遗漏了什么吗?谢谢!

3 个答案:

答案 0 :(得分:0)

这里的问题是#include <iostream> #include <string> #include <cstring> #include <cstdlib> using namespace std; int main() { const int SIZE=9000; //max size of c string char numbers[SIZE]; //declare an char array int sum=0; //initialize at 0 cout << "Enter a series of single digit numbers with nothing separating them.\n"; cout << "And I will tell you sum of those single digits\n"; //prompt user cin.getline(numbers,SIZE); //get input //for loop till the end of the string for (int i=0; i<strlen(numbers);i++) { sum+=atoi(numbers); //if i put "atoi(numbers[i]);" then it tells me I //can't convert char to const char* } cout << "The sum of these single digits is "<< sum <<endl; //display result return 0; } 只返回一个数组的浅表副本 - 因此,虽然数组引用本身是不同的,但其中的向量对象实际上是相同的。由于这些Vector3引用是共享的,因此通过复制的数组修改任何向量将意味着这些更改会反映在原始数组中,从而给出了从不复制数组的外观。

您可以使用Array#mapVector3#clone创建Array#slice数组的深层副本:

vertices

完整代码:

var originalPositions = cityGeometry.vertices.map(function (v) { return v.clone() })
// create a Geometry object from a BufferGeometry
cityGeometry = new THREE.Geometry().fromBufferGeometry( child.geometry );

// properly copy the cityGeometry.vertices array
var originalPositions = cityGeometry.vertices.map(function (v) { return v.clone() });

// change an element of the copy
originalPositions[0].z = 1000;
console.log(originalPositions[0]);
console.log(cityGeometry.vertices[0]);

// now change the original object
cityGeometry.vertices[0].z = 123;
console.log(originalPositions[0]);
console.log(cityGeometry.vertices[0]);

答案 1 :(得分:0)

您可以使用:

originalPositions = JSON.parse(JSON.stringify( cityGeometry.vertices ));

as array.slice()只做一个浅拷贝。

答案 2 :(得分:0)

cityGeometry.vertices是一个对象数组,此数组中的每个项都是对象的引用。因此,如果使用slice来复制数组,则新数组中的每个项也都是对象的引用。

var arr1 = [obj1, obj2, obj3];
var arr2 = arr1.slice();

//arr2[0] == arr1[0] === obj1;

它们都指向同一个对象,因此如果修改arr1 [0] .xxx,obj1.xxx将会改变。解决方案是使用深层复制,或者当对象不深时使用Object.assign

var arr1 = [{x:1}, {y:2}, {z:3}];
var arr2 = [];
arr1.forEach(function(item) {
    arr2.push(Object.assign({},item))
});
arr2[0].x = 3;
console.log(arr1[0].x, arr2[0].x);