I’d like to pose a challenge to the Dynamo community:
Using only native dynamo nodes, create an “isovist” function that accepts the following inputs:
a Point representing the viewpoint
a list of 2d curves representing any possible obstructions
a number N representing the number of sample points
a number R representing the maximum vision radius
and returns a polycurve by points representing the visible polygon from the viewpoint:
The resulting polygon should terminate at the circle of the maximum radius if it doesn’t hit any obstructions before that:
I have solved this for myself, but I am eager to see how others might approach it more cleanly / elegantly. My approach
required quite a bit of list@level trickery + lacing etc. I’m happy to share my script once we have a diversity of solutions I’d like to privilege node-based solutions over designscript-based ones - but if someone has a particularly beautiful way of accomplishing this with DS that would be great to see as well.
My ulterior motive here is that I will be teaching a course on dynamo list management at AU UK - I’d like to use this particular problem as a case study in the kinds of list management issues that arise in the course of building more sophisticated scripts. Anyone whose solution I use in my lab will of course get a shout out!
So - gauntlet thrown show me your stuff Dynamaniacs!
What determines the direction of the vision radius (its bisector, I suppose)?
You show an exterior rectangle; I take it these elements are the simply part of the list of 2D curves, or do you always assume the view is contained, i.e. are the external bounds a constant and not part of the 2D curve input?
Non-linear obstructions or only linear?
You mention sample points; what if the solution doesn’t need them…still a requirement?
Thanks, and can you post a screenshot showing a bspline obstruction or even a circle (basically any obstruction that turns in on itself) to gauge the flexibility of what you’ve done (and to set the bar)
The point is less about accomplishing the specific task at hand - this problem is representative of the kinds of complexity that arise in visual programming day-to-day, and it’s an easy one to describe. My intent is to use this problem to explore various strategies of list management in the dynamo environment. It really shouldn’t be a crazy thing to tackle in visual programming. In Grasshopper it’s not even that complicated to set up:
I guess it depends on which side of the fence you sit; coding ultimately trumps visual programming but its a catch-22 - what I like to call the “coding-paradox” - where problems, especially complex ones or ones dealing with complex data structures, get a lot easier when you code…the problem is, you need to know how to code! Interesting idea and GH solution!
@Andrew_Heumann so there are some differences in how Grasshopper handles data trees vs. how Dynamo handles lists, but for the most part one can achieve the same result with either. The only major differences usually happen when Geometry gets involved and Dynamo just plain sucks at most of the geometrical operations. Anyways, here’s the same thing with just OOTB nodes.
Now, List.Map makes a comeback here since Dynamo’s List.Flatten node only works on Levels from Left>Right while Shift Paths in Grasshopper works in the opposite directions pruning branches from the outside>in.
Other than that I had to “clean” the list from Null values as Dynamo’s Polycurve would not take a null, unlike Grasshopper which does so pretty easily. Feeding this into Grasshopper Polyline is fine:
While Dynamo would crap itself when met with a null value so I had to remove them:
These are two ONLY differences in the first approach that you demonstrated and as you can see they are more of “Dynamo is sensitive to nulls” nature than anything else.
Here’s the whole thing:
Result:
Ps. Adding PruneDuplicates also removes extra points for better result:
Nice job all! Appreciate the cleverness and range of approaches. @Zach_Kron’s is closest to my approach - I did almost the same except I sorted by distance to the center rather than along the parameter value:
NOW my question is this. What are the options if one wants to take multiple isovists from multiple viewpoints? So far I can see how to do this with a DS function like the above, passing it a list of points for the viewpoint argument - or with List.Map on a custom node. Is there a way that leverages only List@Level / Lacing as the management mechanism? I was unable to figure one out.
Accessibility (size and height of access openings, pathways, corridors, etc) and way-finding are another possibility, tho you might need to make things 3d first.
@Andrew_Heumann another interesting extension of your challenge would be to implement an optimisation algorithm, like a goal-seek (or even ML if appropriate) so a really coarse sample rate could be used to start, and increase the rate only where hits are found. It would mean that the effective rate of sampling could be increased exponentially, without any noticeable impact on performance compared to evenly distributed sampling.