2D Structured Mesh Generator

This is more of a programming question than a Julia question… I am trying to create a 2D structured mesh generator for an arbitrary domain shape of square elements. There are probably packages available to accomplish this task but I would like to learn how to do it from foundations… it seems like an achievable project.

I want to provide a function with a node step size(1 for now) and an array of n 2D tuples inputs and output an array of node tuples and an array, that I can later enumerate, with m rows(=elements) by 4 columns(=nodes associated to square elements).

I’m brainstorming ways to accomplish this and I feel like there are two directions I can go with it. I could trace the domain unit by unit guided by logic statements or there might be a way to exploit some of set theory functions offered by Julia.

Any recommendations?

This is where I am at least… It feels inefficient and I’d prefer to use immutable variables.

I believe I can define the valid nodes by some set operation between the boundary and an outer mesh. Followed by another trace process for element association… It feels like I’m doubling the operations by not defining elements concurrently with node generation.

A = [(0, 0), (4, 0), (4, 3), (9, 3), (9, 6), (4, 7), (0, 7), (4, 6)]

function testmesh(size::Int64, A::Array{Tuple{Int64,Int64},1})
    #Input validation
    #even number of coordinates per dimension

    #Outer Mesh
    xmax = 0
    xmin = 0
    ymax = 0
    ymin = 0
    for pt in A
        if pt[1] > xmax
            xmax = pt[1]
        end
        if pt[2] > ymax
            ymax = pt[2]
        end
    end
  mesh = [(x,y) for y in ymin:ymax for x in xmin:xmax];
    
    #Border Trace
    surf = Array{Tuple{Int64,Int64},1}(undef, 1)
    B = sort(A, by=x->x[2])
    p = popfirst!(B)
    B = push!(B, p)
    surf[1] = p
    for count in 1:length(B)
        xsgn = B[1][1] - p[1]
        ysgn = B[1][2] - p[2]

        if sign(xsgn) != 0
            for i in 1:abs(xsgn)
                surf = push!(surf, (p[1]+sign(xsgn)*i, B[1][2]))
            end
        end
        if sign(ysgn) != 0
            for i in 1:abs(ysgn)
                surf = push!(surf, (B[1][1], p[2]+sign(ysgn)*i))
            end
        end
        p = popfirst!(B)
    end
    pop!(surf)



    return surf
end