// questions: // 1. why is the shape rotated slightly around the z-axis? // 2. why were the inside/outside scaling equations chosen? // 3. why do the first and last vertical lines connect to each other? #version 3.7; #include "Math.inc" global_settings { assumed_gamma 1 } camera { orthographic location <0, 0, -1> direction <0, 0, 1> up y scale 3/4 scale 4 } light_source { <0, 0, -3000> color 1 parallel } plane { z, 0 texture { pigment { checker pigment { onion color_map { [000/100 color rgb 0/2] [001/100 color rgb 0/2] [001/100 color rgb 2/2] [099/100 color rgb 2/2] [099/100 color rgb 0/2] [100/100 color rgb 0/2] } scale 1/4 } pigment { onion color_map { [000/100 color rgb 2/2] [001/100 color rgb 2/2] [001/100 color rgb 0/2] [099/100 color rgb 0/2] [099/100 color rgb 2/2] [100/100 color rgb 2/2] } scale 1/4 } } } } #declare TWO_PI = 2 * pi; #declare iNx = 32; // the number of "horizontal" lines per charge, not taking into account iXmin #declare iNy = 32; // the number of "vertical" lines per charge #declare iXmin = 24; // size of the empty hole for each charge, measured in "horizontal" lines #declare iSym = 5; // number of charges arranged around the origin #declare iSx = 2; #declare iSy = 2; #declare fMouseY = 300; // need to get rid of this #declare bLines = true; // show lines connecting the points #declare bInside = true; // are the curved lines inside or outside of the reference shape? or, are the charges inside or outside the reference shape? #macro mag(fX, fY) dist(fX, fY, 0, 0) #end #macro dist(fX1, fY1, fX2, fY2) sqrt(pow(fX2 - fX1, 2) + pow(fY2 - fY1, 2)) #end #macro calc() #local fY1 = 0; #local fX1 = 0; #local fX2 = exp(fX1) * cos(fY1); #local fY2 = exp(fX1) * sin(fY1) + fMouseY; #if (bInside) #local fD = pow(mag(fX2, fY2), 1/iSym); #else #local fD = pow(mag(fX2, fY2), -1/iSym); #end #local fArg = atan2(fX2, fY2) * -1/iSym; #local fX3 = fD * cos(fArg)/TWO_PI; #local fY3 = fD * sin(fArg)/TWO_PI; vlength() // return #end #macro draw() #for (i, 0, iNy - 1) #local fY = i * TWO_PI/iNy; #for (j, iXmin * iSx, iNx * iSx - 1) #local fX1 = j * TWO_PI/iNx/iSx; #local fX2 = (j + 1) * TWO_PI/iNx/iSx; lines(fn(fX1, fY), fn(fX2, fY)) #end #end #for (i, iXmin, iNx) #local fX = i * TWO_PI/iNx; #for (j, 0, iNy * iSy - 1) #local fY1 = j * TWO_PI/iNy/iSy; #local fY2 = (j + 1) * TWO_PI/iNy/iSy; lines(fn(fX, fY1), fn(fX, fY2)) #end #end #end #macro lines(aP1, aP2) #for (i, 0, iSym - 1) #local fX1 = aP1[i][0]; #local fY1 = aP1[i][1]; #local fX2 = aP2[i][0]; #local fY2 = aP2[i][1]; sphere { /calc(), 0.005 pigment {color rgb x} } #if (bLines) cylinder { /calc(), /calc(), 0.005 pigment {color rgb x} } #end #end #end // this is where the magic happens ... #macro fn(fX, fY) #local aP = array[iSym][2]; #local fX1 = exp(fX) * cos(fY); #local fY1 = exp(fX) * sin(fY) - fMouseY; #if (bInside) #local fD = pow(mag(fX1, fY1), 1/iSym); #else #local fD = pow(mag(fX1, fY1), -1/iSym); #end #local fArg = atan2(fX1, fY1) * -1/iSym; #for (i, 0, iSym - 1) #local fX2 = fD * cos(fArg + i * TWO_PI/iSym); #local fY2 = fD * sin(fArg + i * TWO_PI/iSym); #local aP[i][0] = fX2/TWO_PI; #local aP[i][1] = fY2/TWO_PI; #end aP //return #end draw()