##############################
###  DM2_w23  hu_03_setUp  ###
###  _diag  /  2023 10 20  ###
##############################
import rhinoscriptsyntax as rs
import random, time, sys   ###                                              
#sys.path.append("P:/")     ### add path .. setUp_hu_02.py needed !!!                                              
sys.path.append("P:/WWW/flobber27/dm2")     # path for library !!
import DM_lib as dm        ### reload(dm)    
##############################   

rs.UnitSystem(3)                       
rs.ShowGrid(view=None, show=0)
rs.ShowGridAxes(view=None, show=0)
rs.ViewDisplayMode(view=None, mode="Wireframe")
rs.EnableRedraw(0)
dm.PointRadius(displayModeX=0, rad=3, styl=1)
rs.DeleteObjects(rs.AllObjects())


######################################           
anz = random.choice( range(2**4, 2**8, 4) )
coordsCub = dm.setUp_hu_02( anz )[1]  ### calling def from DM_lib to get *new* set of coords
######################################

randomVec = [random.uniform(-30,30) for i in range(3)]
coordsCub = [rs.VectorRotate(cor, randomVec[0], randomVec) for cor in coordsCub]

siz = rs.Distance( coordsCub[0],  coordsCub[1] )
vecX = rs.VectorSubtract( coordsCub[1],  coordsCub[0] )
vecY = rs.VectorSubtract( coordsCub[-1],  coordsCub[0] )
vecZ = dm.normVec3pnts(coordsCub[0], coordsCub[1], coordsCub[-1]) ### unitVector / length = 1.0
vecZ = rs.VectorScale( vecZ, siz )

ptA = coordsCub[0]
ptB = rs.VectorAdd( ptA, rs.VectorScale( vecX, anz/4) )
ptC = rs.VectorAdd( ptB, rs.VectorScale( vecY, anz/4) )
ptD = rs.VectorAdd( ptC, rs.VectorScale( vecX, -anz/4) )

ptE = rs.VectorAdd( ptA, rs.VectorScale( vecZ, anz/4) )
ptF = rs.VectorAdd( ptB, rs.VectorScale( vecZ, anz/4) )
ptG = rs.VectorAdd( ptC, rs.VectorScale( vecZ, anz/4) )
ptH = rs.VectorAdd( ptD, rs.VectorScale( vecZ, anz/4) )

"""
print "*** anz =", anz
print "*** siz =", round(siz, 2), "/ edge lenght =", round(siz, 2),"*",int(anz/4),"=", round(siz*anz/4, 2)
print "*** **********\n"
"""

### just demo ### just demo  >> remove it <<

if 1: 
    baseCrv = rs.AddCurve( [ptA, ptB, ptC, ptD, ptA], 1 ) 
    topCrv  = rs.AddCurve( [ptE, ptF, ptG, ptH, ptE], 1 ) 
    for i,car in enumerate(["A","B","C","D","E","F","G","H"]):
        rs.AddTextDot( car, [ptA, ptB, ptC, ptD,ptE, ptF, ptG, ptH][i] )

    rs.ZoomExtents()
    dirX = rs.CurveArrows (rs.AddLine(ptA, ptB), 2)
    dirY = rs.CurveArrows (rs.AddLine(ptA, ptD), 2)
    dirZ = rs.CurveArrows (rs.AddLine(ptA, ptE), 2)
    rs.ObjectColor(rs.AllObjects()[2], [200,20,20] )
    rs.ObjectColor(rs.AllObjects()[1], [20,200,20] )
    rs.ObjectColor(rs.AllObjects()[0], [20,20,200] )
    
    coords = rs.DivideCurve(baseCrv, anz, 0)
    coords += rs.DivideCurve(topCrv, anz, 0)
    rs.DeleteObjects( [baseCrv, topCrv] )


if 0:
    cen = dm.pntInbetween(ptA, ptG)
    ran = random.uniform(4,16)
    for i,cor in enumerate(coords):
        vec = rs.VectorSubtract( cor, cen )
        unitVec = rs.VectorUnitize( vec )
        scalVec = rs.VectorScale( unitVec, siz*anz/ran)
        circPnt = rs.VectorAdd( cen, scalVec )
        if i%2==0:
            rs.AddLine( cor, circPnt )
        rs.ObjectColor( rs.AddPoint( circPnt ), [200,20,200] )
    
    coords = []
    for i in range(1001):
        scalVec = rs.VectorRotate( scalVec, random.uniform(-90,90), [random.uniform(-1,1) for i in range(3)])
        coords.append( rs.VectorAdd( cen, scalVec ) )
    rs.AddPoints( coords )

# aus uebung 3

