diff --git a/js/isomer.js b/js/isomer.js index 0ff509a..318fd3a 100644 --- a/js/isomer.js +++ b/js/isomer.js @@ -82,6 +82,32 @@ Isomer.prototype.add = function (item, baseColor) { } }; +/** + * Adds an array of {shape: yourShape, color: yourColor} to the scene, + * ordered so that distant faces are displayed first + * */ +Isomer.prototype.addOrdered = function (item) { // array of {shape:, color:} + var Point = Isomer.Point; + var observer = new Point(-10, -10, 10); + var pathList = []; + var index = 0; + + for (var i = 0; i < item.length; i++) { + for(var j = 0 ; j < item[i].shape.paths.length ; j++){ + pathList[index] = { + path: item[i].shape.paths[j], + color: item[i].color + }; + index++; + } + } + pathList.sort(function(pathA, pathB){return (pathA.closerThan(pathB, observer))?1:-1;}); + + for (var i = 0 ; i < pathList.length ; i++) { + this._addPath(pathList[i].path, pathList[i].color); + } +}; + /** * Adds a path to the scene diff --git a/js/path.js b/js/path.js index 3f0f2bc..270cd37 100644 --- a/js/path.js +++ b/js/path.js @@ -88,6 +88,39 @@ }; + /** + * If pathB ("this") is closer from the observer than pathA, it must be drawn after. + * It is closer if one of its vertices and the observer are on the same side of the plane defined by pathA. + */ + Path.prototype.closerThan = function(pathA, observer) { + var i = 0; + // the plane containing pathA is defined by the three points A, B, C + var AB = Vector.fromTwoPoints(pathA.points[0], pathA.points[1]); + var AC = Vector.fromTwoPoints(pathA.points[0], pathA.points[2]); + var n = Vector.crossProduct(AB, AC); + + var OA = Vector.fromTwoPoints(Point.ORIGIN, pathA.points[0]); + var OU = Vector.fromTwoPoints(Point.ORIGIN, observer); //U = user = observer + + // Plane defined by pathA such as ax + by + zc = d + // Here d = nx*x + ny*y + nz*z = n.OA + var d = Vector.dotProduct(n, OA); + + var observerPosition = Vector.dotProduct(n, OU) - d; + + for (i = 0; i < this.points.length; i++) { + var OP = Vector.fromTwoPoints(Point.ORIGIN, this.points[i]); + var pPosition = Vector.dotProduct(n, OP) - d; + if(observerPosition * pPosition > 0){ //same sign = same side + return 1; + } + } + + return 0; + + }; + + /** * Some paths to play with */