algorithmic modeling for Rhino

Hi, I am a graduate student in University of Southern California, and I want to ask some questions about using Ladybug and Honeybee. So I need to do some research about how the glaring problem caused by high-reflective and concave skyscraper. I need to simulate the Walkie Talkie building, and I need to pin point the location of the sunrays hitting the ground after being reflected by the facade and spot potential glare areas. And figure out the thermal comfort of the people standing of that point. I saw some discussion given by you about ray tracing , do you have any example file that I can refer to?  Thanks!


Views: 2537

Replies to This Discussion

I never heard of this building but it sounds like a disaster in multiple ways!

Carbuncle Cup: Walkie Talkie wins prize for worst building of the year

It has singed shopfronts, melted cars and caused great gusts of wind to sweep pedestrians off their feet. Now the Walkie Talkie tower, the bulbous comedy villain of London’s skyline, has been bestowed with the Carbuncle Cup by Building Design (BD) magazine for the worst building of the year.

And it's not the only building with the same problem by that architect.

He should know: he has history with death-ray buildings, having designed a hotel in Las Vegas with a similar concave facade that scorched sunbathers’ hair and melted poolside loungers.

Dear Oster,

  Thanks so much for the scripts you provided, and they are very useful for my research. I will refer you at my thesis paper. Thanks again! I am so appreciate!


How about this?  Just GH, no plugins.  The surface is arbitrary - created here in the 'Surface' group.  The yellow lines are the sun rays, all parallel, controlled by the 'Altitude' and 'Azimuth' angles (knobs).  The blue arrows are the surface normal vectors at each point.  The orange lines are the bounced sun rays.

P.S.  Add an integer slider, max 100, to the points array:


This is the same code but better, less confusing configuration of the 'Altitude' and 'Azimuth' knobs.


Hi Lisha,

A good start point would be checking this examples:

Which is the model I used for this video:

I'm not clear what so you mean by Thermal Glare. Do you want to evaluate Visual Glare or thermal comfort? The first one is straight forward to do. For the second one you need to do more work. You might be able to use a modified version of Solar Temperature Adjuster component to calculate MRT and then use that to calculate the thermal comfort. I would open a discussion in Ladybug group ( with a clear description on what you're trying to achieve.

A "heat map"!


  1. For maximum performance adjusting 'Altitude' and 'Azimuth', enable preview of the 'Plane Intersection' points (PLX) and disable the 'Flatten' component, which disables the 'Heat Map'
  2. Enable preview of the 'Bounce Lines'
  3. Enable the 'IntCrv' ("interesting curves?")

Increasing the number of sun rays (the 'Sun Grid' slider) and decreasing the size of the grid cells (the 'grid size' slider) will improve precision but increase computation speed.


I almost hate to admit this but adding this "heat map" effect took most of the day!  It illustrates how much more effort can be involved in a project after producing the initial results, which in this case, didn't take long at all (yesterday's post).

The concept was very simple: find the points where the bounced sun rays intersected "the ground" and color grid cells depending on how many points there are in each one.

At first I tried a hex grid and intersections with hexagonal planar surfaces; failed, despite many variations on this idea.

Then tried intersections with a plane (simple and fast!  See the "Plane Intersection" group) and counting the points within each hexagon ('InCurve(s)' or 'Points In Curve(s)').  Failed!

Then I tried a rectangular array of rectangles (square surfaces), both intersections ('SLX') and 'InCurve(s)' but had a lot of trouble counting the number per cell.

When I finally succeeded, there were two problems:

  1. performance of 'SLX' was poor and
  2. the grid size was static and intersections would be missed when 'Altitude' and 'Azimuth' changed.

So I automated the grid size based on 'Line | Plane' intersections ('PLX') and used 'InCurve' instead of 'SLX'.


WARNING!!!  I discovered a DISASTROUS unintended consequence of automating the grid size based on 'Line | Plane' intersections.  As the 'Altitude' angle is reduced, the plane intersection points spread out WIDELY, causing my laptop to freeze up completely and requiring a power cycle to recover.  Very sorry about that!

When I tried 'Altitude' at ten degrees, the points spread to a grid size of ~17,000 X ~10,000 units or ~170 million cells!  You can see this (safely) by disabling the 'Flatten' component connected to 'PLX'.  But to be safe, I have deleted the GH code attached to my previous post.  If you got a copy, BE CAREFUL!

Clearly this is fatal for 'InCurve' (where I grafted the 170 million curves!), even though the number of intersection points ("sun rays") didn't change.

Not sure how to handle this...  One idea I tried but forgot to mention before was drawing circles around the intersection points and seeing if they overlapped but I couldn't manage to get the info I need to produce a color "heat map".

