Random Kolam Generator | கோலம் | ముగ్గుల | ರಂಗೋಲಿ

Use the tool below to generate pulli kolam designs of varying size, symmetry, and intricacy.

புதிய புள்ளி கோலம் போட இதைப் பயன்படுத்தலாம் | ముగ్గులు వేయడానికి మీరు దీన్ని ఉపయోగించవచ్చు | ಇದನ್ನು ಬಳಸಿ ರಂಗೋಲಿ ಮಾಡೋಕ್ಕೆ

#HIDDEN
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact

pi=np.pi
rt=2**0.5;

def sqPoints(x0,y0,f):
    return [(x0+f,y0),(x0,y0+f),(x0-f,y0),(x0,y0-f),(x0+f,y0)]

def circlePoints(x0,y0,f):
    rad=f*rt;
    mylist=[]
    for t in range (0,361,6):
        x = x0+ (rad-f)* np.cos(t*pi/180)
        y = y0+ (rad-f)* np.sin(t*pi/180)
        mylist.append((x,y))
    return mylist

def loopPoints (angle, x0, y0, f):
    rad=f*rt;
    mylist = []
    x1=-f
    x2=f
    for t in range (0,361,6):
        if t < 181:
            x = (rad-f)* np.cos(t*pi/180)
            y = (rad-f)* np.sin(t*pi/180)
            mylist.append((x,y))
        else:
            if t>270:
                t1 = ((t-270)/2 + 315)
                x = x1 + rad * np.cos(t1*pi/180)
                y = rad * np.sin(t1*pi/180)
                mylist.append((x,y))
            else:
                t1 = ((t-270)/2 + 225)
                x = x2 + rad * np.cos(t1*pi/180)
                y = rad * np.sin(t1*pi/180)
                mylist.append((x,y))

    s = np.sin(angle*pi/180)
    c = np.cos(angle*pi/180)
    
    mylist = [(i*c - j*s +x0, i*s + j*c +y0) for i,j in mylist]
    return mylist;

def trianglePoints (angle, x0, y0, f):
    rad=f*rt;
    mylist = []
    x1=-f
    for t in range (-45,46,6):
        x = x1 + rad * np.cos(t*pi/180)
        y = rad * np.sin(t*pi/180)
        mylist.append((x,y))
    mylist.append((-f,0))
    mylist.append(mylist[0])
    
    s = np.sin(angle*pi/180)
    c = np.cos(angle*pi/180)
    
    mylist = [(i*c - j*s +x0, i*s + j*c +y0) for i,j in mylist]
    return mylist;

def eyePoints (angle, x0, y0, f):
    rad=f*rt;
    mylist = []
    x1=-f
    for t in range (-45,46,6):
        x = x1 + rad * np.cos(t*pi/180)
        y = rad * np.sin(t*pi/180)
        mylist.append((x,y))
    
    for t in range (135,226,6):
        x = -x1 + rad * np.cos(t*pi/180)
        y = rad * np.sin(t*pi/180)
        mylist.append((x,y))
    
    s = np.sin(angle*pi/180)
    c = np.cos(angle*pi/180)
    
    mylist = [(i*c - j*s +x0, i*s + j*c +y0) for i,j in mylist]
    return mylist;

def cornerPoints (angle, x0, y0, f):
    rad=f*rt;
    mylist = []
    x1=-f
    for t in range (0,361,6):
        if t < 91:
            x = (rad-f)* np.cos(t*pi/180)
            y = (rad-f)* np.sin(t*pi/180)
            mylist.append((x,y))
        else:
            if t>269:
                t1 = ((t-270)/2 + 315)
                x = x1 + rad * np.cos(t1*pi/180)
                y = rad * np.sin(t1*pi/180)
                mylist.append((x,y))
            else:
                if t<181:
                    t1 = ((t-180)/2 + 135)
                    x = rad * np.cos(t1*pi/180)
                    y = x1 + rad * np.sin(t1*pi/180)
                    mylist.append((x,y))

    s = np.sin(angle*pi/180)
    c = np.cos(angle*pi/180)
    
    mylist = [(i*c - j*s +x0, i*s + j*c +y0) for i,j in mylist]
    return mylist;


def drawBox (row, col, top, bottom, left, right):
    numEdges = top + bottom + left + right
    if numEdges == 4:
        #mylist=[(col+.5,row),(col,row+.5),(col-.5,row),(col,row-.5),(col+.5,row)]
        mylist = sqPoints(col, row, 0.5)
    elif numEdges == 3:
        if right == 0:
            angle = 0
        elif left== 0: 
            angle = 180
        elif top == 0:
            angle = 270
        else: 
            angle=90
        mylist = trianglePoints(angle,col, row,0.5)
    elif numEdges == 2:
        if top!= bottom:
            if [top,right]==[1,1]:
                angle=90
            elif [top,left]==[1,1]:
                angle=0
            elif [bottom,left]==[1,1]:
                angle=270
            else:
                angle= 180
            mylist = cornerPoints(angle,col, row,0.5)
        else:
            if top == 1:
                angle = 0
            else:
                angle = 90
            mylist = eyePoints(angle,col, row,0.5)
    elif numEdges == 1:
        if bottom == 1:
            angle = 180
        elif top == 1:
            angle = 0
        elif left == 1:
            angle = 270
        else:
            angle = 90
        mylist = loopPoints(angle,col, row,0.5)
    else:
        mylist=circlePoints(col,row,0.5)
    return mylist

