Antares
Spell Reviewer
- Joined
- Dec 13, 2009
- Messages
- 982
I made a number of functions to create various polyhedrons, such as cubes and octahedrons for my map, as well as functions to move and rotate them. Converting these functions into a more general API hasn't been all that much work, so I decided to share these functions, even though the range of application might be not that high, especially given that there are quite a few very obscure ones among them. But who knows - maybe someone somewhere wakes up at 3 in the morning, yelling "Man, if only I could have a deltoidal hexacontahedron in my map."
There are geometric bodies I could add that would be more useful, but given that there are so many that I could do and I don't know if there's demand for them, it's better that if someone needs a specific geometry, he or she requests it and I try to implement a function for it.
The API allows special effects to be added to the vertices of the polyhedrons as well as lightning effects to the edges.
Ideas for applications:
-Creating and animating a rotating ball for a soccer map.
-A spell that sends an energy sphere at the opponent.
-Rotating holograms in a sci-fi map or an alien artifact.
Some of the functions can be cleaned up a bit. If a moderator deems this resource to be useful, I will do so.
Test map attached to this post.
There are geometric bodies I could add that would be more useful, but given that there are so many that I could do and I don't know if there's demand for them, it's better that if someone needs a specific geometry, he or she requests it and I try to implement a function for it.
The API allows special effects to be added to the vertices of the polyhedrons as well as lightning effects to the edges.
Ideas for applications:
-Creating and animating a rotating ball for a soccer map.
-A spell that sends an energy sphere at the opponent.
-Rotating holograms in a sci-fi map or an alien artifact.
Some of the functions can be cleaned up a bit. If a moderator deems this resource to be useful, I will do so.
Test map attached to this post.
vJASS:
library Polyhedron
//============================================================================================
//Polyhedron Constructors by Cyclotrutan
//============================================================================================
globals
constant integer VERTEX_LIMIT = 62 //Reduce if that many vertices are not needed.
constant integer EDGE_LIMIT = 180 //Reduce if that many edges are not needed.
endglobals
//This is a library of functions that construct the vertex coordinatates of various regular
//polyhedra (Platonic, Archimedean, and Catalan solids). The API provides the ability to add
//special effects at the vertex positions, as well as functions to move and rotate the
//polyhedron.
//============================================================================================
//To create a new polyhedron, call
//polyhedron.create(x,y,z,whichPolyhedron,edgeLength,vertexEffect,effectZoffset,effectScale,rotationSpeed,precessionSpeed)
//x,y,z: The map coordinates where the polyhedron is created.
//whichPolyhedron determines which polyhedron type is created. Valid input arguments are:
//"tetrahedron" https://en.wikipedia.org/wiki/Tetrahedron
//"octahedron" https://en.wikipedia.org/wiki/Octahedron
//"cube" https://en.wikipedia.org/wiki/Cube
//"cuboctahedron" https://en.wikipedia.org/wiki/Cuboctahedron
//"tetrakishexahedron" https://en.wikipedia.org/wiki/Tetrakis_hexahedron
//"snubcube" https://en.wikipedia.org/wiki/Snub_cube
//"triacontahedron" https://en.wikipedia.org/wiki/Rhombic_triacontahedron
//"snubdodecahedron" https://en.wikipedia.org/wiki/Snub_dodecahedron
//"disdyakistriacontahedron" https://en.wikipedia.org/wiki/Disdyakis_triacontahedron
//"deltoidalhexacontahedron" https://en.wikipedia.org/wiki/Deltoidal_hexecontahedron
//edgeLength determines the length of the polyhedron edges and therefore the size of the polyhedron.
//vertexEffect is the path to the special effect that will be visible at each vertex. If vertexEffect
//is an empty string, no special effects will be created.
//effectZoffset is a static shift of each special effect in Z-direction. This will help make the
//rotation look smoother if the special effect is not centered at the origin.
//effectScale is the scale of each special effect.
//rotationSpeed is the angle in radian that the polyhedron will rotate each time .Animate() is called.
//Can be ignored if there's no intention to use .Animate().
//precessionSpeed is the angle in radian that the rotation axis of the polyhedron will precess
//each time .Animate() is called. Can be ignored if there's no intention to use .Animate().
//============================================================================================
//polyhedron.createSimple(x,y,z,whichPolyhedron,edgeLength) creates a polyhedron without attaching
//special effects to it.
//.SetPosition(x,y,z) moves the polyhedron to the coordinates (x,y,z), while leaving the relative
//positions of the vertices unchanged.
//.SetOrientation(phi,theta,rotAngle) will orient the rotation axis of the polyhedron to point
//towards the azimuth angle phi (0 to 2*PI) and the polar angle theta (PI/2 to -PI/2), then rotate
//the polyhedron by the angle rotAngle. Calling this function repeatedly while keeping phi and theta
//constant and changing rotAngle with each call will make the polyhedron rotate around the axis
//defined by phi and theta.
//.Animate() will rotate the polyhedron by the angle defined by rotationSpeed and precess the
//rotation axis by precessionSpeed. Repeatedly calling this function will make the polyhedron
//rotate smoothly around a randomly oriented axis. If you want to have more control over the
//polyhedron animation, use SetOrientation instead.
//.SetScale(whichScale) will scale the polyhedron by the given factor. The new edge length will
//be edgeLength*scale.
//.destroy() will destroy the polyhedron and the associated special effects.
//To change additional attributes of special effects not covered in the API, use this template:
//set A = 0
//loop
// call BlzSetSpecialEffectTimeScale( myPolyhedron.vertexEffect[A] , 0.5 )
// set A = A + 1
//exitwhen A > myPolyhedron.numVertices - 1
//endloop
//.AddLightningEdges(lightningType,cutOffDist) will created lightning effects of the type
//specified by the string "lightningType" and connect each pair of vertices that are cutOffDist
//or less apart. The cutOffDist should be slightly higher than edgeLength. If that doesn't
//produce the desired results, increase or decrease the value until the right vertices are
//connected.
//============================================================================================
//============================================================================================
struct polyhedron
readonly real x //Starting position of polyhedron.
readonly real y
readonly real z
private real array X0[VERTEX_LIMIT] //Starting position of vertices relative to position of polyhedron.
private real array Y0[VERTEX_LIMIT]
private real array Z0[VERTEX_LIMIT]
private real array X[VERTEX_LIMIT] //Current position of vertices relative to position of polyhedron.
private real array Y[VERTEX_LIMIT]
private real array Z[VERTEX_LIMIT]
readonly integer numVertices
effect array vertexEffect[VERTEX_LIMIT]
real effectZoffset
readonly integer numLightnings = 0
lightning array edgeLightning[EDGE_LIMIT]
private integer array lightningOrigin[EDGE_LIMIT]
private integer array lightningEnd[EDGE_LIMIT]
private real rotPhi = 0
private real rotTheta = 0
private real rotAngle = 0
real rotSpeed
real precessionSpeed
real scale = 1
//============================================================================================
//API
//============================================================================================
method SetPosition takes real x, real y, real z returns nothing
local integer A = 0
local integer O
local integer E
set .x = x
set .y = y
set .z = z
loop
exitwhen A > .numVertices - 1
call BlzSetSpecialEffectPosition( .vertexEffect[A] , .x + .X[A] , .y + .Y[A] , .z + .Z[A] + .effectZoffset )
set A = A + 1
endloop
set A = 0
loop
exitwhen A > .numLightnings
set O = .lightningOrigin[A]
set E = .lightningEnd[A]
call MoveLightningEx( .edgeLightning[A] , true , .x + .X[O] , .y +.Y[O] , .z + .Z[O] , .x + .X[E] , .y + .Y[E] , .z + .Z[E] )
set A = A + 1
endloop
endmethod
method SetOrientation takes real phi, real theta, real rotAngle returns nothing
local integer A
local real nx
local real ny
local real nz
local real angle
local real cosAngle
local real sinAngle
local real oneMinCos
local real array M
local real xt
local real yt
local real zt
local integer O
local integer E
set .rotAngle = rotAngle
set .rotPhi = phi
set .rotTheta = theta
if .rotTheta > bj_PI/2 then
set .rotTheta = bj_PI - .rotTheta
set .rotPhi = .rotPhi + bj_PI
elseif .rotTheta < -bj_PI/2 then
set .rotTheta = -bj_PI - .rotTheta
set .rotPhi = .rotPhi + bj_PI
endif
set nx = Cos(.rotPhi)*Cos(.rotTheta)
set ny = Sin(.rotPhi)*Cos(.rotTheta)
set nz = Sin(.rotTheta)
set cosAngle = Cos(.rotAngle)
set sinAngle = Sin(.rotAngle)
set oneMinCos = 1 - cosAngle
set M[1] = nx*nx*oneMinCos + cosAngle
set M[2] = nx*ny*oneMinCos - nz*sinAngle
set M[3] = nx*nz*oneMinCos + ny*sinAngle
set M[4] = ny*nx*oneMinCos + nz*sinAngle
set M[5] = ny*ny*oneMinCos + cosAngle
set M[6] = ny*nz*oneMinCos - nx*sinAngle
set M[7] = nz*nx*oneMinCos - ny*sinAngle
set M[8] = nz*ny*oneMinCos + nx*sinAngle
set M[9] = nz*nz*oneMinCos + cosAngle
set A = 0
loop
exitwhen A > .numVertices - 1
set .X[A] = M[1]*.X0[A] + M[2]*.Y0[A] + M[3]*.Z0[A]
set .Y[A] = M[4]*.X0[A] + M[5]*.Y0[A] + M[6]*.Z0[A]
set .Z[A] = M[7]*.X0[A] + M[8]*.Y0[A] + M[9]*.Z0[A]
call BlzSetSpecialEffectPosition( .vertexEffect[A] , .x + .X[A] , .y + .Y[A] , .z + .Z[A] + .effectZoffset )
set A = A + 1
endloop
set A = 0
loop
exitwhen A > .numLightnings
set O = .lightningOrigin[A]
set E = .lightningEnd[A]
call MoveLightningEx( .edgeLightning[A] , true , .x + .X[O] , .y + .Y[O] , .z + .Z[O] , .x + .X[E] , .y + .Y[E] , .z + .Z[E] )
set A = A + 1
endloop
endmethod
method SetScale takes real whichScale returns nothing
local integer A = 0
local integer O
local integer E
loop
exitwhen A > .numVertices - 1
set .X0[A] = .X0[A]*whichScale/.scale
set .Y0[A] = .Y0[A]*whichScale/.scale
set .Z0[A] = .Z0[A]*whichScale/.scale
set .X[A] = .X[A]*whichScale/.scale
set .Y[A] = .Y[A]*whichScale/.scale
set .Z[A] = .Z[A]*whichScale/.scale
call BlzSetSpecialEffectPosition( .vertexEffect[A] , .x + .X[A] , .y + .Y[A] , .z + .Z[A] )
set A = A + 1
endloop
set .scale = whichScale
set A = 0
loop
exitwhen A > .numLightnings
set O = .lightningOrigin[A]
set E = .lightningEnd[A]
call MoveLightningEx( .edgeLightning[A] , true , .x + .X[O] , .y + .Y[O] , .z + .Z[O] , .x + .X[E] , .y + .Y[E] , .z + .Z[E] )
set A = A + 1
endloop
endmethod
method Animate takes nothing returns nothing
local integer A
local real nx
local real ny
local real nz
local real angle
local real cosAngle
local real sinAngle
local real oneMinCos
local real array M
local real x
local real y
local real z
local real xt
local real yt
local real zt
local integer O
local integer E
set .rotAngle = .rotAngle + .rotSpeed
set .rotPhi = .rotPhi + .precessionSpeed
set .rotTheta = .rotTheta + .precessionSpeed*.rotSpeed
if .rotTheta > bj_PI/2 then
set .rotTheta = bj_PI - .rotTheta
set .rotPhi = .rotPhi + bj_PI
set .precessionSpeed = -.precessionSpeed
set .precessionSpeed = -.precessionSpeed
elseif .rotTheta < -bj_PI/2 then
set .rotTheta = -bj_PI - .rotTheta
set .rotPhi = .rotPhi + bj_PI
set .precessionSpeed = -.precessionSpeed
set .precessionSpeed = -.precessionSpeed
endif
set nx = Cos(.rotPhi)*Cos(.rotTheta)
set ny = Sin(.rotPhi)*Cos(.rotTheta)
set nz = Sin(.rotTheta)
set cosAngle = Cos(.rotAngle)
set sinAngle = Sin(.rotAngle)
set oneMinCos = 1 - cosAngle
set M[1] = nx*nx*oneMinCos + cosAngle
set M[2] = nx*ny*oneMinCos - nz*sinAngle
set M[3] = nx*nz*oneMinCos + ny*sinAngle
set M[4] = ny*nx*oneMinCos + nz*sinAngle
set M[5] = ny*ny*oneMinCos + cosAngle
set M[6] = ny*nz*oneMinCos - nx*sinAngle
set M[7] = nz*nx*oneMinCos - ny*sinAngle
set M[8] = nz*ny*oneMinCos + nx*sinAngle
set M[9] = nz*nz*oneMinCos + cosAngle
set A = 0
loop
exitwhen A > .numVertices - 1
set .X[A] = M[1]*.X0[A] + M[2]*.Y0[A] + M[3]*.Z0[A]
set .Y[A] = M[4]*.X0[A] + M[5]*.Y0[A] + M[6]*.Z0[A]
set .Z[A] = M[7]*.X0[A] + M[8]*.Y0[A] + M[9]*.Z0[A]
call BlzSetSpecialEffectPosition( .vertexEffect[A] , .x + .X[A] , .y + .Y[A] , .z + .Z[A] + .effectZoffset )
set A = A + 1
endloop
set A = 0
loop
exitwhen A > .numLightnings
set O = .lightningOrigin[A]
set E = .lightningEnd[A]
call MoveLightningEx( .edgeLightning[A] , true , .x + .X[O] , .y + .Y[O] , .z + .Z[O] , .x + .X[E] , .y + .Y[E] , .z + .Z[E] )
set A = A + 1
endloop
endmethod
method AddLightningEdges takes string lightningType, real cutOffDist returns nothing
local real cod2 = cutOffDist*cutOffDist
local integer A = 0
local integer B
local integer L = 0
local real dist
loop
exitwhen A > .numVertices - 1
set B = A + 1
loop
exitwhen B > .numVertices - 1
set dist = (.X0[A]-.X0[B])*(.X0[A]-.X0[B]) + (.Y0[A]-.Y0[B])*(.Y0[A]-.Y0[B]) + (.Z0[A]-.Z0[B])*(.Z0[A]-.Z0[B])
if dist < cod2 then
set .lightningOrigin[L] = A
set .lightningEnd[L] = B
set .numLightnings = .numLightnings + 1
set .edgeLightning[L] = AddLightningEx( lightningType , true , .X[A] , .Y[A] , .Z[A] , .X[B] , .Y[B] , .Z[B] )
set L = L + 1
endif
set B = B + 1
endloop
set A = A + 1
endloop
endmethod
method onDestroy takes nothing returns nothing
local integer A = 0
loop
exitwhen A > .numVertices - 1
call DestroyEffect(.vertexEffect[A])
set A = A + 1
endloop
endmethod
//=================================================================================
//Polyhedron constructor functions.
//=================================================================================
private method CreateNthVertex takes integer A, string vertexEffect returns nothing
if vertexEffect != "" then
set .vertexEffect[A] = AddSpecialEffect( vertexEffect , .x + .X0[A] , .y + .Y0[A] )
call BlzSetSpecialEffectZ( .vertexEffect[A] , .z + .Z0[A] + .effectZoffset )
endif
endmethod
private method CreateDeltoidalHexacontahedron takes real edgeLength, string vertexEffect returns nothing
local integer A
local integer P
local integer S
local real array c1
local real array c2
local real array c3
local real array c4
local real array c5
local integer array sign
local integer array permutation
set .numVertices = 62
set c1[1] = 0
set c1[2] = 0
set c1[3] = 2.7778
set c2[1] = 0
set c2[2] = 2.4241
set c2[3] = 1.4982
set c3[1] = 0
set c3[2] = 0.9732
set c3[3] = 2.548
set c4[1] = 1.3889
set c4[2] = 2.2472
set c4[3] = 0.8584
set c5[1] = 1.5747
set c5[2] = 1.5747
set c5[3] = 1.5747
set sign[1] = 1
set sign[2] = 1
set sign[3] = 1
set sign[4] = 1
set sign[5] = 1
set sign[6] = -1
set sign[7] = 1
set sign[8] = -1
set sign[9] = 1
set sign[10] = 1
set sign[11] = -1
set sign[12] = -1
set sign[13] = -1
set sign[14] = 1
set sign[15] = 1
set sign[16] = -1
set sign[17] = 1
set sign[18] = -1
set sign[19] = -1
set sign[20] = -1
set sign[21] = 1
set sign[22] = -1
set sign[23] = -1
set sign[24] = -1
set permutation[1] = 1
set permutation[2] = 2
set permutation[3] = 3
set permutation[4] = 3
set permutation[5] = 1
set permutation[6] = 2
set permutation[7] = 2
set permutation[8] = 3
set permutation[9] = 1
set A = 0
set P = 0
loop
exitwhen P > 2
set S = 0
loop
exitwhen S > 7
set .X0[A] = edgeLength*sign[3*S + 1]*c4[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c4[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c4[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
if P == 0 then
set .X0[A] = edgeLength*sign[3*S + 1]*c5[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c5[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c5[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
endif
if sign[3*S + P+1] == 1 then
set .X0[A] = edgeLength*sign[3*S + 1]*c2[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c2[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c2[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = edgeLength*sign[3*S + 1]*c3[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c3[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c3[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
if sign[3*S + P+2] == 1 then
set .X0[A] = edgeLength*sign[3*S + 1]*c1[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c1[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c1[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
endif
endif
set S = S + 1
endloop
set P = P + 1
endloop
endmethod
private method CreateDisdyakisTriacontahedron takes real edgeLength, string vertexEffect returns nothing
local integer A
local integer P
local integer S
local real phi = 1.61803
local real x = 1.7156
local real R = 1.06509
local real scale = 1.3
local real array c1
local real array c2
local integer array sign
local integer array permutation
set .numVertices = 62
set c1[1] = 0
set c1[2] = scale
set c1[3] = phi
set c2[1] = 0
set c2[2] = phi
set c2[3] = scale/phi
set sign[1] = 1
set sign[2] = 1
set sign[3] = 1
set sign[4] = 1
set sign[5] = 1
set sign[6] = -1
set sign[7] = 1
set sign[8] = -1
set sign[9] = 1
set sign[10] = 1
set sign[11] = -1
set sign[12] = -1
set sign[13] = -1
set sign[14] = 1
set sign[15] = 1
set sign[16] = -1
set sign[17] = 1
set sign[18] = -1
set sign[19] = -1
set sign[20] = -1
set sign[21] = 1
set sign[22] = -1
set sign[23] = -1
set sign[24] = -1
set permutation[1] = 1
set permutation[2] = 2
set permutation[3] = 3
set permutation[4] = 3
set permutation[5] = 1
set permutation[6] = 2
set permutation[7] = 2
set permutation[8] = 3
set permutation[9] = 1
set A = 0
set P = 0
loop
exitwhen P > 2
set S = 0
loop
exitwhen S > 7
if sign[3*S + P+1] == 1 then
set .X0[A] = edgeLength*sign[3*S + 1]*c1[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c1[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c1[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = edgeLength*sign[3*S + 1]*c2[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c2[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c2[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
endif
set S = S + 1
endloop
set P = P + 1
endloop
set c1[1] = R*phi*phi/2
set c1[2] = R*phi/2
set c1[3] = R/2
set S = 0
loop
exitwhen S > 7
set .X0[A] = edgeLength*sign[3*S + 1]
set .Y0[A] = edgeLength*sign[3*S + 2]
set .Z0[A] = edgeLength*sign[3*S + 3]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set P = 0
loop
exitwhen P > 2
set .X0[A] = edgeLength*sign[3*S + 1]*c1[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c1[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c1[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set P = P + 1
endloop
set S = S + 1
endloop
set sign[1] = 1
set sign[2] = -1
set c1[1] = 0
set c1[2] = 0
set c1[3] = R*phi
set S = 0
loop
exitwhen S > 1
set P = 0
loop
exitwhen P > 2
set .X0[A] = edgeLength*sign[S+1]*c1[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[S+1]*c1[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[S+1]*c1[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set P = P + 1
endloop
set S = S + 1
endloop
endmethod
private method CreateSnubDodecahedron takes real edgeLength, string vertexEffect returns nothing
local integer A
local integer P
local integer S
local integer E
local integer I
local real phi = 1.61803
local real x = 1.7156
local real array c
local integer array sets
local integer array sign
local integer array permutation
local real scale = 0.9
set .numVertices = 60
set c[0] = phi * SquareRoot(3 - x*x) / 2
set c[1] = x * phi * SquareRoot(3 - x*x) / 2
set c[2] = phi * SquareRoot((x-1-(1/x))*phi) / 2
set c[3] = x*x * phi * SquareRoot(3 - x*x) / 2
set c[4] = x * phi * SquareRoot((x-1-(1/x))*phi) / 2
set c[5] = phi * SquareRoot(1 - x + (phi + 1)/x) / 2
set c[6] = phi * SquareRoot(x - phi + 1) / 2
set c[7] = x*x * phi * SquareRoot((x-1-(1/x))*phi) / 2
set c[8] = x * phi * SquareRoot(1-x+(phi+1)/x) / 2
set c[9] = SquareRoot((x+2)*phi + 2) / 2
set c[10] = x * SquareRoot(x * (phi + 1) - phi) / 2
set c[11] = SquareRoot((x*x) * (2*phi + 1) - phi) / 2
set c[12] = phi * SquareRoot(x*x + x) / 2
set c[13] = phi*phi * SquareRoot(x * (x+phi) + 1) / (2*x)
set c[14] = phi * SquareRoot(x * (x+phi) + 1) / 2
set sets[1] = 2
set sets[2] = 1
set sets[3] = 14
set sets[4] = 0
set sets[5] = 8
set sets[6] = 12
set sets[7] = 7
set sets[8] = 6
set sets[9] = 11
set sign[1] = -1
set sign[2] = -1
set sign[3] = -1
set sign[4] = -1
set sign[5] = 1
set sign[6] = 1
set sign[7] = 1
set sign[8] = 1
set sign[9] = -1
set sign[10] = 1
set sign[11] = -1
set sign[12] = 1
set permutation[1] = 1
set permutation[2] = 2
set permutation[3] = 3
set permutation[4] = 3
set permutation[5] = 1
set permutation[6] = 2
set permutation[7] = 2
set permutation[8] = 3
set permutation[9] = 1
set A = 0
set P = 0
loop
exitwhen P > 2
set S = 0
loop
exitwhen S > 3
set E = 0
loop
exitwhen E > 2
set .X0[A] = edgeLength*sign[3*S + 1]*c[sets[3*E + permutation[3*P + 1]]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c[sets[3*E + permutation[3*P + 2]]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c[sets[3*E + permutation[3*P + 3]]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set E = E + 1
endloop
set S = S + 1
endloop
set P = P + 1
endloop
set sets[1] = 3
set sets[2] = 4
set sets[3] = 13
set sets[4] = 9
set sets[5] = 5
set sets[6] = 10
set sign[1] = 1
set sign[2] = 1
set sign[3] = 1
set sign[4] = 1
set sign[5] = -1
set sign[6] = -1
set sign[7] = -1
set sign[8] = 1
set sign[9] = -1
set sign[10] = -1
set sign[11] = -1
set sign[12] = 1
set permutation[1] = 1
set permutation[2] = 2
set permutation[3] = 3
set permutation[4] = 3
set permutation[5] = 1
set permutation[6] = 2
set permutation[7] = 2
set permutation[8] = 3
set permutation[9] = 1
set P = 0
loop
exitwhen P > 2
set S = 0
loop
exitwhen S > 3
set E = 0
loop
exitwhen E > 1
set .X0[A] = edgeLength*sign[3*S + 1]*c[sets[3*E + permutation[3*P + 1]]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c[sets[3*E + permutation[3*P + 2]]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c[sets[3*E + permutation[3*P + 3]]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set E = E + 1
endloop
set S = S + 1
endloop
set P = P + 1
endloop
endmethod
private method CreateSnubCube takes real edgeLength, string vertexEffect returns nothing
local integer A
local integer P = 0
local integer S
local integer I
local real t = 1.83929
local real a = 1/1.60972
local real array c
local integer array sign
local integer array permutation
set .numVertices = 24
set c[1] = a
set c[2] = a/t
set c[3] = a*t
set sign[1] = -1
set sign[2] = -1
set sign[3] = -1
set sign[4] = -1
set sign[5] = 1
set sign[6] = 1
set sign[7] = 1
set sign[8] = 1
set sign[9] = -1
set sign[10] = 1
set sign[11] = -1
set sign[12] = 1
set permutation[1] = 1
set permutation[2] = 2
set permutation[3] = 3
set permutation[4] = 3
set permutation[5] = 1
set permutation[6] = 2
set permutation[7] = 2
set permutation[8] = 3
set permutation[9] = 1
set A = 0
loop
exitwhen P > 2
set S = 0
loop
exitwhen S > 3
set .X0[A] = edgeLength*sign[3*S + 1]*c[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 2
set S = S + 1
endloop
set P = P + 1
endloop
set sign[1] = 1
set sign[2] = 1
set sign[3] = 1
set sign[4] = 1
set sign[5] = -1
set sign[6] = -1
set sign[7] = -1
set sign[8] = 1
set sign[9] = -1
set sign[10] = -1
set sign[11] = -1
set sign[12] = 1
set permutation[1] = 3
set permutation[2] = 2
set permutation[3] = 1
set permutation[4] = 2
set permutation[5] = 1
set permutation[6] = 3
set permutation[7] = 1
set permutation[8] = 3
set permutation[9] = 2
set A = 1
set P = 0
loop
exitwhen P > 2
set S = 0
loop
exitwhen S > 3
set .X0[A] = edgeLength*sign[3*S + 1]*c[permutation[3*P + 1]]
set .Y0[A] = edgeLength*sign[3*S + 2]*c[permutation[3*P + 2]]
set .Z0[A] = edgeLength*sign[3*S + 3]*c[permutation[3*P + 3]]
call .CreateNthVertex(A,vertexEffect)
set A = A + 2
set S = S + 1
endloop
set P = P + 1
endloop
endmethod
private method CreateTetrakisHexahedron takes real edgeLength, string vertexEffect returns nothing
local integer A = 0
local real phi
local integer X = 1
local integer Y = 1
local integer Z = 1
local real offset = 0.5
local real m = 1.333
set .numVertices = 14
loop
exitwhen A > 7
if ModuloInteger(A,2) == 1 then
set X = -1*X
endif
if A == 2 or A == 6 then
set Y = -1*Y
endif
if A == 4 then
set Z = -1*Z
endif
set .X0[A] = X*m*edgeLength/2
set .Y0[A] = Y*m*edgeLength/2
set .Z0[A] = Z*m*edgeLength/2
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
endloop
set .X0[A] = ((1+offset)*m*edgeLength)/2
set .Y0[A] = 0
set .Z0[A] = 0
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = -((1+offset)*m*edgeLength)/2
set .Y0[A] = 0
set .Z0[A] = 0
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = 0
set .Y0[A] = ((1+offset)*m*edgeLength)/2
set .Z0[A] = 0
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = 0
set .Y0[A] = -((1+offset)*m*edgeLength)/2
set .Z0[A] = 0
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = 0
set .Y0[A] = 0
set .Z0[A] = ((1+offset)*m*edgeLength)/2
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = 0
set .Y0[A] = 0
set .Z0[A] = -((1+offset)*m*edgeLength)/2
call .CreateNthVertex(A,vertexEffect)
endmethod
private method CreateTriacontahedron takes real edgeLength, string vertexEffect returns nothing
local real t = 0.8616*edgeLength
local real p = 1.618
local integer A = -1
local integer B
local integer C
local integer N = 0
set A = -1
loop
exitwhen A > 1
set B = -1
loop
exitwhen B > 1
set C = -1
loop
exitwhen C > 1
set .X0[N] = A*t
set .Y0[N] = B*t
set .Z0[N] = C*t
call .CreateNthVertex(N,vertexEffect)
set N = N + 1
if B == 1 then
set .X0[N] = 0
set .Y0[N] = A*t*p
set .Z0[N] = C*t/p
call .CreateNthVertex(N,vertexEffect)
set N = N + 1
set .X0[N] = A*t/p
set .Y0[N] = 0
set .Z0[N] = C*t*p
call .CreateNthVertex(N,vertexEffect)
set N = N + 1
set .X0[N] = A*t*p
set .Y0[N] = C*t/p
set .Z0[N] = 0
call .CreateNthVertex(N,vertexEffect)
set N = N + 1
set .X0[N] = A*edgeLength/1.46
set .Y0[N] = 2*C*edgeLength/1.46
set .Z0[N] = 0
call .CreateNthVertex(N,vertexEffect)
set N = N + 1
set .X0[N] = 0
set .Y0[N] = A*edgeLength/1.46
set .Z0[N] = 2*C*edgeLength/1.46
call .CreateNthVertex(N,vertexEffect)
set N = N + 1
set .X0[N] = 2*C*edgeLength/1.46
set .Y0[N] = 0
set .Z0[N] = A*edgeLength/1.46
call .CreateNthVertex(N,vertexEffect)
set N = N + 1
endif
set C = C + 2
endloop
set B = B + 2
endloop
set A = A + 2
endloop
set .numVertices = 32
endmethod
private method CreateCuboctahedron takes real edgeLength, string vertexEffect returns nothing
local integer A = 0
local real phi
local real Z
local real XY
set .numVertices = 12
loop
exitwhen A > .numVertices - 1
if A == 0 then
set phi = 0
set Z = edgeLength/SquareRoot(2)
set XY = edgeLength/SquareRoot(2)
elseif A == 4 then
set phi = bj_PI/4
set Z = 0
set XY = edgeLength
elseif A == 8 then
set phi = 0
set Z = -edgeLength/SquareRoot(2)
set XY = edgeLength/SquareRoot(2)
endif
set .X0[A] = XY*Cos(phi)
set .Y0[A] = XY*Sin(phi)
set .Z0[A] = Z
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set phi = phi + bj_PI/2
endloop
endmethod
private method CreateCube takes real edgeLength, string vertexEffect returns nothing
local integer A = 0
local real phi = bj_PI/4
local real Z = -edgeLength/2
set .numVertices = 8
loop
exitwhen A > .numVertices - 1
if A == 4 then
set Z = edgeLength/2
endif
set .X0[A] = edgeLength/SquareRoot(2)*Cos(phi)
set .Y0[A] = edgeLength/SquareRoot(2)*Sin(phi)
set .Z0[A] = Z
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set phi = phi + bj_PI/2
endloop
endmethod
private method CreateOctahedron takes real edgeLength, string vertexEffect returns nothing
local integer A = 0
local real phi = 0
local real Z = 0
set .numVertices = 6
loop
exitwhen A > 3
set .X0[A] = edgeLength/SquareRoot(2)*Cos(phi)
set .Y0[A] = edgeLength/SquareRoot(2)*Sin(phi)
set .Z0[A] = Z
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set phi = phi + bj_PI/2
endloop
set .X0[A] = 0
set .Y0[A] = 0
set .Z0[A] = edgeLength/SquareRoot(2)
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = 0
set .Y0[A] = 0
set .Z0[A] = -edgeLength/SquareRoot(2)
call .CreateNthVertex(A,vertexEffect)
endmethod
private method CreateTetrahedron takes real edgeLength, string vertexEffect returns nothing
local real L = edgeLength*SquareRoot(3.0/8.0)
local integer A = 0
set .numVertices = 4
set .X0[A] = SquareRoot(8.0/9.0)*L
set .Y0[A] = 0
set .Z0[A] = -L/3
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = -SquareRoot(2.0/9.0)*L
set .Y0[A] = SquareRoot(2.0/3.0)*L
set .Z0[A] = -L/3
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = -SquareRoot(2.0/9.0)*L
set .Y0[A] = -SquareRoot(2.0/3.0)*L
set .Z0[A] = -L/3
call .CreateNthVertex(A,vertexEffect)
set A = A + 1
set .X0[A] = 0
set .Y0[A] = 0
set .Z0[A] = L
call .CreateNthVertex(A,vertexEffect)
endmethod
static method create takes real x, real y, real z, string whichPolyhedron, real edgeLength, string vertexEffect, real effectZoffset, real effectScale, real rotationSpeed, real precessionSpeed returns polyhedron
local polyhedron newPolyhedron = polyhedron.allocate()
local integer A = 0
set newPolyhedron.effectZoffset = effectZoffset
set newPolyhedron.x = x
set newPolyhedron.y = y
set newPolyhedron.z = z
if whichPolyhedron == "deltoidalhexacontahedron" then //62 (Catalan)
call newPolyhedron.CreateDeltoidalHexacontahedron(edgeLength , vertexEffect)
elseif whichPolyhedron == "disdyakistriacontahedron" then //62 (Catalan)
call newPolyhedron.CreateDisdyakisTriacontahedron(edgeLength , vertexEffect)
elseif whichPolyhedron == "snubdodecahedron" then //60 (Archimedean)
call newPolyhedron.CreateSnubDodecahedron(edgeLength , vertexEffect)
elseif whichPolyhedron == "triacontahedron" then //32 (Catalan)
call newPolyhedron.CreateTriacontahedron(edgeLength , vertexEffect)
elseif whichPolyhedron == "snubcube" then //24 (Archimedean)
call newPolyhedron.CreateSnubCube(edgeLength , vertexEffect)
elseif whichPolyhedron == "tetrakishexahedron" then //14 (Catalan)
call newPolyhedron.CreateTetrakisHexahedron(edgeLength , vertexEffect)
elseif whichPolyhedron == "cuboctahedron" then //12 (Archimedean)
call newPolyhedron.CreateCuboctahedron(edgeLength , vertexEffect)
elseif whichPolyhedron == "cube" then //8 (Platonic)
call newPolyhedron.CreateCube(edgeLength , vertexEffect)
elseif whichPolyhedron == "octahedron" then //6 (Platonic)
call newPolyhedron.CreateOctahedron(edgeLength , vertexEffect)
elseif whichPolyhedron == "tetrahedron" then //4 (Platonic)
call newPolyhedron.CreateTetrahedron(edgeLength , vertexEffect)
else
call BJDebugMsg("Invalid polyhedron type")
return 0
endif
loop
exitwhen A > newPolyhedron.numVertices - 1
call BlzSetSpecialEffectScale( newPolyhedron.vertexEffect[A] , effectScale )
set A = A + 1
endloop
set newPolyhedron.rotSpeed = rotationSpeed
set newPolyhedron.precessionSpeed = precessionSpeed
return newPolyhedron
endmethod
static method createSimple takes real x, real y, real z, string whichPolyhedron, real edgeLength returns polyhedron
local polyhedron newPolyhedron = polyhedron.create(x, y, z, whichPolyhedron, edgeLength, "", 0, 0, 0, 0)
return newPolyhedron
endmethod
endstruct
endlibrary
Attachments
Last edited: