我已经在这里和其他网站上阅读了几篇关于在多维数组上使用自定义排序函数的帖子,但是在这种情况下无法解决如何实现它们的问题......
我正在尝试使用画家算法...
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]的顺序是我想要改变的。
我现在已经困惑了两天,并且非常感谢帮助!
谢谢你, 安德鲁
答案 0 :(得分:0)
你可以尝试这种排序方法,是的,它是一个自定义排序功能,但它们很棒。
您获取值z
的值,并保留每个点的索引列表,然后按z
对其进行排序。
// 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]] + ' *** ');
}