algorithmic modeling for Rhino
Hi all!
After struggling with data types and getting to know some of the inner workings of the VB script editor in GH, I have a question. For a generative cluster of geometry I want to be able to put in a number of curves, offset them and then make a union of those. This should give me the curve on which the center of the next particle that collides with the cluster lays.
[See attached picture]
Here's my problem. At first I got an awfull lot of error messages due to my inexperience with coding in VB and/or GH. After alle those were taken care of I have two scripts that do the job. I want to be able to do it in one script but I can't get the array of curves into the Curve.CreateBooleanUnion(x). If I set thoses curves as output and as input [hint: curves] in the next VB script, then Curve.CreateBooleanUnion(x) does work.
I guess I'm doing something terribly wrong in stating my variables, but I have no clue how to solve this.
Thanks for taking the time to look at my problem.
Reinier
Script 'offset'
Private Sub RunScript(ByVal x As Curve, ByRef A As Object)
Dim z As array
z = x.Offset(plane.WorldXY, 0.5, 1, 2)
A = z(0)
End Sub
Script 'union'
Private Sub RunScript(ByVal x As List(Of Curve), ByRef A As Object)
A = Curve.CreateBooleanUnion(x)
End Sub
Tags:
Hi Reinier,
are you always dealing with just circles/spheres? Because if you are, it is probably a bad idea to switch to volume/region booleans, as those are incredibly expensive and slow operations compared to working with a list of circles.
As for the code you posted, it's definitely very odd.
Dim z As array
z = x.Offset(plane.WorldXY, 0.5, 1, 2)
A = z(0)
You almost never declare a variable as an "array". You should typically use a actual type with array brackets:
Dim z as Curve()
Secondly, I thought you wanted to operate on multiple curves? The code you posted only takes a single curve as input and outputs the first curve in the offset result. If you want to create a region union of a bunch of offset curves, you need to work on the entire collection from the start:
Private Sub RunScript(ByVal x As List(Of Curve), ByVal offset As Double, ByRef A As Object)
Dim offsets As New List(Of Curve)For Each curve As Curve in x
Dim localOffsets As Curve() = curve.Offset(plane.WorldXY, 0.5, 0.01, CurveOffsetCornerStyle.Round)
offsets.AddRange(localOffsets)
Next
A = Curve.CreateBooleanUnion(offsets)
End Sub
--
David Rutten
david@mcneel.com
Poprad, Slovakia
Thanks alot for the help!
I was affraid the array thing was kind of odd, but it solved some of the problems I had earlier. I tried to go through all the curves in x with indexes but that gave me bad results. Your approach is a much more elegant solution.
The reason I wanted to try this way with the union is that when I get a lot of particles [circles] every timestep every circle has to be checked for collision with all the other particles. That was working up until 5000 particles or so. Since all the particles in the center aren't reachable I was thinking for a way to only having to check the outer edge. This would get updated every time a particle 'landed'.
Maybe my earlier approach of doing the calculation in Matlab and importing the resulting textfile into GH is better for long simulations, but I was curious to see if it was possible to do it all inside GH.
Thanks again for the help, and I'll keep trying, reading the SDK, cursing and eventually get something satisfying :)
Like with so many optimizations, there's a trade-off. It will take a long time to create that boundary curve, but it may still be a good idea if you can then re-use that boundary curve to speed up some other computation. The only way to really make sure is to write both algorithms and see which one is faster.
There are of course other possibilities as well. Solving collisions is a process where the question "which objects are closest to point X?" occurs a lot. So in order to speed up collision testing you need to find a way to answer that question very quickly. Iterating over thousands of objects every time and finding the closest one is called the 'brute force' approach and it gets linearly slower with more objects. I.e. testing 2000 objects for proximity will take twice as long as testing 1000 objects, provided it takes the same amount of time per object.
OcTrees and kd-Trees (and other geometrical tree structures) allow you to speed up these kinds of proximity tests. I implemented an OcTree data structure in Grasshopper that you may be able to use. Have a look at the Grasshopper.Kernel.Geometry namespace. Node2Tree, Node3Tree and Tree(Of T) are of interest here. Node2Tree will allow you to quickly search a collection of 2D points, Node3Tree works on 3D points and Tree(Of T) is the most generic implementation.
This is all pretty complicated stuff so if you're just starting out with programming (or even just starting with VB.NET) you may not want to go down this road.
--
David Rutten
david@mcneel.com
Poprad, Slovakia
Thanks for the lengthy replies, and for thinking with me.
When deciding what the alternate aproaches could be after first simply doing the bruteforce method I came across the Octree algorithm. So I wanted to use the octree in GH, but since I'm doing a generative thing I cannot just use that component. Since the Grasshopper.Kernel.Geometry namespace is not in the GH SDK I wont go into trying to make that work. Espescially with my very limited programming experience that wouldn't be a good idea.
The boundary curve thing is working now, it places a new particle on the intersection of the direction it's traveling and the boundary curve. So now it's a matter of making the actual loop for adding the point to the cloud of points. I also have to think of validating the intersection(s), but that will be a part of the random walk routine.
Thanks for the help, I'll probably be back soon with more 'odd code' :)
Welcome to
Grasshopper
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
© 2024 Created by Scott Davidson. Powered by