designcoding
About Table of Contents Keywords Monthly Archive
Support designcoding!

Minimum Spanning Tree

April 26, 2012 | Algorithms
#computational-geometry #grasshopper #vbnet

This is the updated version of my MST code from 2012. After over a hundred hours of Rhinocommon and Grasshopper SDK studies, and lots of dead ends, I was finally able to calculate the minimum spanning tree of any given curve network in Grasshopper. Problems like these are interesting to me because of their clear logic and diverse areas of applications in design. I tried to simulate Dijkstra’s, Kruskal’s, and Prim’s algorithms, but no chance. There are similar solutions such as Shortest Walk and SpiderWeb which are much more faster and professional than mine. I chose a reverse-delete algorithm. The logic is simple: take the longest connection in the set. Then, see if you delete the connection, and whether the two nodes are still connected or not. If deleting that connection does not remove the two nodes, then delete it and continue from the next longest connection.

Minimum Spanning Tree animation

This Grasshopper definition includes one component written in VB.net language and it generates the Minimum Spanning Tree of a given curve network (a list of connected lines) in 2D and 3D. I added a standard Delaunay Triangulation to test it in the Grasshopper definition. The only input of the code is the list of lines. The outputs are the minimum spanning tree as line objects, and the step-by-step explanation texts of the operation. The code is using native Grasshopper components. Thus, no add-ons are necessary for it to work. This animation visualizes the outcome with a MultiPipe.

Dim i, j As Integer
Dim message As String
Dim count As Integer = lines.Count()
Dim connect As New DataTree (Of Object)
Dim point_list As New List (Of point3d)
For i = 0 To count - 1
	Dim path As New GH_Path(i)
	Dim temp_pointA As point3d
	Dim temp_pointB As point3d
	temp_pointA = lines(i).pointatnormalizedlength(0)
	temp_pointB = lines(i).pointatnormalizedlength(1)
	Dim flag As Boolean = False
	Dim which_point As Integer
	which_point = -1
	For j = 0 To point_list.Count() - 1
		If (point_list(j) = temp_pointA) Then
			flag = True
			which_point = j
		End If
	Next
	If (flag = True) Then
		connect.insert(which_point, path, 0)
	End If
	If (flag = False) Then
		point_list.add(temp_pointA)
		connect.insert(point_list.count() - 1, path, 0)
	End If
	which_point = -1
	flag = False
	For j = 0 To point_list.Count() - 1
		If (point_list(j) = temp_pointB) Then
			flag = True
			which_point = j
		End If
	Next
	If (flag = True) Then
		connect.insert(which_point, path, 1)
	End If
	If (flag = False) Then
		point_list.add(temp_pointB)
		connect.insert(point_list.count() - 1, path, 1)
	End If
	connect.insert(temp_pointA.distanceto(temp_pointB), path, 2)
	connect.insert("unchecked", path, 3)
Next

Dim mspt As DataTree (Of Object)
mspt = connect

Dim maxlen As Double
Dim maxidx As Integer

For j = 0 To mspt.branchcount() - 1
	maxlen = 0
	maxidx = 0
	message = "*** Started iteration # " + System.Convert.ToString(j)
	Print(message)

	For i = 0 To mspt.branchcount() - 1
		If (mspt.branch(i).item(2) > maxlen) And (mspt.branch(i).item(3) = "unchecked") Then
			maxlen = mspt.branch(i).item(2)
			maxidx = i
		End If
	Next
	message = "Longest edge is " + System.Convert.ToString(maxlen) + " at connection " + System.Convert.ToString(maxidx)
	Print(message)
	Dim temp_indexA As Integer
	Dim temp_indexB As Integer
	temp_indexA = mspt.branch(maxidx).item(0)
	temp_indexB = mspt.branch(maxidx).item(1)

	message = "Nodes of this connection are " + System.Convert.ToString(temp_indexA) + " and " + System.Convert.ToString(temp_indexB)
	Print(message)

	Dim temp_resultA, temp_resultB As Boolean
	temp_resultA = isConnected(mspt, temp_indexA, point_list.count(), maxidx)
	If (temp_resultA = True)
		message = "Deleting connection " + System.Convert.ToString(maxidx) + " did not break connectivity of node " + System.Convert.ToString(temp_indexA)
	Else
		message = "Deleting connection " + System.Convert.ToString(maxidx) + " DID break connectivity of node " + System.Convert.ToString(temp_indexA)
	End If
	Print(message)

	temp_resultB = isConnected(mspt, temp_indexB, point_list.count(), maxidx)
	If (temp_resultB = True)
		message = "Deleting connection " + System.Convert.ToString(maxidx) + " did not break connectivity of node " + System.Convert.ToString(temp_indexB)
	Else
		message = "Deleting connection " + System.Convert.ToString(maxidx) + " DID break connectivity of node " + System.Convert.ToString(temp_indexB)
	End If
	Print(message)

	If (temp_resultA = True) And (temp_resultB = True) Then
		message = "Therefore, connection " + System.Convert.ToString(maxidx) + " is deleted from the graph"
		Print(message)
		mspt.branch(maxidx).item(3) = "deleted"
	Else
		message = "Connection " + System.Convert.ToString(maxidx) + " is important and remained"
		mspt.branch(maxidx).item(3) = "approved"
	End If

