plotjuliafractals

Drawing Koch's curve without recursion in Julia


I want to draw a Koch curve in Julia without recursion. My strategy is to divide the given line into three segments using the segPoints function:

function seg_points(startPoint, endPoint, n=3)
        mids = []
        for i in 1:n-1
            push!(mids, i/n * [startPoint[1]+endPoint[1], startPoint[2]+endPoint[2]])
        end
        return mids
    end

Then, the function polygon is used to find the top third point.

function polygon(p1, p2, n=3)
    x = p2[1]-p1[1]
    y = p2[2]-p1[2]
    P3 = p1 + [x * cos(pi/3) - y * sin(pi/3), x * sin(pi/3) + y * cos(pi/3)]
    return P3
end

Finally in the function koch_curve is to draw the fractal:

function koch_curve(order::Int, startPoint = [0.0,0.0], endPoint = [1.0,0.0])
    pts=[startPoint, endPoint]
    for i in 1:order
        order_points =[]
        for j in 2:length(pts)
            a = pts[j-1]
            b = pts[j]
            c, d = seg_points(a, b)
            e = polygon(c, d)
            push!(order_points, c, d, e)
        end
        for pt in order_points
            push!(pts, pt)
        end
    end
    return pts
end

But it doesn't work. The output plot is this with order=5: enter image description here


Solution

  • First thing is the midpoints aren't being computed correctly. A weighted average should be used if you want to find the points that equally divide a segment:

    function seg_points(startPoint, endPoint, n=3)
        mids = []
        for i in 1:n-1
            push!(mids, (1 - i/n) * startPoint + i/n * endPoint)
        end
        return mids
    end
    

    Then you need to push the points in the correct order, since lines are defined by adjacent points:

    function koch_curve(order::Int, startPoint = [0.0,0.0], endPoint = [1.0,0.0])
        pts=[startPoint, endPoint]
        for i in 1:order
            order_points =[]
            for j in 2:length(pts)
                a = pts[j-1]
                b = pts[j]
                c, d = seg_points(a, b)
                e = polygon(c, d)
                # don't push b, since this b = the next loop iter's a:
                push!(order_points, a, c, e, d)
            end
            push!(order_points, pts[end]) # the last b
            pts = order_points
        end
        return pts
    end