def randomKolam (m,k):
    
    allRows=[]
    allCols=[]
    for i in range(k):
        rowEdges=[]
        colEdges=[]
        for j in range(k+1):
            if j==0 or j==k:
                active=0
                rowEdges.append(active)
            else:
                active = int(np.ceil(np.random.randint(m)/m))
                rowEdges.append(active)
                active = int(np.ceil(np.random.randint(m)/m))
            colEdges.append(active)
        allRows.append(rowEdges)
        allCols.append(colEdges)
    return [allRows, allCols]
def sym180 (m,k):
    
    myDrawing=[]
    allRows=[]
    allCols=[]
    for i in range(int(np.floor(k/2))):
        rowEdges=[]
        colEdges=[]
        for j in range(k+1):
            if j==0 or j==k:
                active=0
                rowEdges.append(active)
            else:
                active = int(np.ceil(np.random.randint(m)/m))
                rowEdges.append(active)
                active = int(np.ceil(np.random.randint(m)/m))
            colEdges.append(active)
        allRows.append(rowEdges)
        allCols.append(colEdges)
    if k % 2 ==1:
        rowEdges=[0]
        colEdges=[0]
        for j in range(int(np.floor(k/2))):
            active = int(np.ceil(np.random.randint(m)/m))
            rowEdges.append(active)
            active = int(np.ceil(np.random.randint(m)/m))
            colEdges.append(active)
        r = rowEdges[::-1]
        c = colEdges[::-1]
        allRows.append(rowEdges+r)
        allCols.append(colEdges+c)
    for i in range(int(np.floor(k/2))):
        ind = int(np.floor(k/2))-i-1
        nextRow=allRows[ind]
        allRows.append(nextRow[::-1])
        nextCol=allCols[ind]
        allCols.append(nextCol[::-1])
    return [allRows, allCols]

def sym90 (m,k):
    
    allRows=[]
    for i in range(int(np.floor(k/2))):
        rowEdges=[]
        for j in range(k+1):
            if j==0 or j==k:
                active=0
            else:
                active = int(np.ceil(np.random.randint(m)/m))
            rowEdges.append(active)
        allRows.append(rowEdges)
    if k % 2 ==1:
        rowEdges=[0]
        for j in range(int(np.floor(k/2))):
            active = int(np.ceil(np.random.randint(m)/m))
            rowEdges.append(active)
        r = rowEdges[::-1]
        allRows.append(rowEdges+r)

    for i in range(int(np.floor(k/2))):
        ind = int(np.floor(k/2))-i-1
        nextRow=allRows[ind]
        allRows.append(nextRow[::-1])
    allCols=allRows[::-1]
    return [allRows, allCols]
        
def diagBoth (m,k):
    
    allRows=[]
    for i in range(int(np.floor(k/2))):
        rowEdges=[]
        for j in range(k+1):
            if j==0 or j==k:
                active=0
            else:
                active = int(np.ceil(np.random.randint(m)/m))
            rowEdges.append(active)
        allRows.append(rowEdges)
    if k % 2 ==1:
        rowEdges=[0]
        for j in range(int(np.floor(k/2))):
            active = int(np.ceil(np.random.randint(m)/m))
            rowEdges.append(active)
        r = rowEdges[::-1]
        allRows.append(rowEdges+r)

    for i in range(int(np.floor(k/2))):
        ind = int(np.floor(k/2))-i-1
        nextRow=allRows[ind]
        allRows.append(nextRow[::-1])
    allCols=allRows
    return [allRows, allCols]

def diagLR (m,k,diagSym):
    ## random kolam w \ (1) or / (0) symmetry, good for 3x3 or 4x4
    
    allRows=[]
    for i in range(k):
        rowEdges=[]
        for j in range(k+1):
            if j==0 or j==k:
                active=0
            else:
                active = int(np.ceil(np.random.randint(m)/m))
            rowEdges.append(active)
        allRows.append(rowEdges)
    allCols=allRows
    if diagSym ==1:
        allCols=[elem[::-1] for elem in allRows[::-1]]
    return [allRows, allCols]

