## Posted By

ZonjaCapalini on 07/21/09

# Klein bottle generator

/ Published in: Other

`// Time to sleep between rezzes -- avoids compile errorsfloat   sleep = 1;// Number of "slices"integer m = 120;// Number of "stripes"integer n = 8;// Name of the rezzed object (must exist in inv)string  edgeprimname = "Cylinder"; // Rezz a segment between 2 given points, assign its color color// Mod of a routine found here: //   http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryBezierCurveDemo// Original credits follow://   Bezier Curve Demo 1.0.1//   Catherine Omega Heavy Industries//   Modified by Lionel Forager 29-12-2006: //     Added segment drawing between points. Corrected minor bugs.drawLineSegment(vector base, vector p1,vector p2, integer order){    // Calc the position of the center of the segment    vector center = (p1+p2)/2.;    vector localZ = p2 - p1;    // Get distance between points    float distance= llVecMag(localZ);    // Normalize the vector    localZ = localZ / distance;     vector xAxis;    // Let's choose as x local axis the direction of a vector normal    // to localZ and contained in the plain given by localZ and global X    // or global Y, the one that is less parallel to localZ    if ( localZ.x < localZ.y ) xAxis= <1.,0.,0.>;    else                       xAxis= <0.,1.,0.>;     // localX is the one contain in the plane given by localZ and xAxis    // that is normal to localZ. That is, localX = xAxis - localZ*xaxis*localZ.    // We should normalize the vector to get a unitary one.    vector localX= xAxis - (localZ * xAxis) * localZ;    localX= llVecNorm(localX);     // Now get the rotation to put axis Z oriented pointing    // to the direction between the two given points.     rotation rot = llAxes2Rot(localX,localZ % localX, localZ);         // Rezz the cylinder!    llRezObject(edgeprimname,base + center,ZERO_VECTOR,rot,(integer) (distance*1000)*100+order);     // Avoid clogging the queue and subsequent compile problems    llSleep(sleep);}  default {     touch_start(integer total_number)    {         llSay(0, "Generating Klein bottle...");          integer i;        integer j;        float a = 2;        float b = 7;        float c = 2;        float r;        float u;        float v;        float x;        float y;        float z;        list oldcoor = [];        list firstcoor = [];        list coor = [];        vector prevpos;        rotation rot;         for (i = 0; i <= m; i++) {            // llSay(0,"Looping I="+(string)i+" of "+(string)m);             for (j = 0; j < n; j++) {                // llSay(0," Looping J="+(string)j+" of "+(string)n);                 u = 2 * PI * i / m;                v = 2 * PI * j / n;                 if (n % 2 == 1) v += PI / n * i/m;                 r = c * (1 - llCos(u) / 2);                 // See PlanetMath,                         // http://planetmath.org/?op=getobj&from=objects&id=4249                 if (u < PI) {                    x = a * llCos(u) * (1 + llSin(u)) + r * llCos(u) * llCos(v);                    y = b * llSin(u) + r * llSin(u) * llCos(v);                } else {                    x = a * llCos(u) * (1 + llSin(u)) + r * llCos(v + PI);                    y = b * llSin(u);                };                 z = r * llSin(v);                  // draw "horizontal" lines                if (j > 0) {                    prevpos = llList2Vector(coor,j-1);                    drawLineSegment(llGetPos(),prevpos,<x,y,z>,j);                };                 if (j == n-1) {                    prevpos = llList2Vector(coor,0);                    drawLineSegment(llGetPos(),prevpos,<x,y,z>,0);                };                  // draw "vertical" and diagonal lines                if (i > 0) {                      prevpos = llList2Vector(oldcoor,j);                    drawLineSegment(llGetPos(),prevpos,<x,y,z>,j);                     if (j > 0) prevpos = llList2Vector(oldcoor,j-1);                    else prevpos = llList2Vector(oldcoor,n-1);                    drawLineSegment(llGetPos(),prevpos,<x,y,z>,j);                 };                  // if (i < m) llRezObject("Vertex", llGetPos() + <x,y,z>,                 // <0.0,0.0,0.0>, <0.0,0.0,0.0,1.0>, 0);                 coor = coor + [<x,y,z>];             };              if (i == 0) firstcoor = coor;            oldcoor = coor;            coor = [];         };        llSay(0, "Done!");     }}`