3维数组排序Javascript

时间:2013-03-06 20:33:26

标签: javascript sorting multidimensional-array

我已经在这里和其他网站上阅读了几篇关于在多维数组上使用自定义排序函数的帖子,但是在这种情况下无法解决如何实现它们的问题......

我正在尝试使用画家算法...

face_list[num_face][num_vertex] = [2d_x, 2d_y, z, light_intensity]

如何编写sort函数,使face_list按z排序?

我试过了

a=a[2][2]

b=b[2][2]

对于第三个数组的第三个值但浏览器不喜欢它。

[num_face]的顺序是我想要改变的。

我现在已经困惑了两天,并且非常感谢帮助!

谢谢你, 安德鲁

2 个答案:

答案 0 :(得分:0)

你可以尝试这种排序方法,是的,它是一个自定义排序功能,但它们很棒。 您获取值z的值,并保留每个点的索引列表,然后按z对其进行排序。

取自:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort#Example.3A_Sorting_maps

// the array to be sorted
var list = ["Delta", "alpha", "CHARLIE", "bravo"];
// temporary holder of position and sort-value
var map = [];
// container for the resulting order
var result = [];

// walk original array to map values and positions
for (var i=0, length = list.length; i < length; i++) {
  map.push({    
    // remember the index within the original array
    index: i, 
    // evaluate the value to sort
    value: list[i].toLowerCase() 
  });
}

// sorting the map containing the reduced values
map.sort(function(a, b) {
  return a.value > b.value ? 1 : -1;
});

// copy values in right order
for (var i=0, length = map.length; i < length; i++) {
  result.push(list[map[i].index]);
}

// print sorted list
print(result);

答案 1 :(得分:0)

这应该让你开始。

(相应的jsBin在这里:http://jsbin.com/olegoj/1/edit

// 3D points array.
var points=[];

var Vector=function(x,y,z) {
  this.x=x;
  this.y=y;
  this.z=z;
};

Vector.prototype.toString= function() {
  return (' x: ' + this.x + ' y: ' + this.y  + ' z : ' + this.z);
};

// returns a new vector translatedfrom ampVec * random 
Vector.prototype.createRandomShift= function(ampVec) {
    var thisRandom = Math.random()*0.9+0.1;
  return  new Vector(
      thisRandom*ampVec.x+this.x,
       thisRandom*ampVec.y+this.y,
        thisRandom*ampVec.z+this.z    );
};

var pointCount=20;

var pt = new Vector(Math.random()*100|0, Math.random()*100|0, Math.random()*100|0 );
var ampVec = new Vector(Math.random()*4-2, Math.random()*4-2, Math.random()*4 - 2);
var ampVecAmp = new Vector(Math.random()*2-1, Math.random()*2-1, Math.random()*2-1) ;

// fill the point array.
// based on the current point shifted randomly by ampVec
// ampVec itself is shifted randomly by ampVecAmp 
for(var i=0; i<pointCount; i++) {
   points.push(pt );
   pt=pt.createRandomShift(ampVec);
   ampVec=ampVec.createRandomShift(ampVecAmp);
}

// array of face. a face is an array of 3 point indexes.
var facelist=[];

var faceCount=10, i=faceCount;

// fill the face array
while(i--) {
    var thisFacePoints=[];
    var ip1 = 0;
    // 3 point indexes
    thisFacePoints.push(ip1=Math.random()*pointCount|0);
    thisFacePoints.push(Math.random()*pointCount|0);
    thisFacePoints.push(Math.random()*pointCount|0);
    facelist.push(thisFacePoints);
}

// returns the min z for a face
var minZ=function(f) {
    return Math.min(f[0].z, Math.min(f[1].z, f[2].z));
};

// returns the max z for a face                  
var maxZ=function(f) {
   return Math.max(f[0].z, Math.max(f[1].z, f[2].z));
};

// !!! sort the faces on Z !!!
facelist.sort(function(a,b) {
   if (maxZ(a) < minZ (b)) return 1;  // a fully below b
   if (minZ(b) < minZ(a) ) return -1;  // b fully below a
   // !!!!!!!!!!!!!!!!!!!!!!!!
   // in fact here is the tricky part :
   // here a and b overlap in Z.
  return trickyFaceZSort(a,b); 
 });

 // !!!!!! returns wether face a is < to face b when looking at Z (0,0,1).
//Required : a and b overlaps by Z.
var trickyFaceZSort= function(a,b) {
 // do some checks on projected(xi), projected(yi)  -> return 0 if no overlap
 // then you have the hardest part ahead : x,y and z overlap.
 return 0;
};

// Print sorted faces
for(var i=0; i<facelist.length; i++) {
    var fp=facelist[i];
console.log(' *** face ' + i + ' *** ');
console.log(' ** point 0 ' + points[fp[0]] + ' *** ');
console.log(' ** point 1 ' + points[fp[1]] + ' *** ');
console.log(' ** point 2 ' + points[fp[2]] + ' *** ');  
}