def symXY (m,k,vertSym):
    ## random kolam w vertical (1) or horizontal (0) symmetry, good for 3x3 or 4x4
    
    allRows=[]
    allCols=[]
    for i in range(int(np.ceil(k/2))):
        colEdges=[]
        for j in range(k+1):
            if j==0 or j==k:
                active=0
            else:
                active = int(np.ceil(np.random.randint(m)/m))
            colEdges.append(active)
        allCols.append(colEdges)
    tempRows=[]
    for i in range(k):
        rowEdges=[]
        for j in range(int(np.ceil((k+1)/2))):
            if j==0:
                active=0
            else:
                active = int(np.ceil(np.random.randint(m)/m))
            rowEdges.append(active)
        tempRows.append(rowEdges)

    for i in range(k):
        allRows.append(tempRows[i][0:int(np.ceil(k/2))]+tempRows[i][::-1])

    for i in reversed(range(int(np.floor(k/2)))):
        allCols.append(allCols[i])

    if vertSym==0:
        temp=allCols
        allCols=allRows
        allRows=temp
    return [allRows, allCols]

def symBoth (m,k) :
    
    allRows=[]
    allCols=[]

    tempRows=[]
    tempCols=[]
    for i in range(int(np.ceil(k/2))):
        rowEdges=[]
        colEdges=[]
        for j in range(int(np.ceil((k+1)/2))):
            if j==0:
                activer=0
                activec=0
            else:
                activer = int(np.ceil(np.random.randint(m)/m))
                activec = int(np.ceil(np.random.randint(m)/m))
            rowEdges.append(activer)
            colEdges.append(activec)
        tempRows.append(rowEdges)
        tempCols.append(colEdges)

    for i in range(int(np.ceil(k/2))):
        allRows.append(tempRows[i][0:int(np.ceil(k/2))]+tempRows[i][::-1])
        allCols.append(tempCols[i][0:int(np.ceil(k/2))]+tempCols[i][::-1])

    for i in reversed(range(int(np.floor(k/2)))):
        allCols.append(allCols[i])
        allRows.append(allRows[i])
    return [allRows, allCols]

def symRadial (m,k):
    
    allRows=[]
    tempRows=[]
    for i in range(int(np.ceil(k/2))):
        rowEdges=[]
        for j in range(int(np.ceil((k+1)/2))):
            if j==0:
                active=0
            else:
                active = int(np.ceil(np.random.randint(m)/m))
            rowEdges.append(active)
        tempRows.append(rowEdges)
    for i in range(int(np.ceil(k/2))):
        allRows.append(tempRows[i][0:int(np.ceil(k/2))]+tempRows[i][::-1])

    for i in range(int(np.floor(k/2))):
        ind = int(np.floor(k/2))-i-1
        nextRow=allRows[ind]
        allRows.append(nextRow[::-1])
    allCols=allRows
    return [allRows, allCols]

def edgesToDrawing (k,allRows,allCols):
    myDrawing = []
    for r in range(k):
        for c in range(k):
                #print(r,c,allRows[r][c]+allRows[r][c+1]+allCols[c][r]+allCols[c][r+1])
                row = r
                col = c
                left = allRows[r][c]
                right = allRows[r][c+1]
                top = allCols[c][r]
                bottom = allCols[c][r+1]
                myDrawing.append(drawBox(row, col, top, bottom, left, right))
    return myDrawing

def drawKolam(Symmetry,Randomness,GridSize):
    symmetry= Symmetry
    m=Randomness
    k=GridSize
    if symmetry=="Radial":
        [allRows,allCols]=symRadial (m,k)
    if symmetry=="Diagonal":
        [allRows,allCols]=diagBoth (m,k)
    elif symmetry=="Square":
        [allRows,allCols]=symBoth (m,k)
    elif symmetry=="180 Degree":
        [allRows,allCols]=sym180 (m,k)
    elif symmetry=="90 Degree":
        [allRows,allCols]=sym90 (m,k)
    elif symmetry=="Vertical":
        [allRows,allCols]=symXY (m,k,1)
    elif symmetry=="Horizontal":
        [allRows,allCols]=symXY (m,k,0)
    elif symmetry=="Diagonal Up":
        [allRows,allCols]=diagLR (m,k,0)
    elif symmetry=="Diagonal Down":
        [allRows,allCols]=diagLR (m,k,1)
    myDrawing = edgesToDrawing(k,allRows,allCols)
    for val in myDrawing:
        plt.plot([ i for i, j in val ], 
           [ j for i, j in val ],'maroon')

    for i in range(k):
        for j in range(k):
            plt.plot(i,j,'.',c='black',markersize=20-1.5*k)#0.3*(13-k)**2
    plt.axis('square')
    plt.axis('off')
    plt.show()

interact(drawKolam, 
         Symmetry= ['Radial','90 Degree','180 Degree','Diagonal','Square',
                    'Vertical','Horizontal','Diagonal Up','Diagonal Down'],
         Randomness=(2,9,1),
         GridSize=(3, 10, 1));