# Joining lines together into a single line

I’ve been working on a GDscript to draw isolines (contours). I’m using the Meandering Triangles algorithm from https://blog.bruce-hill.com/meandering-triangles, and it works pretty well! The problem is I don’t know how to do Step 4, which is where all the little individual lines that make up the contour lines are joined together, so that I have a set of points describing an entire isoline which I can then drop into a Line2D.points.

Bruce wrote his code in Python, which I’ve yet to learn, and I just don’t quite get how the joining works under the hood. That is, I understand the principle—find a segment which touches the current segment, and join them together, then do it again and again—but I don’t understand how the code makes that happen. And thus I haven’t been able figure out how to make it work in GDscript, let alone do so performantly. I feel like I really should do this, as the current implementation, where all the lines are still their own Line2D nodes, creates 3,000-5,000 such nodes. Turning those into, say, a couple dozen Line2Ds really feels like a good idea.

Below is the code the generates the several thousand tiny lines; apologies if I wrote awful code (looking at you, var offset) but I’m only two weeks into GDscript and, as I said, no weeks into Python. cols and rows are defined earlier in the script, and are at present in the 50-100 range. Any help will be greatly appreciated!

func contourDraw(isorange = Vector3(0,0,0), xmin = 0, xmax = cols, ymin = 0, ymax = rows):
var triangles = []
for x in range(xmin, xmax - 1):
for y in range(ymin, ymax - 1):
triangles.append([Vector2(x,y), Vector2(x+1,y), Vector2(x,y+1)])
triangles.append([Vector2(x+1,y), Vector2(x,y+1), Vector2(x+1,y+1)])

var contour_segments = []
for triangle in triangles:
for isocheck in range(isorange.x, floor(isorange.y /isorange.z)):
var isoline = isocheck * isorange.z
var below = []
var above = []
for vertex in triangle:
if matrix[vertex.x][vertex.y].strength < isoline: below.append(vertex)
if matrix[vertex.x][vertex.y].strength >= isoline: above.append(vertex)
if below.size() == 0 or above.size() == 0:
continue

var minority = above if above.size() < below.size() else below
var majority = above if above.size() > below.size() else below

var contour_points = []
var crossed_edges = [[minority[0], majority[0]], [minority[0], majority[1]]]

for triangle_edge in crossed_edges:
var offset = ( ( isoline - matrix[triangle_edge[1].x][triangle_edge[1].y].strength ) / ( matrix[triangle_edge[0].x][triangle_edge[0].y].strength - matrix[triangle_edge[1].x][triangle_edge[1].y].strength ) )
var crossing_point = Vector2(
(offset * triangle_edge[0][0]) + ((1 - offset) * triangle_edge[1][0]),
(offset * triangle_edge[0][1]) + ((1 - offset) * triangle_edge[1][1])
)
contour_points.append(crossing_point * grid_space)
contour_segments.append(contour_points)

var counter = 0
for segment in contour_segments:
var line = Line2D.new()
line.default_color = Color.from_hsv(0.58,0.5,0.5)
line.width = 1
line.antialiased = true
line.points = segment