
import rhinoscriptsyntax as rs
import random, time, itertools

rs.UnitSystem(5)                                        
rs.Command("-groundplane Options On=No enter enter", 0) 
rs.ShowGrid(None, 0)
rs.ShowGridAxes(None, 0)
rs.EnableRedraw(0)
rs.DeleteObjects( rs.AllObjects() )




def coords2sphere ( coords, center, radius, makePts=1, makeCrv=0, makeProjectCrv=0 ):
    if center in coords:
        coords.remove( center )
    coordsOnSphere=[]
    for vec in coords:
        cor = vec
        if not rs.Distance( vec, center ):
            continue
        vec = rs.VectorSubtract( vec, center ) 
        vec = rs.VectorUnitize( vec )
        vec = rs.VectorScale( vec, radius )
        vec = rs.VectorAdd( center, vec)
        coordsOnSphere.append( vec )
        if makeProjectCrv==1:
            rs.AddLine( center, vec )
        if makeProjectCrv==2:
            rs.AddLine( cor, vec )
    if makePts:
        rs.ObjectColor(rs.AddPoints( coordsOnSphere ), [10,10,10] )
    if makeCrv:
        rs.AddCurve( coordsOnSphere, makeCrv )
    return coordsOnSphere


#hu2, setup, used again
lenX = 10       
lenY = random.randint(lenX, lenX*4)
lenZ = random.randint(lenX, lenX*9)


vecX = [1, 0, 0]
vecY = rs.VectorUnitize([ random.uniform(0,0.5), random.uniform(0.5,1), 0 ])
vecZ = rs.VectorUnitize([ random.uniform(-0.5,0.5), random.uniform(-0.5,0.5), 1 ])

rs.ObjectColor( rs.AddCurve([ [0,0,0], rs.VectorScale(vecX, lenX) ] ), [100,0,0] )
rs.ObjectColor( rs.AddCurve([ [0,0,0], rs.VectorScale(vecY, lenY) ] ), [0,100,0] )
rs.ObjectColor( rs.AddCurve([ [0,0,0], rs.VectorScale(vecZ, lenZ) ] ), [0,0,100] )
rs.AddPoints( [rs.VectorScale(vecX, lenX), rs.VectorScale(vecY, lenY), rs.VectorScale(vecZ, lenZ)] )

#center
centerX = rs.VectorAdd(rs.VectorScale(vecX, lenX*0.5), rs.VectorScale(vecY, lenY*0.5))
centerX = rs.VectorAdd(centerX, rs.VectorScale(vecZ, lenZ*0.5))
radiusX = rs.VectorLength( centerX )*1.0001
rs.AddPoint( centerX )

#rs.AddSphere( centerX, radiusX)
anzAll_0 = len(rs.AllObjects()) # number of objects in scene



if 1:
    crvX = rs.AddCurve([ [0,0,0], rs.VectorScale(vecX, lenX) ] )
    coordsX = rs.DivideCurve( crvX, lenX, create_points=0, return_points=1)  
    coords2sphere ( coordsX, centerX, radiusX, makePts=0, makeCrv=1, makeProjectCrv=2 )
    
    crvY = rs.AddCurve([ [0,0,0], rs.VectorScale(vecY, lenY) ] )
    coordsY = rs.DivideCurve( crvY, lenY, create_points=0, return_points=1)  
    coords2sphere ( coordsY, centerX, radiusX, makePts=0, makeCrv=1, makeProjectCrv=2 )

rs.ZoomExtents()
rs.Redraw()

anzAll_1 = len(rs.AllObjects())     # number of objects in scene
rs.DeleteObjects( rs.AllObjects()[0:anzAll_1 - anzAll_0] )


#here comes my tool4_mercator:



#here comes my para.llel.epiped:


#Points of Base of parallelepiped
A = [0,0,0]                                                                                               
B = rs.VectorScale(vecX, lenX)                                                                            
C = rs.VectorAdd( B, rs.VectorScale(vecY, lenY) )
D = rs.VectorScale(vecY, lenY)

#rs.DeleteObjects( rs.AllObjects() )



#Base of parallelepiped
rs.ObjectColor( rs.AddCurve( [A, B, C, D, A], 1), [0,0,0] )                                       
rs.ObjectColor( rs.AddCurve( [B, rs.VectorAdd(B, rs.VectorScale(vecZ, lenZ))], 1), [0,0,0] )            
rs.ObjectColor( rs.AddCurve( [C, rs.VectorAdd(C, rs.VectorScale(vecZ, lenZ))], 1), [0,0,0] ) 
rs.ObjectColor( rs.AddCurve( [D, rs.VectorAdd(D, rs.VectorScale(vecZ, lenZ))], 1), [0,0,0] ) 


Base =  [ A, B, C, D, A]                                                                    
#random.shuffle( Base)
#rs.AddCurve( Base, 2 )
Top = []                                                                                               
for point in Base:
    Top.append( rs.VectorAdd(point, rs.VectorScale(vecZ, lenZ)) )                                         
#rs.AddCurve( Top, 2 )
rs.ObjectColor( rs.AddCurve( Top, 1 ), [0,0,0] )                                                       
Body = Base + Top        




#Surfaces of Base and XY