if 0:
    anz = 24
    abstand = rs.Distance(ptA, ptB)/(anz-1)
    vec_x = rs.VectorSubtract(ptB, ptA)
    vec_x = rs.VectorUnitize(vec_x)
    #vec_x = rs.VectorScale(vec_x, abstand)
    
    vec_y = rs.VectorUnitize(rs.VectorSubtract(ptD, ptA))
    vec_z = rs.VectorUnitize(rs.VectorSubtract(ptE, ptA))
    
    
    
    pt_x = rs.VectorAdd(ptA, vec_x)
    #rs.AddPoint(pt_x)
    
    
    cubeGrid = []
    for x in range(anz):
        vec = rs.VectorScale(vec_x, abstand*x)
        pt_x = rs.VectorAdd(ptA, vec)
        #rs.AddPoint(pt_x)
        for y in range(anz):
            pt_y = rs.VectorAdd(pt_x, rs.VectorScale(vec_y, abstand*y))
            #rs.AddPoint(pt_y)
            for z in range(anz):
                pt_z = rs.VectorAdd(pt_y, rs.VectorScale(vec_z, abstand*z))
                #rs.AddPoint(pt_z)
                cubeGrid.append(pt_z)
    
    #rs.AddPoints(cubeGrid)
    
    center = random.choice(cubeGrid)
    radius = random.uniform(rs.Distance(ptA, ptB)*0.25, rs.Distance(ptA, ptB)*0.5)
    
    sphereCoords = []
    
    for cor in cubeGrid:
        if rs.Distance( center, cor ) < radius:
            sphereCoords.append( cor )
            cubeGrid.remove(cor)
    
    #rs.AddPoints(sphereCoords)
    random.shuffle(sphereCoords)
    rs.AddCurve(sphereCoords, 2)
    
    
    for i in range (10001):
        pt0 = random.choice(cubeGrid)
        pt1 = random.choice(cubeGrid)
        if rs.Distance(pt0,pt1) < abstand*5:
            rs.AddCurve([pt0,pt1])

### just demo ### just demo  >> remove it <<

### here we go:



"""
cubelength = rs.Distance(ptA, ptB)
circleshift_0 = 0.2
circleshift_1 = 0.8

cen = dm.pntInbetween(ptA, ptG)

midAE = dm.pntInbetween(ptA, ptE)
midBF = dm.pntInbetween(ptB, ptF)

rs.AddPoint(cen)

vec0 = rs.VectorSubtract(midAE, cen)
vec0 = rs.VectorUnitize(vec0)
vec1 = vec0
vec0 = rs.VectorScale(vec0, cubelength*random.uniform(circleshift_0,circleshift_1))

vec1= rs.VectorScale(vec1, cubelength*random.uniform(circleshift_0,circleshift_1))

vec2 = rs.VectorSubtract(midBF, cen)
vec2 = rs.VectorUnitize(vec2)
vec2 = rs.VectorScale(vec2, cubelength*random.uniform(circleshift_0,circleshift_1))

pt0 = rs.VectorAdd(cen, vec0)
#rs.AddPoint(pt0)

pt1 = rs.VectorSubtract(cen, vec1)
#rs.AddPoint(pt1)

pt2 = rs.VectorAdd(cen, vec2)
#rs.AddPoint(pt2)



midcirc = rs.AddCircle3Pt(pt0, pt1, pt2)

circdots = rs.DivideCurve(midcirc, 50, 0)
#dm.textDots(circdots)


dist_list = []
for cor in circdots:
    dist = rs.Distance(cen, cor)
    dist_list.append([dist, cor])

dist_list.sort()

min_dist = dist_list[0][1]
rs.AddCurve([cen, min_dist])

vec_md = rs.VectorSubtract(min_dist, cen)
vec_midsphere = rs.VectorScale(vec_md, 0.7)

if 1:
    coords = []
    for i in range(1001):
        scalVec = rs.VectorRotate( vec_midsphere, random.uniform(-180,180), [random.uniform(-1,1) for i in range(3)])
        coords.append( rs.VectorAdd( cen, scalVec ) )
    rs.AddPoints( coords )


vec_ran = rs.VectorScale(vec_md, random.uniform(0.1, 0.25))
ran_sat = random.choice(circdots)




if 1:
    coords = []
    for k in range(5):
        ran_sat = random.choice(circdots)
        vec_ran = rs.VectorScale(vec_md, random.uniform(0.1, 0.3))
        sat = []
        for i in range(101):
            scalVec = rs.VectorRotate( vec_ran, random.uniform(-180,180), [random.uniform(-1,1) for i in range(3)])
            sat.append( rs.VectorAdd( ran_sat, scalVec ) )
        coords.append(sat)


for i in range(len(coords)):
    rs.AddPoints( coords[i] )




#rs.AddCurve(coords, 1)

#new_cen = rs.CircleCenterPoint(midcirc)
#rs.AddPoint(new_cen)
"""




anz = 24
abstand = rs.Distance(ptA, ptB)/(anz-1)
vec_x = rs.VectorSubtract(ptB, ptA)
vec_x = rs.VectorUnitize(vec_x)
#vec_x = rs.VectorScale(vec_x, abstand)

