// Shading.  Light source must be a unit vector indicating direction of source.
// Copyright 2007 Bill Gibbons
// License: Creative Commons Attribution 3.0 License
// See http://creativecommons.org/licenses/by/3.0/

function shade_polyhedron(polyhedron, color, light_source) {
  for (var i = 0; i < polyhedron.length; i++) {
    var polygon = polyhedron[i];
    // Compute unit normal vector to polygon.
    var x1 = polygon[1][0] - polygon[0][0];
    var y1 = polygon[1][1] - polygon[0][1];
    var z1 = polygon[1][2] - polygon[0][2];
    var x2 = polygon[2][0] - polygon[1][0];
    var y2 = polygon[2][1] - polygon[1][1];
    var z2 = polygon[2][2] - polygon[1][2];
    var nx = y1*z2 - z1*y2;
    var ny = z1*x2 - x1*z2;
    var nz = x1*y2 - y1*x2;
    var length = Math.sqrt(nx*nx + ny*ny + nz*nz);
    nx /= length;
    ny /= length;
    nz /= length;

    // Compute the distance between the endpoints when the unit direction
    // vectors are both placed at the origin.  Try both directions for the
    // normal vector and use the smallest distance.
    var dsq1 = (nx - light_source[0]) * (nx - light_source[0]) +
               (ny - light_source[1]) * (ny - light_source[1]) +
               (nz - light_source[2]) * (nz - light_source[2]);
    var dsq2 = (-nx - light_source[0]) * (-nx - light_source[0]) +
               (-ny - light_source[1]) * (-ny - light_source[1]) +
               (-nz - light_source[2]) * (-nz - light_source[2]);
    var d = Math.sqrt(Math.min(dsq1, dsq2));

    // Compute cosine of the angle and use it to shade the color.
    var angle = 2 * Math.asin(d/2);
    var factor = Math.cos(angle);
    var red = Math.floor(color[0]*100 +  color[0]*factor*156);
    var green = Math.floor(color[1]*100 +  color[1]*factor*156);
    var blue = Math.floor(color[2]*100 +  color[2]*factor*156);
    polygon.color = "rgb(" + red + "," + green + "," + blue + ")";
  }
}
