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
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.
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, majority], [minority, majority]] for triangle_edge in crossed_edges: var offset = ( ( isoline - matrix[triangle_edge.x][triangle_edge.y].strength ) / ( matrix[triangle_edge.x][triangle_edge.y].strength - matrix[triangle_edge.x][triangle_edge.y].strength ) ) var crossing_point = Vector2( (offset * triangle_edge) + ((1 - offset) * triangle_edge), (offset * triangle_edge) + ((1 - offset) * triangle_edge) ) 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 $Contours.add_child(line) counter += 1 print(counter) pass