Grasshopper

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

Views: 388

Attachments:

Replies to This Discussion

Like this

Attachments:

Hi Naruto! Thanks but the script does something like this!

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.

RSS

About

Translate

Search

Photos

  • Add Photos
  • View All

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service