algorithmic modeling for Rhino
Hi!
I have this interesting script, got here
http://www.parametricmodel.com/
I tried to change to the current VB, but my level does not allow me to do more than change a OnLine to Line, OnCircle to Circle ...
In the file I have the old and the new VB, with indications of where I think the scipt begins to fail.
Someone could take a look?
I would be very grateful.
This is the current script:
Private Sub RunScript(ByVal C As List(Of Circle), ByRef A As Object, ByRef B As Object)
Dim Circle_List As New List(Of Circle)
Circle_List = C
Dim Line_List As New List(Of Line)
Dim arrSide(2) As Double
Dim dblAngle As Double
' define the current center circle
Dim intCurrCenter As Int32 = 0
Dim oCenterCircle As Circle = Circle_List.Item(intCurrCenter)
' locate the second circle
Dim oCurrCircle As Circle
oCurrCircle = Circle_List.Item(1)
Dim delta As New Vector3d (oCenterCircle.radius + oCurrCircle.radius, 0, 0)
oCurrCircle.Translate(delta)
' draw the first line from the center to the second circle
Dim first_Line As New Line(oCenterCircle.center, oCurrCircle.center)
Line_List.add(first_Line)
Dim oBaseCircle As Circle
Dim axis As New Vector3d(0, 0, 1)
' Locate the other circles
For i As int32 = 2 To Circle_List.Count - 1
' a counter is the safety line that can get us out of an infinite loop if necessary
Dim count As int32 = 0
oCurrCircle = Circle_List.Item(i)
'(MY COMMENT) HERE oCurrCircle SHOULD NOT BE IN THE 0, 0, 0. I THINK...
oBaseCircle = Circle_List.Item(i - 1)
REPEAT:
If count > 1000 Then Exit For
' Calculate the length of the sides
arrSide(0) = oCenterCircle.Center.DistanceTo(Circle_List.Item(i).center)
arrSide(1) = oCenterCircle.radius + Circle_List.Item(i).radius
arrSide(2) = oBaseCircle.radius + Circle_List.Item(i).radius
' Calculate Angle
dblAngle = Math.Acos((arrSide(0) ^ 2 + arrSide(1) ^ 2 - arrSide(2) ^ 2) / (2 * arrSide(0) * arrSide(1))) '* 180 / Math.PI
' Update oCircle
Dim newV1 As New Vector3d(oCenterCircle.center.x, oCenterCircle.center.y, 0)
Dim newV2 As New Vector3d(oBaseCircle.center.x, oBaseCircle.center.y, 0)
Dim newV3 As New Vector3d(newV2 - newV1)
newV3.Unitize()
newV3 = newV3 * arrSide(1)
newV3.Rotate(dblAngle, axis)
newV3 = newV3 + newV1
Dim oCenter As New Vector3d(oCurrCircle.Center)
oCurrCircle.Translate(newV3 - oCenter)
' Check for intersection with existing circles
For j As int32 = intCurrCenter + 1 To i - 1
If oCurrCircle.Center.DistanceTo(Circle_List.Item(j).center) + 0.001 < oCurrCircle.radius + Circle_List.Item(j).radius Then
' update the current center circle
oCenterCircle = Circle_List.Item(j)
count = count + 1
GoTo REPEAT
End If
Next
' draw a line to the new center if there are no intersections
Dim oLine As New Line(oCenterCircle.center, oCurrCircle.center)
Line_List.add(oLine)
Next
A = Circle_List
B = Line_List
Tags:
Can someone understand why this script stops working when I changethe dotNet to the current VB?
It probably changes because OnCircle is a class while Circle is a structure. When you get a structure out of a collection, then modify it, it won't change the circle still stored in the collection. You have to put it back specifically.
I didn't get the translation exactly right, but it's something along these lines:
If (C.Count < 2) Then Return
' Declare output collections.
Dim circles As Circle() = C.ToArray()
Dim lines As New List(Of Line)
' Populate collections with first data.
Dim circle0 As Circle = circles(0)
Dim circle1 As Circle = circles(1)
circle1.Translate(New Vector3d(circle0.Radius + circle0.Radius, 0, 0))
circles(1) = circle1 ' Put the modified circle back into the array.
lines.Add(New Line(circle0.Center, circle1.Center))
' Iterate over remaining circles.
For i As Int32 = 2 To circles.Length - 1
Dim pivot As Circle = circles(0)
Dim current As Circle = circles(i)
Dim previous As Circle = circles(i - 1)
Dim chickenInt As Int32 = 0
Do While (chickenInt < 1000)
chickenInt += 1
Dim side0 As Double = pivot.Center.DistanceTo(previous.Center)
Dim side1 As Double = pivot.Radius + current.Radius
Dim side2 As Double = previous.Radius + current.Radius
Dim enumerator As Double = (side0 * side0) + (side1 * side1) - (side2 * side2)
Dim denominator As Double = 2 * side0 * side1
Dim angle As Double = Math.Acos(enumerator / denominator)
' Update current circle.
Dim vector1 As New Vector3d(pivot.Center)
Dim vector2 As New Vector3d(previous.Center)
Dim vector3 As New Vector3d(vector2 - vector1)
vector3.Unitize()
vector3 *= side1
vector3.Rotate(angle, Vector3d.ZAxis)
vector3 += vector1
current.Translate(vector3 - New Vector3d(current.Center))
'circles(i) = current
' Check for intersections
For k As Int32 = 1 To i - 1
Dim distance As Double = current.Center.DistanceTo(circles(k).Center)
Dim radii As Double = current.Radius + circles(k).Radius
If ((distance + 0.001) < radii) Then
pivot = circles(k)
Continue Do
End If
Next
' draw a line to the new center if there are no intersections
Dim line As New Line(pivot.Center, current.Center)
lines.Add(line)
Exit Do
Loop
circles(i) = current ' Put the modified circle back into the array.
Next
A = circles
B = lines
Thanks David, you're wonderful :)
The script still fails sometimes, but it also failed in the original code.
I hope to find a way to fix it.
But the translation seems perfect.
Thank you very much for your time.
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