Next

Dim length As Double = 0

Dim finale As New List (Of line)
For i = 0 To mspt.branchcount() - 1
	If (mspt.branch(i).item(3) = "approved") Then
		finale.add(New Rhino.Geometry.Line(point_list(mspt.branch(i).item(0)), point_list(mspt.branch(i).item(1))))
		length = length + (point_list(mspt.branch(i).item(0)).distanceto(point_list(mspt.branch(i).item(1))))
	End If
Next

conn = finale
node = point_list
mst = mspt

message = "Found minimum spanning tree of " + System.Convert.ToString(point_list.count()) + " points, at total length of " + System.Convert.ToString(length)
Print(message)
Minimum Spanning Tree Grasshopper definition
Minimum Spanning Tree computational-geometry, grasshopper
Grasshopper definition (GH)Download

Cite this post

Yazar, T. (2012, April 26). Minimum Spanning Tree. designcoding. Retrieved August 24, 2026, from https://www.designcoding.net/minimum-spanning-tree/

Related Posts

Shortest Path Generator

April 30, 2012

This is the continuation of my scripting experiment within Grasshopper. Like the minimum spanning tree algorithm, this is also a famous problem of computational geometry; the shortest path problem. I’m now coding faster and understanding the namespace more easily in Grasshopper. This time, the challenge was implementing Dijkstra’s algorithm for the Shortest Path Generator. Again, it’s a quite powerful algorithm, I even plan to use it in my current project. Although there is a faster alternative, Shortest Walk-in Food4Rhino and it…

Tattoo Design

April 27, 2023

Here is a tattoo design I am currently developing by using Grasshopper. 11 years ago, I developed a Grasshopper definition that approximates Julia Sets here. One of the experimental outputs of that definition looks suitable for a tattoo design. It is a beautiful fractal shape. But I am not perfectly sure about its suitability for a tattoo. Here it is: This was generated by the function z2+c and the parameters were: 0.3+0.49i with 25 iterations. I experimented a bit more…

Fractal Trees

April 11, 2015

Based on this post, the problem of modeling tree-like fractal shapes is still a good question for the early years of computational design education. Last time, I used Rhino’s macro to study these fractal trees in an “impossibly” limited interface. But this time I used a VB.NET script. Here is the code inside of the VB.net component: Here are the inputs. x is the number of iterations. The Crv input is a line needed for the first iteration. t represents how…

Camera Animation

April 28, 2014

Here is the simple Grasshopper definition that activates Rhinoceros’ camera by given parameters. Camera position is determined by the “point-oriented” method here. This means that you have to have a target point for the camera first. In fact, I was trying to find a suitable command for getting the actual camera position of the Rhinoceros but I think it is impossible (for now). I couldn’t track the camera object by its ID number also. There are some Grasshopper components that deal with…

Regenerating Random Numbers

January 2, 2013

Just a quick tip as I thought might be useful in some cases. Generating random numbers in architectural scripting is not a too catchy thing for designers. It is for sure, we want every parameter to be under our control (as if it were possible!). I was thinking about that in Grasshopper. A dataflow graph such as in Grasshopper regenerates whenever necessary (a change on an input value “fires” every connected component), therefore random number component requires your action (for…

  • Chapters

    • Algorithms
    • Discourses
    • Fabrications
    • Studios
  • Explore

    • All Keywords
    • Table of Contents
    • Monthly Archive
    • #rhino-python
    • #polyhedra
    • #parametric-surface
    • #robot
    • #tessellation
    • #boolean
    • #kuka-prc
    • #dome
    • #design-object
    • #image-sampler
    • #terrain
    • #sandblasting
    • #stone
    • #parametric-curve
    • #animation
    • #cycloid
    • #art
    • #simulation
    • #aperiodic
    • #tiling
  • Search

  • Support designcoding!

  • Enjoying designcoding? Support me on Patreon to keep it growing. Thank you!

  • copyright 2026 designcoding.net | about | privacy policy | end user license agreement