for x in range (int (lenX+1)):
    vector_X = rs.VectorScale (vecX, x)
    for y in range (int(lenY+1)):
        vector_Y = rs.VectorAdd(vector_X, rs.VectorScale (vecY, y) )
        for z in range (lenZ+1):
            vector_Z = rs.VectorAdd (vector_Y, rs.VectorScale(vecZ, z))
            point_side_XY_0 = rs.AddPoint(vector_Y)
            rs.ObjectColor( rs.AddPoint(point_side_XY_0), [0,0,0] )                                       

if 0:
    for y in range ( int(lenY+1) ):                                                                      
        vector_Y = rs.VectorScale(vecY, y)                                                                     
        rs.AddPoint(vector_Y)
        for z in range ( int(lenZ+1) ):
          vector_Z = rs.VectorAdd (vector_Y, rs.VectorScale(vecZ, z))

vector_y_plus_z = rs.VectorAdd(vector_Y, vector_Z)
point_sideYZ1 = rs.AddPoint(vector_y_plus_z)                                                          
rs.ObjectColor( point_sideYZ1, [0,0,0] )                                                           



#points on surfaces //// positions according to a formula
if 1:
    listX = []
    listY = []
    k = 1.5
    p_1 = (lenX/1.5)-(2*k)
    p_2 = (lenX/1.5)+(2*k)
    p_3 = (lenY/1.5)-(2*k)
    p_4= (lenY/1.5)+(2*k)
#takes longer with higher numbers so i just used smaller ones

    for x in range ( int(lenX+1) ):
        for y in range( int(lenY+1) ):
            for z in range( int(lenZ+1) ):
                vec = rs.VectorAdd( rs.VectorAdd( rs.VectorScale(vecX, x), rs.VectorScale(vecY, y) ), rs.VectorScale(vecZ, z) )
                if p_1 < x < p_2 and y == 0 and z < lenZ:
                    listY.append(vec)
                if p_3 < y < p_4 and x == 0 and z < lenZ:
                    listX.append(vec)
                if p_1 < x < p_2 and z == 0 and (0 < y < p_3 or p_4 < y < lenY):
                    listX.append(vec)
                if p_1 < x < p_2 and y == lenY and z < lenZ:
                    listY.append(vec)
                if p_3 < y < p_4 and x == lenX and z < lenZ:
                    listX.append(vec)
                if p_1 < x < p_2 and z == lenZ and ((0-1) < y < p_3 or p_4 < y < lenY+1):
                    listX.append(vec)
                if  (0 < x < p_1 or p_2 < x < lenX+1) and z == 0 and p_3 < y < p_4:
                    listY.append(vec)
                if  ((0-1) < x < p_1 or p_2 < x < lenX+1) and z == lenZ and p_3 < y < p_4:
                    listY.append(vec)
    rs.AddPoints(listX)
    rs.AddPoints(listY)



#Sphere in parallelepiped in center
if 1:
    center = rs.VectorAdd(rs.VectorAdd( rs.VectorScale(vecX, lenX),rs.VectorScale(vecY, lenY)),rs.VectorScale(vecZ, lenZ))
    center = rs.VectorScale( rs.VectorUnitize(center), rs.VectorLength(center)*2)
    

    radiusX = lenX*2
    sphCoords = []
    for i in range(500):
        vec = [random.uniform(-6,6),random.uniform(-7,7),random.uniform(-8,8)]
        vec = rs.VectorScale(rs.VectorUnitize(vec), radiusX)
        vec = rs.VectorAdd(vec, center)
        sphCoords.append(vec)



#Lines from Spehere to parallelepiped
if 0:
    for cor in sphCoords:
        pointX = random.choice(listY)
        rs.AddLine( cor, pointX )


#Sphere around parallelepiped
if 1:
    center = rs.VectorAdd(rs.VectorAdd( rs.VectorScale(vecX, lenX),rs.VectorScale(vecY, lenY)),rs.VectorScale(vecZ, lenZ))
    center = rs.VectorScale( rs.VectorUnitize(center), rs.VectorLength(center)*0.5)
    radiusX = random.uniform((lenZ+lenX)/2, (lenZ+lenY)/2)
    coordsProj = coords2sphere ( listX, center, radiusX, makePts=0  , makeCrv=1, makeProjectCrv=2 )


    allPairs = list( itertools.permutations( coordsProj, 2 ) )
    print allPairs[0]

    
    rs.ZoomExtents()
    for i,pair in enumerate(allPairs[0:]):
        if rs.Distance( pair[0],pair[1] ) < 8:
            rs.AddCurve( pair, 1 )
        if i%8500==0:
            rs.Redraw()
            print i
    
def project2spher( new_coords, new_radius, make_line, make_points ):
    coords = []
    for vec in new_coords:
        vec_all = rs.VectorUnitize( vec )
        vec_sph = rs.VectorScale( vec_all, new_radius )
        coords.append( vec_sph )
        if make_points:
            rs.AddPoint( vec_sph )
        if makeLine:
            rs.AddLine( vec, vec_sph )
    print coords
    return coords

rs.ZoomExtents( )


#this was a complicatated task, so i took another ones excercise and tried to play aroud with the script and figure out what does what#