## Saturday, February 9, 2013

### Lighting Distribution

I've written a simple Maxima program which uses linear interpolation and lamp luminous intensity data to determine the illuminance on a flat surface (read floor or work surface) caused by several lamps in different locations.  It displays a color contour do show you how the light is distributed.  I could probably tweak some things to get a nicer selection of colors for the color contour but as far as a result which is easy to interpret, this works fine.  Behold:

Never mind the clutter in the bottom left hand corner.  This is just the z-axis numbers written on top of one another because we are looking straight down on the graph.  Small price to pay for the cool result and you can edit the picture afterward if you need something for presentation purposes.  An additional problem I observe is the aspect ratio.  It should look square because my chosen room is square (8' × 8').  Dauntless, I press on.

To implement this program with your own example you need:

• Maxima:  a free computer algebra system.
• Light data
• A room and light configuration.

Light Selection
You need to select a light and find the manufacturer data.  I am using the Cooper RPN3MR-E3MRC.  This is a combination of the light fixture and the lamp in the fixture.  The data you need will indicate how the candle power changes with vertical angle.  The assumed situation is that the light is pointing down.  The vertical angle is measured between the vertical line passing through the center of the light fixture and the line drawn through the center of the fixture to a location on the floor (or incident surface).  This vertical angle affects the "amount of light" (measured in candelas) that is going in that direction.  To input the data for your luminaire-lamp combination you enter it on the line that says "lampData:".  The data is in the form of a list of lists where the nested lists (two items each) represent points.  The pattern for each point in the master list is [angle in degrees, candle power in candelas].  If your data doesn't go all the way to 90 degrees, then put a final point [90, 0] to indicate there will be no light going in that direction.

Considerations in the Calculation
The vertical angle not only affects the "amount of light" in that direction but the angle of incidence with the floor.  We are assuming the light is "facing" the floor.  (The floor is horizontal.  The light is shining straight down onto it, although, of course it "spreads out" as it goes down.)  Remembering that the "angle of incidence" is measured relative to the normal line (perpendicular to the floor), you can see that the angle of incidence is an alternating angle with the vertical angle and therefore equal to it.  An angle of incidence affects how the light "spreads out" across a surface because the same amount of light gets spread out more if the surface is at an angle (not "facing head on") to the beam of light.  Also, not every point of the floor is the same distance away from each light.  As light travels it spreads out in two directions.  If you spread the same amount of anything (sound, light, peanut butter) over a larger area, there isn't as much of it in a given area.  The basic formula is:

$fc = \frac{cp}{d^2}\cos{\theta}$,

where
fc = foot-candles (a measure of illuminance: cd/ft2)
cp = candle power (candelas: cd, same unit in metric and imperial, relates to the Watt)
d = distance (in feet)
θ = angle of incidence (measured from the normal).

The formula is the same if you use metric, but the units change.  Instead of entering feet and getting foot-candles, you enter meters and get lux.  You use the same lamp data which is in candelas.  Candelas are the same in metric and imperial.  To put it very simply:

lux = cd/m2
fc = cd/ft2

Using the Program
If you want metric, enter all distances in m (you will get lux).  If you want imperial, enter all distances in ft (you will get foot-candles).
1. As always, choose a coordinate system and stick to it.  Pick a corner of your room to be (0,0) and one of the sides to be the positive x-axis.
2. Enter the length and width of your room.  I have called these x_length and y_length to avoid misunderstandings based on the usual understanding of width < length.  Just pick a dimension to be the x direction length and one for the y direction length.  Doesn't matter which is set to which.  Just be consistent with step 1.  Sorry, only rectangles.  You're welcome to program something more interesting if you get bored some day.  Or, maybe your room can pretend to be a rectangle?
3. Enter the locations (positions) of your luminaires.  These are in terms of [x, y, z].  I have entered the height of the luminaires for the the z value (12.5 feet).  You could instead enter their height above a work surface (the results would only be correct for the work surface).  Alternatively, you can change the Illum(x,y) function definition to use a z-value of the height of the work surface instead of 0 (same caveat as previous suggestion).

Note:  P2P_Illum() means Point-to-Point Illuminance.  Illum() is the sum of the illuminance contributions of each luminaire to a given point.

Possible Improvements to the Program
1. Change the color selections for the plot.  Perhaps yellow for higher values.  Might be a fiddly thing to get right.
2. Include a more explicit boundary (wall) definition mechanism.  A list of vertices would satisfy the wall definition needs.  But then some programming would need to be done to determine which lights have a line of sight to a given x,y point.  There would also be a need to either crop the end result or indicate some neutral value for places in the plot area but not within the boundaries of the room.
3. Allow the incident surface shape to be specified.
• This might be as simple as allowing inputs of areas at different heights.  This would be the simplest and most widely useful approach.  It would be helpful to indicate the locations of the different surfaces on the plot as well.  It might be necessary to directly use the draw package to do this. [First, load(draw).  Then learn how to use draw.  I haven't looked much into it yet.]
• More complex surface entry would require more complex angle of incidence calculations.  The angle of incidence would not necessarily be equal to the vertical angle.  If the incident surface (or part thereof) was represented as an analytic function of two variables, you could use the partial derivatives to determine the tangent plane and thus the direction of the normal.  Given the direction of the normal and the direction toward a given luminaire, you take the dot product of these (normalized/unit) vectors to get the cosine of the angle of incidence (which is what you need; see formula above).
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 1, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.8177675008773804, "perplexity": 1317.5592046219297}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2018-43/segments/1539583512679.76/warc/CC-MAIN-20181020080138-20181020101638-00197.warc.gz"}