Reputation: 497
I have already read several posts here and on other sites about using a custom sort function on multidimensional arrays but can't work out how to implement them for this case...
I am trying to use the painters algorithm...
face_list[num_face][num_vertex] = [2d_x, 2d_y, z, light_intensity]
How do I write the sort function such that the face_list is sorted by z?
I have tried
a=a[2][2]
b=b[2][2]
For third value of third array but the browser doesn't like it.
The sequence of [num_face] is what I want changed.
I've been puzzling over this for two days now and would appreciate help!
Thank you, Andrew
Upvotes: 1
Views: 1407
Reputation: 19294
This should get you started.
(corresponding jsBin is here : 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]] + ' *** ');
}
Upvotes: 0
Reputation: 7466
You can try this method of sorting, yes it's a custom sort function, but they're great.
You get the values, in your case the z
value, and keeps a list of the indices of each point, then sorts it by 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);
Upvotes: 1