Too bad...  It looked pretty cool.

OK, this is MUCH BETTER.  Nothing like a better algorithm to improve performance and handle "edge cases" at the same time.

I created a "sparse grid" consisting only of squares where the bounced sun rays intersected the plane.  And avoided using the compute-intensive components 'InCurve' or 'SLX' by counting the number of intersection points in each grid cell, using the 'Map as List (M)' output of the 'CSet' component that I used to create the grid cells.

The result is a huge improvement in response time when changing 'Altitude' and 'Azimuth'.

Then I went one step further and provided an option to drive 'Altitude' and 'Azimuth' from a table of values, available here:

NOTE: I didn't find an easy way to split text on whitespace in GH(?) and did that manually.

Then I animated the slider:


Poor 'Boundary' surface benchmark

Looking at the GH Profiler, I noticed a major performance bottleneck in the 'Boundary' component.  It wasn't obvious until I increased the 'Sun Grid' slider value to 50 and reduced the 'cell size' slider to 0.5.  When the 'Azimuth' angle is changed to 180 +- 90 (dawn or dusk), the points are widely dispersed, reducing the density and increasing the number of cells in the "sparse grid".  Under these conditions, the number of cells was ~2000 and the Profiler time for 'Boundary' went up to a full minute or more each time 'Altitude' or 'Azimuth' was changed.

So I created this code to benchmark some alternatives and found two interesting things:

  1. 'Boundary' surface performance (v.1) is not linear.  As the number of surfaces goes from 1000 to 2000, the time per surface goes up dramatically.
  2. I tried three alternatives for creating a rectangular surface at a given point that are all substantially faster: v.2, v.3 and v.4.  For 2000 points, v.4 is 150 times faster than v.1 !!!

Performance of v.2, v.3 and v.4 are similar and all scale up very well.  To benchmark beyond 2000 points, I recommend disabling the VERY SLOW v.1.  At 5000 points the 'Pop2D' component takes ~11.3 seconds but v.3 and v.4 take less than one second to generate 5000 surfaces!

See attached.

So I replaced the 'Rectangle' and 'Boundary' components in my sun reflection model with v.4 in (also attached) and the performance is amazing.

I'm sure someone has mentioned this performance issue with 'Boundary' on the forum before but as with many things, I didn't realize what a major obstacle it can be until I discovered this for myself.


Better and better!

With no reply from the original poster (Lisha?), I guess I'm tilting at windmills here...  Yet another beautiful but useless piece of code.  Oh well, it's interesting and fun.  I can see several useful clusters coming out of this, including 'Sun Rays', 'Bounce Lines' and the 'Dynamic Sparse Grid' producing 'Heat Map' values.  Two significant improvements today:

  1. 'Absolute' or 'Relative' heat map values.  Until now, the heat map values were relative, meaning there were always some red grid cells, even though they didn't mean the same thing.  Now you choose and calibrate 'Absolute' values, meaning red cells appear only when the maximum density of sun rays is reached.
  2. The grid of sun rays is now square, like the ground plane grid, instead of dividing the surface with the same number of rows and columns, which in this case made the columns closer together than the rows.  The 'Sun Grid' slider now sets a grid cell size, like the 'cell size' slider for the ground plane grid.  In theory, they should be the same but that's not required.

I also added two more surfaces to play with and a switch to reverse surface normal vectors.

The speed is so good that a full day animation takes less time than a single frame did before, even at high resolution (small grid cell sizes).  That's all for now.  Enjoy.



Removed the next performance bottleneck identified by the GH Profiler, 'SubSet' used in the "Splitting list of values" code I borrowed.  Really bad at higher resolution; with cell sizes of 0.125, at dawn and dusk when the intersections are widely dispersed, there are many more "Sparse Grid" cells (~25K).

I was able to get the same result I needed much faster by replacing 'SubSet' and 'Lng' with 'DeDomain', 'A-B' and 'A+B'.  I didn't need to split lists:

There is still room for speed improvement in this very simple task of counting repeated values in a list, a trivial task with a "for loop" in JavaScript or PHP.  I clustered the code, fast enough for now.

More Surfaces

Added a few more sample surfaces to explore, all using the same two vertical curves (parabolas) as edges, some with a straight line connecting their bottom or top ends, some with four identical edges and subtle differences based on 'Sweep' options used to create them.  Very visible in the reflections and focus of the sun rays.

Calibration for 'Absolute' heat map values is done with slider when maximum is expected, like at noon.

Straight edge at top instead of bottom:

Wide Views

Line Bottom, Parabola Top: ("Srf Complex N" sample)

Line Top, Parabola Bottom: ("Flat Top" sample)






  • Add Photos
  • View All


  • Add Videos
  • View All

© 2022   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service