Last active
December 13, 2018 03:50
-
-
Save stla/6892a261bc2c45509cd1482fbeff2f93 to your computer and use it in GitHub Desktop.
Twenty Hopf tori with Asymptote
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
settings.render = 4; | |
settings.outformat = "pdf"; | |
import graph3; | |
import three; | |
import palette; | |
size(500,0); | |
// projection and light -------------------------------------------------------- | |
currentprojection = orthographic(2,0,0); | |
currentlight = light(gray(0.85), ambient=black, specularfactor=3, | |
(20,0,0), specular=gray(0.6), viewport=false); | |
// transformation which reorients and translates ------------------------------- | |
transform3 transReorient(triple axis, triple vector){ | |
triple vX1 = unit(vector); | |
triple vX2 = unit(axis); | |
triple vY = unit(cross(vX1,vX2)); | |
triple vZ1 = unit(cross(vX1,vY)); | |
triple vZ2 = unit(cross(vX2,vY)); | |
real[][] M1 = | |
{{vX1.x, vX1.y, vX1.z}, | |
{vY.x, vY.y, vY.z}, | |
{vZ1.x, vZ1.y, vZ1.z}}; | |
real[][] M2 = | |
{{vX2.x, vY.x, vZ2.x}, | |
{vX2.y, vY.y, vZ2.y}, | |
{vX2.z, vY.z, vZ2.z}}; | |
real[][] M = transpose(M2*M1); | |
transform3 T = copy(identity4); | |
T[0][0] = M[0][0]; | |
T[1][0] = M[1][0]; | |
T[2][0] = M[2][0]; | |
T[0][1] = M[0][1]; | |
T[1][1] = M[1][1]; | |
T[2][1] = M[2][1]; | |
T[0][2] = M[0][2]; | |
T[1][2] = M[1][2]; | |
T[2][2] = M[2][2]; | |
T[0][3] = vector.x; | |
T[1][3] = vector.y; | |
T[2][3] = vector.z; | |
return T; | |
} | |
// parameterization of Hopf torus ---------------------------------------------- | |
triple F(pair uv){ | |
real t = uv.x; | |
real phi = uv.y; | |
real nlobes = 3; | |
real A = 0.44; | |
real p2 = sin(pi/2 - (pi/2-A)*cos(t*nlobes)) * cos(t+A*sin(2*t*nlobes)); | |
real p3 = sin(pi/2 - (pi/2-A)*cos(t*nlobes)) * sin(t+A*sin(2*t*nlobes)); | |
real p1 = cos(pi/2 - (pi/2-A)*cos(t*nlobes)); | |
real yden = sqrt(2*(1+p1)); | |
real y1 = (1+p1)/yden; | |
real y2 = p2/yden; | |
real y3 = p3/yden; | |
real cosphi = cos(phi); | |
real sinphi = sin(phi); | |
real x3 = cosphi*y1; | |
real x4 = sinphi*y1; | |
real x2 = cosphi*y2 - sinphi*y3; | |
real x1 = cosphi*y3 + sinphi*y2; | |
return 0.025 * (x1/(1-x4), x2/(1-x4), x3/(1-x4)); | |
} | |
// twenty points on the unit sphere -------------------------------------------- | |
real phi = (1 + sqrt(5)) / 2; | |
real a = 1 / sqrt(3); | |
real b = a / phi; | |
real c = a * phi; | |
triple[] points = | |
{( a, a, a), | |
( a, a, -a), | |
( a, -a, a), | |
(-a, -a, a), | |
(-a, a, -a), | |
(-a, a, a), | |
( 0, b, -c), | |
( 0, -b, -c), | |
( 0, -b, c), | |
( c, 0, -b), | |
(-c, 0, -b), | |
(-c, 0, b), | |
( b, c, 0), | |
( b, -c, 0), | |
(-b, -c, 0), | |
(-b, c, 0), | |
( 0, b, c), | |
( a, -a, -a), | |
( c, 0, b), | |
(-a, -a, -a)}; | |
// viridis color palette ------------------------------------------------------- | |
pen[] viridis = { | |
rgb("440154ff"), rgb("440256ff"), rgb("450457ff"), rgb("450559ff"), | |
rgb("46075aff"), rgb("46085cff"), rgb("460a5dff"), rgb("460b5eff"), | |
rgb("470d60ff"), rgb("470e61ff"), rgb("471063ff"), rgb("471164ff"), | |
rgb("471365ff"), rgb("481467ff"), rgb("481668ff"), rgb("481769ff"), | |
rgb("48186aff"), rgb("481a6cff"), rgb("481b6dff"), rgb("481c6eff"), | |
rgb("481d6fff"), rgb("481f70ff"), rgb("482071ff"), rgb("482173ff"), | |
rgb("482374ff"), rgb("482475ff"), rgb("482576ff"), rgb("482677ff"), | |
rgb("482878ff"), rgb("482979ff"), rgb("472a7aff"), rgb("472c7aff"), | |
rgb("472d7bff"), rgb("472e7cff"), rgb("472f7dff"), rgb("46307eff"), | |
rgb("46327eff"), rgb("46337fff"), rgb("463480ff"), rgb("453581ff"), | |
rgb("453781ff"), rgb("453882ff"), rgb("443983ff"), rgb("443a83ff"), | |
rgb("443b84ff"), rgb("433d84ff"), rgb("433e85ff"), rgb("423f85ff"), | |
rgb("424086ff"), rgb("424186ff"), rgb("414287ff"), rgb("414487ff"), | |
rgb("404588ff"), rgb("404688ff"), rgb("3f4788ff"), rgb("3f4889ff"), | |
rgb("3e4989ff"), rgb("3e4a89ff"), rgb("3e4c8aff"), rgb("3d4d8aff"), | |
rgb("3d4e8aff"), rgb("3c4f8aff"), rgb("3c508bff"), rgb("3b518bff"), | |
rgb("3b528bff"), rgb("3a538bff"), rgb("3a548cff"), rgb("39558cff"), | |
rgb("39568cff"), rgb("38588cff"), rgb("38598cff"), rgb("375a8cff"), | |
rgb("375b8dff"), rgb("365c8dff"), rgb("365d8dff"), rgb("355e8dff"), | |
rgb("355f8dff"), rgb("34608dff"), rgb("34618dff"), rgb("33628dff"), | |
rgb("33638dff"), rgb("32648eff"), rgb("32658eff"), rgb("31668eff"), | |
rgb("31678eff"), rgb("31688eff"), rgb("30698eff"), rgb("306a8eff"), | |
rgb("2f6b8eff"), rgb("2f6c8eff"), rgb("2e6d8eff"), rgb("2e6e8eff"), | |
rgb("2e6f8eff"), rgb("2d708eff"), rgb("2d718eff"), rgb("2c718eff"), | |
rgb("2c728eff"), rgb("2c738eff"), rgb("2b748eff"), rgb("2b758eff"), | |
rgb("2a768eff"), rgb("2a778eff"), rgb("2a788eff"), rgb("29798eff"), | |
rgb("297a8eff"), rgb("297b8eff"), rgb("287c8eff"), rgb("287d8eff"), | |
rgb("277e8eff"), rgb("277f8eff"), rgb("27808eff"), rgb("26818eff"), | |
rgb("26828eff"), rgb("26828eff"), rgb("25838eff"), rgb("25848eff"), | |
rgb("25858eff"), rgb("24868eff"), rgb("24878eff"), rgb("23888eff"), | |
rgb("23898eff"), rgb("238a8dff"), rgb("228b8dff"), rgb("228c8dff"), | |
rgb("228d8dff"), rgb("218e8dff"), rgb("218f8dff"), rgb("21908dff"), | |
rgb("21918cff"), rgb("20928cff"), rgb("20928cff"), rgb("20938cff"), | |
rgb("1f948cff"), rgb("1f958bff"), rgb("1f968bff"), rgb("1f978bff"), | |
rgb("1f988bff"), rgb("1f998aff"), rgb("1f9a8aff"), rgb("1e9b8aff"), | |
rgb("1e9c89ff"), rgb("1e9d89ff"), rgb("1f9e89ff"), rgb("1f9f88ff"), | |
rgb("1fa088ff"), rgb("1fa188ff"), rgb("1fa187ff"), rgb("1fa287ff"), | |
rgb("20a386ff"), rgb("20a486ff"), rgb("21a585ff"), rgb("21a685ff"), | |
rgb("22a785ff"), rgb("22a884ff"), rgb("23a983ff"), rgb("24aa83ff"), | |
rgb("25ab82ff"), rgb("25ac82ff"), rgb("26ad81ff"), rgb("27ad81ff"), | |
rgb("28ae80ff"), rgb("29af7fff"), rgb("2ab07fff"), rgb("2cb17eff"), | |
rgb("2db27dff"), rgb("2eb37cff"), rgb("2fb47cff"), rgb("31b57bff"), | |
rgb("32b67aff"), rgb("34b679ff"), rgb("35b779ff"), rgb("37b878ff"), | |
rgb("38b977ff"), rgb("3aba76ff"), rgb("3bbb75ff"), rgb("3dbc74ff"), | |
rgb("3fbc73ff"), rgb("40bd72ff"), rgb("42be71ff"), rgb("44bf70ff"), | |
rgb("46c06fff"), rgb("48c16eff"), rgb("4ac16dff"), rgb("4cc26cff"), | |
rgb("4ec36bff"), rgb("50c46aff"), rgb("52c569ff"), rgb("54c568ff"), | |
rgb("56c667ff"), rgb("58c765ff"), rgb("5ac864ff"), rgb("5cc863ff"), | |
rgb("5ec962ff"), rgb("60ca60ff"), rgb("63cb5fff"), rgb("65cb5eff"), | |
rgb("67cc5cff"), rgb("69cd5bff"), rgb("6ccd5aff"), rgb("6ece58ff"), | |
rgb("70cf57ff"), rgb("73d056ff"), rgb("75d054ff"), rgb("77d153ff"), | |
rgb("7ad151ff"), rgb("7cd250ff"), rgb("7fd34eff"), rgb("81d34dff"), | |
rgb("84d44bff"), rgb("86d549ff"), rgb("89d548ff"), rgb("8bd646ff"), | |
rgb("8ed645ff"), rgb("90d743ff"), rgb("93d741ff"), rgb("95d840ff"), | |
rgb("98d83eff"), rgb("9bd93cff"), rgb("9dd93bff"), rgb("a0da39ff"), | |
rgb("a2da37ff"), rgb("a5db36ff"), rgb("a8db34ff"), rgb("aadc32ff"), | |
rgb("addc30ff"), rgb("b0dd2fff"), rgb("b2dd2dff"), rgb("b5de2bff"), | |
rgb("b8de29ff"), rgb("bade28ff"), rgb("bddf26ff"), rgb("c0df25ff"), | |
rgb("c2df23ff"), rgb("c5e021ff"), rgb("c8e020ff"), rgb("cae11fff"), | |
rgb("cde11dff"), rgb("d0e11cff"), rgb("d2e21bff"), rgb("d5e21aff"), | |
rgb("d8e219ff"), rgb("dae319ff"), rgb("dde318ff"), rgb("dfe318ff"), | |
rgb("e2e418ff"), rgb("e5e419ff"), rgb("e7e419ff"), rgb("eae51aff"), | |
rgb("ece51bff"), rgb("efe51cff"), rgb("f1e51dff"), rgb("f4e61eff"), | |
rgb("f6e620ff"), rgb("f8e621ff"), rgb("fbe723ff"), rgb("fde725ff") }; | |
// construct the Hopf torus ---------------------------------------------------- | |
surface s = surface(F, (0,0), (2pi,2pi), 65, 65, Spline); | |
s.colors(palette(s.map(abs), viridis)); | |
// draw the twenty Hopf tori --------------------------------------------------- | |
picture pic; | |
for(int i = 0; i < 20; ++i){ | |
transform3 T = transReorient(Z, points[i]); | |
draw(pic,T*s); | |
draw(pic,O--points[i]); | |
draw(pic, extrude(T*circle(c=O, r=0.03, normal=Z), O--cycle), | |
material(rgb(255,215,0), emissivepen=gray(0.1))); | |
} | |
add(rotate(20,X)*rotate(70,Y)*rotate(30,Z)*pic); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment