1

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

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

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

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

我试过了

a=a[2][2]

b=b[2][2]

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

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

我已经为此困惑了两天,希望能得到帮助!

谢谢你,安德鲁

4

2 回答 2

1

您可以尝试这种排序方法,是的,它是一个自定义排序功能,但它们很棒。你得到值,在你的情况下是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);
于 2013-03-06T20:42:28.510 回答
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]] + ' *** ');  
}
于 2013-03-06T22:27:39.170 回答