# 2013 Jan Elias, http://www.fce.vutbr.cz/STM/elias.j/, elias.j@fce.vutbr.cz

"""
Auxiliary functions for polyhedra
"""

from builtins import range
import math,random,doctest,geom,numpy
try: # use psyco if available
import psyco
psyco.full()
except ImportError: pass

# c++ implementations for performance reasons

#**********************************************************************************
[docs]def randomColor(seed=None):
random.seed(seed);
#Return random Vector3 with each component in interval 0...1 (uniform distribution)
return Vector3(random.random(),random.random(),random.random())

#**********************************************************************************
#create polyhedra, one can specify vertices directly, or leave it empty for random shape
"""create polyhedra, one can specify vertices directly, or leave it empty for random shape.

:param Material material: material of new body
:param Vector3 size: size of new body (see Polyhedra docs)
:param float seed: seed for random operations
:param [Vector3] v: list of body vertices (see Polyhedra docs)
"""
b=Body()
random.seed(seed);
b.aspherical = True
if len(v)>0:
b.shape = Polyhedra(v=v)
else:
b.shape = Polyhedra(size = size, seed=random.randint(0,1E6))
if color[0] == -1:
b.shape.color = randomColor(seed=random.randint(0,1E6))
else:
b.shape.color = color
b.mat = material
b.state.mass = b.mat.density*b.shape.GetVolume()
b.state.inertia = b.shape.GetInertia()*b.mat.density
b.state.ori = b.shape.GetOri()
b.state.pos = b.shape.GetCentroid()
if fixed:
b.state.blockedDOFs = 'xyzXYZ'
return b

#**********************************************************************************
#creates polyhedra having N vertices and resembling sphere
"""creates polyhedra having N vertices and resembling sphere

:param int N: number of vertices
:param Material material: material of new body
:param Vector3 center: center of the new body
"""
pts = []

inc = math.pi * (3. - math.sqrt(5.))
off = 2. / float(N)
for k in range(0, N):
y = k * off - 1. + (off / 2.)
r = math.sqrt(1. - y*y)
phi = k * inc

ball = polyhedra(material,v=pts)
ball.state.pos = center
return ball

#**********************************************************************************
pts = []

p = (1.+math.sqrt(5.))/2.
A = [[0.,1.,3.*p],[2.,1.+2.*p,p],[1.,2.+p,2.*p]]
for a in A:
a = [a[0]*f,a[1]*f,a[2]*f]
B = [a,[a[1],a[2],a[0]],[a[2],a[0],a[1]]]
for b in B:
pts.append(b)
if not b[0] == 0:
pts.append([-b[0], b[1], b[2]])
if not b[1] == 0:
pts.append([-b[0],-b[1], b[2]])
if not b[2] == 0: pts.append([-b[0],-b[1],-b[2]])
if not b[2] == 0:
pts.append([-b[0], b[1],-b[2]])
if not b[1] == 0:
pts.append([ b[0],-b[1], b[2]])
if not b[2] == 0:
pts.append([ b[0],-b[1],-b[2]])
if not b[2] == 0: pts.append([ b[0], b[1],-b[2]])
ball = polyhedra(material,v=pts)
ball.state.pos = centre
return ball

#**********************************************************************************
pts = []

c1 = 0.337754
c2 = 1.14261
c3 = 0.621226
A = [[c2,c1,c3],[c1,c3,c2],[c3,c2,c1],[-c1,-c2,-c3],[-c2,-c3,-c1],[-c3,-c1,-c2]]
for a in A:
a = [a[0]*f,a[1]*f,a[2]*f]
pts.append([-a[0],-a[1], a[2]])
pts.append([ a[0],-a[1],-a[2]])
pts.append([-a[0], a[1],-a[2]])
pts.append([ a[0], a[1], a[2]])
ball = polyhedra(material,v=pts)
ball.state.pos = centre
return ball
#**********************************************************************************
#fill box [mincoord, maxcoord] by non-overlaping polyhedrons with random geometry and sizes within the range (uniformly distributed)
"""fill box [mincoord, maxcoord] by non-overlaping polyhedrons with random geometry and sizes within the range (uniformly distributed)
:param Vector3 mincoord: first corner
:param Vector3 maxcoord: second corner
:param Vector3 sizemin: minimal size of bodies
:param Vector3 sizemax: maximal size of bodies
:param Vector3 ratio: scaling ratio
:param float seed: random seed
"""
random.seed(seed);
v = fillBox_cpp(mincoord, maxcoord, sizemin,sizemax,  ratio, random.randint(0,1E6), material)
#lastnan = -1
#for i in range(0,len(v)):
#	if(math.isnan(v[i][0])):
#		lastnan = i

#**********************************************************************************
#fill box [mincoord, maxcoord] by non-overlaping polyhedrons with random geometry and sizes within the range (uniformly distributed)