// Last edited on 2013-02-01 20:03:55 by stolfilocal
    
#macro lamp_array(nrings,angrad,lux,shd) 
  // A round lamp array with {nrings} rings of lamps,
  // total angular radius {angrad} (degrees), and total strength {lux}.
  // The array is perpendicular to the X axis centered on <1,0,0>.
  // from the origin.
  // If {shd} the lamps cast shadows.

  // Compute normalization factor {st_norm} for ring strengths:
  #local k = 0;  // Light ring index.
  #local st_norm = 0;
  #while (k < nrings)
    #local st = lamp_array_rel_ring_strength(k,nrings);
    #local st_norm = st_norm + st; 
    #local k = k + 1;
  #end
  
  #local coin = seed(4615);
  #local rbulb = 0.25*sin(radians(angrad));
  
  union{
    #local k = 0;  // Light ring index.
    #while (k < nrings)
      // Number of lamps {np} in ring {k} and initial phase {phas}:
      #local np = (k = 0 ? 1 : 6*pow(2,k-1));      // Number of lamps in ring.
      #local phas = (k = 0 ? 0 : 0.6180/np);       // Rel. position of first lamp
      // Total relative strength {st} of lamps in ring:
      #local st = lamp_array_rel_ring_strength(k,nrings);
      // Generate the lamps in the ring:
      #local p = 0; // Lamp index.
      #while (p < np)
        // Jittering terms in {k,p}:
        #local dk = (k = 0 ? 0 : 0.20*(2*rand(coin)-1));
        #local dp = (k = 0 ? 0 : 0.20*(2*rand(coin)-1));
        // Angular radius of ring:
        #local tau = lamp_array_rel_ring_radius(k+dk,nrings); // Relative radius of ring
        #local phi = (k = 0 ? 0 : angrad*tau);  // Angular radius of ring.
        #local tht = 360*(phas + (p+dp)/np); 
        light_source {
          x
          color rgb (st/st_norm/np)*lux*<1.0,1.0,1.0>
          looks_like{ sphere{ 0,rbulb texture{ pigment{ color rgb <1,0,0> } finish{ ambient 1 diffuse 0 } } } } 
          rotate phi*z
          rotate tht*x
          #if (! shd)
            shadowless
          #end
        }
        #debug concat("light at phi = ", str(phi,6,1), " tht = ", str(tht,6,1), "\n")
        #local p = p + 1;
      #end
      #local k = k + 1;
    #end
  }
#end

#macro lamp_array_rel_ring_strength(k,nrings)
  // Relative total strength (unnormalized) of lights in ring {k} of {nrings} rings.
  #local st = (k = 0 ? 0.5*0.5 : 2*k)*((nrings-0.5)*(nrings-0.5) - k*k);
  st
#end

#macro lamp_array_rel_ring_radius(k,nrings)
  // Relative radius of light ring {k} in a lamp cluster with {nrings} rings.
  #local rr = (k = 0 ? 0 : pow(k/(nrings - 0.5),1.5));
  rr
#end