vec_y = rs.VectorUnitize(rs.VectorSubtract(ptD, ptA))
vec_z = rs.VectorUnitize(rs.VectorSubtract(ptE, ptA))



pt_x = rs.VectorAdd(ptA, vec_x)
#rs.AddPoint(pt_x)


cubeGrid = []
for x in range(anz):
    vec = rs.VectorScale(vec_x, abstand*x)
    pt_x = rs.VectorAdd(ptA, vec)
    #rs.AddPoint(pt_x)
    for y in range(anz):
        pt_y = rs.VectorAdd(pt_x, rs.VectorScale(vec_y, abstand*y))
        #rs.AddPoint(pt_y)
        for z in range(anz):
            pt_z = rs.VectorAdd(pt_y, rs.VectorScale(vec_z, abstand*z))
            #rs.AddPoint(pt_z)
            cubeGrid.append(pt_z)

#rs.AddPoints(cubeGrid)





# test fuer touching spheres

"""
sphere_list = []

cen_0 = random.choice(cubeGrid)
rad_0 = 2
vec_0 = rs.VectorScale(rs.VectorUnitize(vec_x), rad_0)
sphere_list.append([cen_0, rad_0])


###
sphere0 = []
for i in range(1001):
    spherevec = rs.VectorRotate( vec_0, random.uniform(-180,180), [random.uniform(-1,1) for i in range(3)])
    sphere0.append(rs.VectorAdd(cen_0, spherevec))

new_Grid_0 =[]

for cor in cubeGrid:
    dist = rs.Distance(cen_0, cor)
    if dist > rad_0:
        new_Grid_0.append(cor)


###
sphere1 = []
cen_1 = random.choice(new_Grid_0)
dist_1 = rs.Distance(cen_0, cen_1)
rad_1 = (rs.Distance(cen_0, cen_1) - rad_0)
vec_1 = rs.VectorScale(rs.VectorUnitize(vec_x), rad_1)
sphere_list.append([cen_1, rad_1])


for i in range(1001):
    spherevec = rs.VectorRotate( vec_1, random.uniform(-180,180), [random.uniform(-1,1) for i in range(3)])
    sphere1.append(rs.VectorAdd(cen_1, spherevec))

new_Grid_1 =[]

for cor in new_Grid_0:
    dist = rs.Distance(cen_1, cor)
    if dist > rad_1:
        new_Grid_1.append(cor)




###
sphere2 = []
cen_2 = random.choice(new_Grid_1)


dist_list = []
for i in range(len(sphere_list)):
    dist = rs.Distance(sphere_list[i][0], cen_2)
    dist = dist - sphere_list[i][1]
    dist_list.append(dist)
dist_list.sort()


rad_2 = dist_list[0]
vec_2 = rs.VectorScale(rs.VectorUnitize(vec_x), rad_2)
sphere_list.append([cen_2, rad_2])


#sphere_list.append([cen_2, rad_2])

for i in range(1001):
    spherevec = rs.VectorRotate( vec_2, random.uniform(-180,180), [random.uniform(-1,1) for i in range(3)])
    sphere2.append(rs.VectorAdd(cen_2, spherevec))

new_Grid_2 =[]

for cor in new_Grid_1:
    dist = rs.Distance(cen_2, cor)
    if dist > rad_2:
        new_Grid_2.append(cor)
"""


#rs.AddPoints(new_Grid_2)

#rs.AddPoints(cubeGrid)

#rs.AddPoints(sphere0)
#rs.AddPoints(sphere1)
#rs.AddPoints(sphere2)


### loop ###

# starters #

cen_rad_list = []
sphere_list = []
new_Grid = cubeGrid
inside = []
dist_list = []


#cen = random.choice(cubeGrid)
rad = 2
#vec = rs.VectorScale(rs.VectorUnitize(vec_x), rad)



for i in range(3):
    cen = random.choice(new_Grid)
    
    
    if i > 0:
        for i in range(len(cen_rad_list)):
            dist = rs.Distance(cen_rad_list[i][0], cen)
            dist = dist - cen_rad_list[i][1]
            dist_list.append(dist)
        dist_list.sort()
        rad = dist_list[0]
    
    
    vec = rs.VectorScale(rs.VectorUnitize(vec_x), rad)
    
    
    for j in range(1001):
        spherevec = rs.VectorRotate( vec, random.uniform(-180,180), [random.uniform(-1,1) for i in range(3)])
        sphere_list.append(rs.VectorAdd(cen, spherevec))
    
    
    for cor in new_Grid:
        dist = rs.Distance(cen, cor)
        if dist < rad:
            inside.append(cor)
    
    
    for cor in inside:
        if cor in new_Grid:
            new_Grid.remove(cor)
    
    
    cen_rad_list.append([cen, rad])


#rs.AddPoints(new_Grid)

for i in range(len(cen_rad_list)):
    dm.textDots([cen_rad_list[i][0]], str(i))



rs.AddPoints(sphere_list)






################
rs.ZoomExtents()




