KGRKJGETMRETU895U-589TY5MIGM5JGB5SDFESFREWTGR54TY
Server : Apache/2.4.62
System : FreeBSD fbsdweb2.web.rcn.net 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64
User : www ( 80)
PHP Version : 8.3.8
Disable Function : NONE
Directory :  /domains/gohover/cell/paprica/uploadtestfolder/Current Code/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /domains/gohover/cell/paprica/uploadtestfolder/Current Code/substitution_tiling_modules.js
// console.log("loading substitution modules now")





 default_tiling_settings = {
     PenroseRhombs: {recursion_level: 5, rosette_p: true, mods: ""},
     PenroseKites: {recursion_level: 5, rosette_p: true, mods: ""},
     PenroseRobinson: {recursion_level: 5, rosette_p: true, mods: ""},
     Penrose_P1: {recursion_level: 5, rosette_p: true, mods: ""},  
     BinaryTiling:  {recursion_level: 5, rosette_p: "unavailable", mods: ""}, 
     Danzer7fold:  {recursion_level: 4, rosette_p: "unavailable", mods: ""},    
     AmmannBeenker:  {recursion_level: 5, rosette_p: true, mods: ""},  
     Watanabe_Ito_Soma_8_Fold:  {recursion_level: 5, rosette_p: "unavailable", mods: ""}, 
     AmmannA4:  {recursion_level: 5, rosette_p: "unavailable", mods: ""}, 
     Chair:  {recursion_level: 5, rosette_p: "unavailable", mods: ""},  
     Sphinx:  {recursion_level: 5, rosette_p: "unavailable", mods: ""}, 
     DanzerT2000:  {recursion_level: 5, rosette_p: "unavailable", mods: ""}, 
     Diamond_BigTriangle:  {recursion_level: 5, rosette_p: "unavailable", mods: ""},  
     Diamond_SmallTriangle:  {recursion_level: 5, rosette_p: "unavailable", mods: ""},  
     Domino: {recursion_level: 5, rosette_p: "unavailable", mods: ""},  
     RhombSquareOctogon:  {recursion_level: 5, rosette_p: "unavailable", mods: ""}, 
     Pinwheel:  {recursion_level: 5, rosette_p: "unavailable", mods: ""},    
     Shield:  {recursion_level: 5, rosette_p: "unavailable", mods: ""},  
     Socolar:  {recursion_level: 5, rosette_p: "unavailable", mods: ""}, 
     SocolarInscribedRhombs:  {recursion_level: 5, rosette_p: "unavailable", mods: ""},  
     Watanabe_Ito_Soma_12_Fold: {recursion_level: 5, rosette_p: "unavailable", mods: ""},
     Lord_Tiling: {recursion_level: 5, rosette_p: "unavailable", mods: ""}, 
  
     dummylastitem:  {recursion_level: 5, rosette_p: "unavailable", mods: ""}
}


  
  
function  parse_mesh_specification() {
  if (the_mesh_spec.tiling_name == "none") {return "none"}
  var recursion_level = the_mesh_spec.recursion_level
  var single_or_rosette = "single"
  if (the_mesh_spec.rosette_p == true) {single_or_rosette = "rosette"}  
  var xmax = the_mesh_spec.xmax
  var ymax = the_mesh_spec.ymax 
  var nfold = the_mesh_spec.nfold
  var lines = the_mesh_spec.lines
  var shift = the_mesh_spec.shift
  var n_rings = the_mesh_spec.n_rings
  

  switch (the_mesh_spec.tiling_name) {
    case "PenroseRhombs": Penrose_module.make_Penrose_Tiling("rhombs", recursion_level,single_or_rosette) ; break;
    case "PenroseKites": Penrose_module.make_Penrose_Tiling("kites", recursion_level,single_or_rosette) ; break;
    case "PenroseRobinson": Penrose_module.make_Penrose_Tiling("Robinson", recursion_level,single_or_rosette) ; break;
    case "Penrose_P1":   Penrose_P1_module.make_Penrose_P1_Tiling(recursion_level, single_or_rosette)  ; break;



 /*  
   PenroseP1_firstdraft_module.make_PenroseP1_Tiling( recursion_level,single_or_rosette); break;
               if (recursion_level < 5) {alert("For Penrose P1, only recursion levels 5 through 10 are available.  Setting recursion level to 5."); recursion_level = 5}
               if (recursion_level >11) {alert("For Penrose P1, only recursion levels 5 through 11 are available.  Setting recursion level to 11."); recursion_level = 11}
               switch (recursion_level) {
                 case 5:   window.location.href = "../MeshPages/Penrose-P1-Level5.html"; break
                 case 6:   window.location.href = "../MeshPages/Penrose-P1-Level6.html"; break
                 case 7:   window.location.href = "../MeshPages/Penrose-P1-Level7.html"; break
                 case 8:   window.location.href = "../MeshPages/Penrose-P1-Level8.html"; break
                 case 9:   window.location.href = "../MeshPages/Penrose-P1-Level9.html"; break
                 case 10:  window.location.href = "../MeshPages/Penrose-P1-Level10.html"; break
                 case 11:  window.location.href = "../MeshPages/Penrose-P1-Level11.html"; break
               }
              break;
    */

    case "BinaryTiling": BinaryTiling_module.make_Binary_Tiling(recursion_level,single_or_rosette) ; break;

    case "Danzer7fold":  
               if (recursion_level < 1) {alert("For Danzer 7 fold tiling, only recursion levels 1 through 5 are available.  Setting recursion level to 1."); recursion_level = 1}
               if (recursion_level > 5) {alert("For Danzer 7 fold tiling, only recursion levels 1 through 5 are available.  Setting recursion level to 5."); recursion_level = 5}
               switch (recursion_level) {
                 case 1:   window.location.href = "../MeshPages/Danzer7fold-level1.html"; break
                 case 2:   window.location.href = "../MeshPages/Danzer7fold-level2.html"; break
                 case 3:   window.location.href = "../MeshPages/Danzer7fold-level3.html"; break
                 case 4:   window.location.href = "../MeshPages/Danzer7fold-level4.html"; break
                 case 5:   window.location.href = "../MeshPages/Danzer7fold-level5.html"; break
               }
              break;
    case "AmmannBeenker": AmmannBeenker_module.make_AmmannBeenker_Tiling(recursion_level,single_or_rosette) ; break;
    case "Watanabe_Ito_Soma_8_Fold": Watanabe_Ito_Soma_8_Fold_module.make_Watanabe_Ito_Soma_8_Fold_Tiling(recursion_level,single_or_rosette, true) ; break;

    case "AmmannA4": AmmannA4_module.make_AmmannA4_Tiling(recursion_level,single_or_rosette) ; break;
    case "Chair": ChairTiling_module.make_Chair_Tiling(recursion_level,single_or_rosette) ; break;
    case "Sphinx": SphinxTiling_module.make_Sphinx_Tiling(recursion_level,single_or_rosette) ; break;
    case "DanzerT2000": DanzerT2000_module.make_DanzerT2000_Tiling(recursion_level,single_or_rosette) ; break;
    case "Diamond_BigTriangle": Diamond_Triangle_module.make_Diamond_BigTriangle_Tiling(recursion_level,single_or_rosette) ; break;
    case "Diamond_SmallTriangle": Diamond_Triangle_module.make_Diamond_SmallTriangle_Tiling(recursion_level,single_or_rosette) ; break;
    case "Lord_Tiling":  Lord_module.make_Lord_Tiling(recursion_level,single_or_rosette) ; break;
    case "Domino": domino_module.make_domino_Tiling(recursion_level,single_or_rosette) ; break;
    case "RhombSquareOctogon": RhombSquareOctogon_module.make_RhombSquareOctogon_Tiling(recursion_level,single_or_rosette) ; break;
    case "Pinwheel": Pinwheel_module.make_Pinwheel_Tiling(recursion_level,single_or_rosette) ; break;
    case "Shield": Shield_module.make_Shield_Tiling(recursion_level,single_or_rosette) ; break;
    case "Socolar": Socolar_module.make_Socolar_Tiling(recursion_level,single_or_rosette, false) ; break;
    case "SocolarInscribedRhombs": Socolar_module.make_Socolar_Tiling(recursion_level,single_or_rosette, true) ; break;
    case "Watanabe_Ito_Soma_12_Fold": Watanabe_Ito_Soma_12_Fold_module.make_Watanabe_Ito_Soma_12_Fold_Tiling(recursion_level,single_or_rosette, true) ; break;

    case "Paul_Zinn-Justin": 
           PaulZinnJustin_module.precompute()
           PaulZinnJustin_module.ericredraw()
    break;

    case "my_multigrid":
           my_dual_method_tiling_generator_ver001(nfold, lines, shift)
    break;

    case "gen_experiment2":
          my_dual_method_tiling_generator2(nfold, lines, shift)
    break;

    case "gen_experiment3":
          my_dual_method_tiling_generator3(nfold, lines, shift)
    break;

    case "gen_experiment4":
          my_dual_method_tiling_generator4(nfold, lines, shift)
    break;

    case "gen_experiment5":
          my_dual_method_tiling_generator5(nfold, lines, shift)
    break;

    case "gen_experiment6":
          my_dual_method_tiling_generator6(nfold, lines, shift)
    break;
    case "gen_experiment7":
          my_dual_method_tiling_generator7(nfold, lines, shift)
    break;



    case "Square": make_square_tiling(xmax, ymax); break;
    case "Tetrakis_Square": make_tetrakis_square_tiling(xmax, ymax); break;
    case "Cairo": make_cairo_tiling(xmax, ymax); break;
    case "Truncated_Square": make_truncated_square_tiling(xmax, ymax); break;
    case "Snub_Square" :  make_snub_square_tiling(xmax, ymax); break;
    case "Regular_Trianglular" :  make_regular_triangular_tiling(xmax, ymax); break;
    case "Hexagonal" :  make_hexagonal_tiling_from_triangles(xmax, ymax); break;
    case "Rhombille" :  make_regular_rhombic_tiling(xmax, ymax); break;
    case "Trihexagonal" :  make_trihexagonal_tiling(xmax, ymax); break;
    case "Truncated_Hexagonal" :  make_truncated_hexagonal_tiling(xmax, ymax); break;
    case "Rhombitrihexagonal" :  make_rhombitrihexagonal_tiling_from_triangles(xmax, ymax); break;
    case "Deltoidal_Trihexagonal": make_deltoidal_trihexagonal_tiling (xmax, ymax); break;
    case "Floret_Pentagonal" :  make_floret_pentagonal_tiling(xmax, ymax); break;
    case "Triakis_Triangular" :  make_triakis_triangular_tiling(xmax, ymax); break;
    case "Truncated_TriHexagonal" :  make_truncated_trihexagonal_tiling(xmax, ymax); break;
    case "Kisrhombille" :  make_kisrhombille_tiling (xmax, ymax); break;
    case  "Snub_Trihexagonal" :  make_snub_trihexagonal_tiling(xmax, ymax);  break;
    case  "Elongated_Triangular" :  make_elongated_triangular_tiling(xmax, ymax); break; 
    case  "Prismatic_Pentagonal" :  make_prismatic_pentagonal_tiling(xmax, ymax); break; 

    case "Spiral" :  call_offset_circles (n_rings); break;
    case "Circular": call_concentric_circles (n_rings); break;


    case "Martini" : make_martini_lattice_tiling (xmax,ymax); break;
    case "durer_pentagon_and_thinrhomb_periodic" : make_durer_pentagon_and_thinrhomb_periodic_tiling(xmax, ymax); break;

    case "durer_pentagon_and_thinrhomb_periodic" : make_durer_pentagon_and_thinrhomb_periodic_tiling(xmax, ymax); break;
    case "durer_pentagon_and_thinrhomb_radial" : Durer_Nonperiodic_module.make_Durer_Radial_Tiling(recursion_level,single_or_rosette); break;
    case "durer_pentagon_and_thinrhomb_spiral" : Durer_Nonperiodic_module.make_Durer_Spiral_Tiling(recursion_level,single_or_rosette); break;
    case "Kepler_Aa_Radial" : Kepler_Aa_module.make_Kepler_Aa_Tiling(recursion_level,single_or_rosette) ; break;

   // there should be a default case here

   } 
}




//   *************************
//     Transform  Section

// from http://jsfiddle.net/DRf9P/
// from http://stackoverflow.com/questions/9461397/how-to-detect-point-on-canvas-after-canvas-rotation

// See also:  possibly a built in way:  http://stackoverflow.com/questions/14521058/returning-un-transformed-mouse-coordinates-after-rotating-an-object-on-html5-can

// Last updated November 2011
// By Simon Sarris
// www.simonsarris.com
// [email protected]
//
// Free to use and distribute at will
// So long as you are nice to people, etc

// Simple class for keeping track of the current transformation matrix

// For instance:
//    var t = new Transform();
//    t.rotate(5);
//    var m = t.m;
//    ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);

// Is equivalent to:
//    ctx.rotate(5);

// But now you can retrieve it :)

// Remember that this does not account for any CSS transforms applied to the canvas

function Transform() {
  this.reset();
}

Transform.prototype.reset = function() {
  this.m = [1,0,0,1,0,0];
};

Transform.prototype.multiply = function(matrix) {
  var m11 = this.m[0] * matrix.m[0] + this.m[2] * matrix.m[1];
  var m12 = this.m[1] * matrix.m[0] + this.m[3] * matrix.m[1];

  var m21 = this.m[0] * matrix.m[2] + this.m[2] * matrix.m[3];
  var m22 = this.m[1] * matrix.m[2] + this.m[3] * matrix.m[3];

  var dx = this.m[0] * matrix.m[4] + this.m[2] * matrix.m[5] + this.m[4];
  var dy = this.m[1] * matrix.m[4] + this.m[3] * matrix.m[5] + this.m[5];

  this.m[0] = m11;
  this.m[1] = m12;
  this.m[2] = m21;
  this.m[3] = m22;
  this.m[4] = dx;
  this.m[5] = dy;
};

Transform.prototype.invert = function() {
  var d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]);
  var m0 = this.m[3] * d;
  var m1 = -this.m[1] * d;
  var m2 = -this.m[2] * d;
  var m3 = this.m[0] * d;
  var m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]);
  var m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]);
  this.m[0] = m0;
  this.m[1] = m1;
  this.m[2] = m2;
  this.m[3] = m3;
  this.m[4] = m4;
  this.m[5] = m5;
};

Transform.prototype.rotate = function(rad) {
  var c = Math.cos(rad);
  var s = Math.sin(rad);
  var m11 = this.m[0] * c + this.m[2] * s;
  var m12 = this.m[1] * c + this.m[3] * s;
  var m21 = this.m[0] * -s + this.m[2] * c;
  var m22 = this.m[1] * -s + this.m[3] * c;
  this.m[0] = m11;
  this.m[1] = m12;
  this.m[2] = m21;
  this.m[3] = m22;
};

Transform.prototype.translate = function(x, y) {
  this.m[4] += this.m[0] * x + this.m[2] * y;
  this.m[5] += this.m[1] * x + this.m[3] * y;
};

Transform.prototype.scale = function(sx, sy) {
  this.m[0] *= sx;
  this.m[1] *= sx;
  this.m[2] *= sy;
  this.m[3] *= sy;
};

Transform.prototype.transformPoint = function(px, py) {
  var x = px;
  var y = py;
  px = x * this.m[0] + y * this.m[2] + this.m[4];
  py = x * this.m[1] + y * this.m[3] + this.m[5];
  return [px, py];
};

//    End of the Transform section
//***********************************

function radians (deg) {
   return  deg*Math.PI/180 
} 

function sq(n) {
        return Math.pow(n, 2)
}
    



// Template for tiling modules
/*
var tilingname_module = (function () {


       var outsideacess = {}
 
       outsideacess.make_tilingname_Tiling = function (n) {
 
            maxLevel = n;

            draw_startshape(0, 0, 100, 0, 1); 
         }



	return outsideacess;
}());

*/




    //  Credit and many thanks to Rune Madsen 
   //  Need to say more about Rune's very helpful contribution in a more prominent place!
     


var AmmannBeenker_module = (function () {


       var outsideacess = {}
 
       var maxLevel;  
       var sigdigits = 4;

       var magic = 1+Math.sqrt(2);
       var t = new Transform();

       outsideacess.make_AmmannBeenker_Tiling = function (n, single_or_rosette) {
          maxLevel = n;
          if (single_or_rosette == "single") {
          //    drawRectangle(0, 0, 100, 0, 1); 
          drawRhombus(0, 0, 100, 0, 1); 



          }
          else {
              for (var i = 0; i<360; i+=45) {  
                 drawRhombus(0, 0, 100, i, 1);   // rosette of rhombs
              }
           }
         }





        function drawRhombus(  x,   y,   diagonal,   deg,  level)  {
 
            var  sideLength = (diagonal / 2.0) / Math.cos(radians(45.0/2));


            t.translate(x,y);
            t.rotate(deg*Math.PI/180);
            
  
            var  myXskew =   Math.sin(radians(45.0)) * sideLength;
            var  myYskew =   Math.cos(radians(45.0)) * sideLength
        
 

            if (level == maxLevel) {
                 var coords =  [[0,0], [0, sideLength], [myXskew, myYskew + sideLength], [myXskew, myYskew]]
                 for (var i = 0; i<=3; i++) {
                      coords[i] = t.transformPoint(coords[i][0],coords[i][1])
                 }
                 build_verts_and_faces(coords, "rhomb")
            } 


            else { // (level < maxLevel) 
                var  shortDiagonal = Math.sin(radians(45.0/2.0)) * sideLength;
    
                drawRhombus(0.0, 0.0, shortDiagonal * 2.0, 0.0, level + 1);
                drawRhombus(0.0, 0.0 + sideLength, shortDiagonal * 2.0, -90, level + 1);
                drawRhombus(myXskew, myYskew + sideLength, shortDiagonal * 2.0, -180, level + 1);
    
                var  rectSide = (shortDiagonal / 2.0) / Math.cos(radians(45.0/2.0));
                var  rectDiagonal = rectSide * Math.sqrt(2); // have to be multiplied by 2
    
                drawRectangle(myXskew - (rectSide * 2.0), rectDiagonal + (rectSide * 2.0), rectSide * 2.0, -90, level + 1);
                drawRectangle(myXskew + (rectDiagonal), myYskew + (rectDiagonal), rectSide * 2.0, 135, level + 1);
                drawRectangle(-rectDiagonal, sideLength - rectDiagonal, rectSide * 2.0, -45, level + 1);
                drawRectangle(rectSide * 2.0, sideLength, rectSide * 2.0, 90, level + 1);
            }
  
            t.rotate(radians(-deg));
            t.translate(-x,-y);
        }

        function drawRectangle(  x,   y,   sideLength,   deg,  level)  {
    
            t.translate(x,y);
            t.rotate(deg*Math.PI/180);
 
            if(level == maxLevel) {
                var coords =  [[0,0], [sideLength, 0], [sideLength, sideLength], [0, sideLength]]
                for (var i = 0; i<=3; i++) {
                      coords[i] = t.transformPoint(coords[i][0],coords[i][1])
                 }
                 build_verts_and_faces(coords,  "square");

            }


          if(level < maxLevel)   {

                var  shortRectSide = sideLength / magic;
                var  shortRectDiagonal = shortRectSide * Math.sqrt(2);
        
                drawRectangle(shortRectDiagonal/2, shortRectDiagonal / 2, shortRectSide, 135, level + 1);
                drawRectangle(shortRectDiagonal/2 + shortRectSide, shortRectDiagonal / 2 + shortRectSide, shortRectSide, 180, level + 1);
                drawRectangle(sideLength - (shortRectDiagonal/2), (shortRectDiagonal / 2), shortRectSide, -135, level + 1);
                drawRectangle(sideLength + (shortRectDiagonal / 2), (shortRectDiagonal / 2), shortRectSide, 135, level + 1);
                drawRectangle(sideLength - (shortRectDiagonal/2), sideLength + (shortRectDiagonal / 2), shortRectSide, -135, level + 1);
    
                var  rhompDiagonal = Math.cos(radians(45.0/2.0)) * shortRectSide;
                drawRhombus(0, 0, rhompDiagonal * 2, -45, level + 1);
                drawRhombus(0, sideLength, rhompDiagonal * 2.0, -90, level + 1);
                drawRhombus(0, sideLength, rhompDiagonal * 2.0, -135, level + 1);
                drawRhombus(sideLength - (shortRectDiagonal/2),  shortRectDiagonal / 2, rhompDiagonal * 2, 0, level + 1);
          }
  
        t.rotate(radians(-deg));
        t.translate(-x,-y);
        }


	return outsideacess;
}());



var AmmannA4_module = (function() {
    
    
    var outsideacess = {}
    var t = new Transform();
    
    var factor = Math.sqrt(2);
    
    var maxLevel;
    var startSize = 400;
    
    
    
    outsideacess.make_AmmannA4_Tiling = function(n, single_or_rosette) {
                  maxLevel = n;

        
        
        drawHourGlass(0, 0, startSize, 0, 1);
    
    }
    
    
    
    
    function drawReverseChair(x, y, p, deg, level) {
        t.translate(x, y);
        t.rotate(radians(deg));
        
        var q = p * factor; // I think this is correct but try variants
        
        if (level == maxLevel) {
            
            var coords = [[0, 0], [0, p], [0, q], [0, p + q + p], [p, p + q + p], [p, p + q], [q + p, p + q], [q + p, 0]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "chair");
        } 
        else if (level < maxLevel) {
            var newP = p / (1 + factor);
            var newQ = newP * factor;
            drawHourGlass(p + q, 0, newP, 90, level + 1);
            drawBastyChair(0, newP + newQ, newP, -90, level + 1);
            drawReverseChair(p + q, p + q, newP, 180, level + 1);
            drawHourGlass(0, newP + newQ, newP, 0, level + 1);
            drawBastyChair(newP + newQ, p + q + p, newP, 180, level + 1);
        
        
        }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
    
    }
    
    function drawBastyChair(x, y, p, deg, level) {
        t.translate(x, y);
        t.rotate(deg * Math.PI / 180);
        var q = p * factor; // I think this is correct but try variants
        
        if (level == maxLevel) {
            var coords = [[0, 0], [0, p + q], [q, p + q], [q, p + q + p], [q + p, p + q + p], [q + p, q], [q + p, p], [q + p, 0]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "chair");
        
        } 
        else if (level < maxLevel) {
            var newP = p / (1 + factor);
            var newQ = newP * factor;
            drawHourGlass(0, 0, newP, 0, level + 1);
            drawBastyChair(newP + newQ, newP + newQ + newP + newQ + newP, newP, 180, level + 1);
            drawReverseChair(p + q, 0, newP, 90, level + 1);
            drawHourGlass(newP + newQ + newP + newP + newQ, newP + newQ, newP, 90, level + 1);
            drawReverseChair(p + q, p + q + p, newP, 180, level + 1);
        
        }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
    
    }
    
    function drawHourGlass(x, y, p, deg, level) { //  no need for flip here
        t.translate(x, y);
        t.rotate(deg * Math.PI / 180);
        var q = p * factor; // I think this is correct but try variants
        
        if (level == maxLevel) {
            
            
            var coords = [[0, 0], [0, p], [0, p + q], [p, p + q], [p, p + q + p], [p + q, p + q + p], [p + q + p, p + q + p], [p + q + p, p + q], [p + q + p, p], [p + q, p], [p + q, 0], [p, 0]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "chair");
        
        } 
        else if (level < maxLevel) {
            var newP = p / (1 + factor);
            var newQ = newP * factor;
            drawHourGlass(0, 0, newP, 0, level + 1);
            drawBastyChair(newP + newQ, newP + newP + newQ + newQ + newP, newP, 180, level + 1);
            
            
            drawReverseChair(newP + newP + newQ + newQ + newP, 0, newP, 90, level + 1);
            
            
            drawHourGlass(newP + newQ + newP + newQ + newP, newQ + newP, newP, 90, level + 1);
            drawBastyChair(newP + newP + newQ + newQ + newP, newP + newQ, newP, 0, level + 1);
            
            
            drawReverseChair(newP + newQ, p + q + p, newP, 270, level + 1);
            
            
            drawHourGlass(newP + newQ + newQ + newP, newQ + newP + newQ + newP, newP, 0, level + 1);
        
        
        }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
    
    }
    
    
    return outsideacess;
}());






var ChairTiling_module = (function() {
    
    var outsideacess = {}
    var t = new Transform();

    // Source:  https://github.com/runemadsen/prvaring-code/blob/master/code/repetition/aperiodic_tiling/aperiodic_tiling.pde

    // Substitution rule:
    // http://web.media.mit.edu/~black/tiles/aperiodic.html
    
    var maxLevel;
    var startSize;
    
    outsideacess.make_Chair_Tiling = function(n, single_or_rosette) {


        sigdigits = 8
        alert("changing sigdigits!")

        maxLevel = n;
        
        startSize = 500;
        drawL(0, 0, startSize, 0, 0);
    }
    
    function drawL(x, y, sideLength, deg, level) {
        t.translate(x, y);
        t.rotate(radians(deg));
        if (level == maxLevel) {
            var coords = [[0, 0], [0, sideLength / 2], [0, sideLength], [sideLength / 2, sideLength], [sideLength, sideLength], [sideLength, sideLength / 2], [sideLength / 2, sideLength / 2], [sideLength / 2, 0]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "chair");
        }
        
        if (level < maxLevel) 
        {
            level++;
            
            drawL(sideLength / 4, sideLength / 4, sideLength / 2, 0, level);
            drawL(sideLength / 2, 0, sideLength / 2, 90, level);
            drawL(0, sideLength / 2, sideLength / 2, 0, level);
            drawL(sideLength / 2, sideLength, sideLength / 2, 270, level);
        }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
    }
    
    return outsideacess;
}());



var DanzerT2000_module = (function() {
    
    var outsideacess = {}
    var t = new Transform();

    //  Source:  https://github.com/runemadsen/prvaring-code/blob/master/code/repetition/aperiodic_tiling2/aperiodic_tiling2.pde

    // Substitution rule:
    // http://tilings.math.uni-bielefeld.de/substitution_rules/t2000
    
    var factor = Math.sqrt(3);
    
    outsideacess.make_DanzerT2000_Tiling = function(n, single_or_rosette) {
        maxLevel = n;

        // draw single triangle
        
        startSize = 200;
        drawTriangle(0, 0, startSize, 180+60, 0, false);
    }
    

    function drawTriangle(x, y, bottomSize, deg, level, drawSingle) {
        // pythagoras theorem on half right-sided triangle
        var b = bottomSize / 2;
        var c = bottomSize / factor;
        var a = Math.sqrt(sq(c) - sq(b)); // a2 + b2 = c2
        
        t.translate(x, y);
        t.rotate(radians(deg));
        
        if (level == maxLevel) {
            var coords = [[0, 0], [-b, a], [b, a]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "triangle");
        
        }
        
        if (drawSingle && level < maxLevel) {
            level++;
            drawTriangle(0, 0, bottomSize, 0, level, false);
        } 
        else if (level < maxLevel) {
            level++;
            
            drawTriangle(-(a / factor), a, c, 150, level, false);
            drawTriangle(a / factor, a, c, -150, level, false);
            
            var childBottom = c / factor;
            var childB = childBottom / 2;
            var childC = childBottom / factor;
            var childA = Math.sqrt(sq(childC) - sq(childB)); // a2 + b2 = c2

            // all these small triangles should draw a big one, not subdivide immediately. 
            drawTriangle(0, a - childA, childBottom, 0, level, true);
            drawTriangle(0, a - childA, childBottom, 120, level, true);
            drawTriangle(0, a - childA, childBottom, -120, level, true);
        }
        
        t.rotate(radians(-deg));
        t.translate(-x, -y);
    }
    
    return outsideacess;
}());

var domino_module = (function() {
    
    var outsideacess = {}
    var t = new Transform();

var maxLevel;

    outsideacess.make_domino_Tiling = function(n, single_or_rosette) {
                  maxLevel = n;

        sigdigits = 8
        alert("changing sigdigits!")



  var startSize = 980;

  drawL(0, 0, startSize, 90, 0);
}

function drawL( x,  y,  sideLength,  deg,  level) {
        t.translate(x, y);
        t.rotate(radians(deg));

  if (level == maxLevel) {

 
            var coords = [[0,0],[sideLength/2, 0],[sideLength/2,sideLength/2], [sideLength/2,sideLength],[0,sideLength], [0,sideLength/2]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "domino");


 }
  if(level < maxLevel) {
    level++;
    
    drawL(0, sideLength/4, sideLength/2, -90, level);
    drawL(0, sideLength/4, sideLength/2, 0, level);
    drawL(sideLength/4,sideLength/4, sideLength/2, 0, level);
    drawL(0, sideLength, sideLength/2, -90, level);
  }

       t.rotate(radians(-deg));
        t.translate(-x, -y);
    
    }
    
    
    return outsideacess;
}());





// Penrose credits and thanks (this should be expanded upon.
// http://preshing.com/20110831/penrose-tiling-explained/    
// and
// In  the above link, see Tim Hutton's comment  on Kites and Darts.
// and
// https://github.com/daneroo/im-penrose (translated Preshing's code into javascript!)

var Penrose_module = (function() {

    
    var outsideacess = {}
    
  outsideacess.make_Penrose_Tiling = function(type, NUM_SUBDIVISIONS, single_or_rosette) {
      make_Penrose_Tiling_aux(type,  NUM_SUBDIVISIONS, single_or_rosette)
  }


//------ Configuration --------
//NUM_SUBDIVISIONS = 7;
//-----------------------------
// 5 subdivisions  = 430 Rhomb cells


var goldenRatio = (1 + Math.sqrt(5)) / 2;

// P = A + (B - A) / goldenRatio;
function midpoint(A,B){
  var P = {
    x: A.x + (B.x-A.x) / goldenRatio,
    y: A.y + (B.y-A.y) / goldenRatio
  }
  return P;
}
function subdivide_Penrose_Rhombs(triangles){
  var result = [];
  triangles.forEach(function(triangle){
    var color=triangle.color,A=triangle.A,B=triangle.B,C=triangle.C
    if (color===0){
      // # Subdivide red triangle
      // P = A + (B - A) / goldenRatio;
      var P = midpoint(A,B)
      result.push({color:0, A:C, B:P, C:B}, {color:1, A:P, B:C, C:A});
    } else {
      // # Subdivide blue triangle
      // Q = B + (A - B) / goldenRatio;
      var Q = midpoint(B,A);
      // R = B + (C - B) / goldenRatio;
      var R = midpoint(B,C);
      result.push({color:1, A:R, B:C, C:A}, {color:1, A:Q, B:R, C:B}, {color:0, A:R, B:Q, C:A});
    }
  });
  return result;
}

// Tim Hutton's Kite and Darts version
function subdivide_Kites_and_Darts(triangles){
  var result = [];
  triangles.forEach(function(triangle){
    var color=triangle.color,A=triangle.A,B=triangle.B,C=triangle.C
    if (color===0){
            //  Subdivide red (sharp isosceles) (half kite) triangle 
           // Q = A + (B - A) / goldenRatio 
          var Q = midpoint(A, B)
          //  R = B + (C - B) / goldenRatio 
          var R = midpoint(B, C)
           // result += [(1, R, Q, B), (0, Q, A, R), (0, C, A, R)] 
          result.push({color:1, A:R, B:Q, C:B}, {color:0, A:Q, B:A, C:R}, {color:0, A:C, B:A, C:R});

    } else {
            // Subdivide blue (fat isosceles) (half dart) triangle 
            // P = C + (A - C) / goldenRatio 
           var P = midpoint(C, A)

            // result += [(1, B, P, A), (0, P, C, B)] 
           result.push({color:1, A:B, B:P, C:A}, {color:0, A:P, B:C, C:B});

    }
  });
  return result;
}


function toRect(r, phi){
  // Return the complex number x with polar coordinates r and phi. Equivalent to r * (math.cos(phi) + math.sin(phi)*1j).
  return {
    x: r*Math.cos(phi),
    y: r*Math.sin(phi)
  };
}



// visit http://www.sb.fsu.edu/~caspar/201/
function make_Penrose_Tiling_aux (type,NUM_SUBDIVISIONS, single_or_rosette ) { 

   // # Create wheel of red triangles around the origin
   var triangles = [];
   var numberoftriangles;
   if (single_or_rosette == "single") {numberoftriangles = 2} else {numberoftriangles = 10}
   for (var i=0;i<numberoftriangles;i++){   // two triangles instead of 10? (One thick rhomb instead of five rhombs)

     var B = toRect(100, (2*i - 1) * Math.PI / 10);   // also tried startsizes of 500 instead of 1
     var C = toRect(100, (2*i + 1) * Math.PI / 10);    // also tried startsizes of 500 instead of 1
     if (i % 2 === 0){ //# Make sure to mirror every second triangle
       var t=B;
       B=C;
       C=t;
     }
     if (type == "rhombs" || type == "Robinson") {
       triangles.push({color:0,A:{x:0,y:0}, B:B, C:C});
     }
     else {  // type == "kites" || type == "P1"
       triangles.push({color:0,A:B, B:{x:0,y:0}, C:C});
     }
   }

   // # Perform subdivisions
   if (type == "rhombs" || type == "Robinson") {
     for (var i=0;i<NUM_SUBDIVISIONS;i++){
       triangles = subdivide_Penrose_Rhombs(triangles);
     }
   }
   else {  // type == "kites" || type == "P1"
    for (var i=0;i<NUM_SUBDIVISIONS;i++){
       triangles = subdivide_Kites_and_Darts(triangles);
     }
   }


  if (type == "Robinson") {
     for (var i = triangles.length; i--;) {
       if (triangles[i].color == 0) {
           build_verts_and_faces( [[ triangles[i].B.x, triangles[i].B.y ],
                                   [ triangles[i].A.x, triangles[i].A.y ],
                                   [ triangles[i].C.x, triangles[i].C.y ]], "Thin Triangle")
       } else {
           build_verts_and_faces( [[ triangles[i].B.x, triangles[i].B.y ],
                                   [ triangles[i].A.x, triangles[i].A.y ],
                                   [ triangles[i].C.x, triangles[i].C.y ]], "Thick Triangle")
       } 
     }
   } 
   else { // type != "Robinson"
   

  // now find pairs of triangles which can be combined to make a penrose tile

   var  x_thin = []
   var  y_thin = []

   var  x_fat = []
   var  y_fat = []
   var cx,cy,bx,by;
   var tempsigdigits = 5;
   
   var colorzero_name, colorone_name

   if (type == "rhombs") {colorzero_name = "thin rhomb"; colorone_name = "thick rhomb"}
   else {colorzero_name = "kite"; colorone_name = "dart"}

   for (var i = triangles.length; i--;) {
         cx  = roundNumber(triangles[i].C.x, tempsigdigits)
         bx  = roundNumber(triangles[i].B.x, tempsigdigits)
         cy  = roundNumber(triangles[i].C.y, tempsigdigits)
         by = roundNumber(triangles[i].B.y, tempsigdigits)


     if (triangles[i].color == 0) {  // thin triangles have color == 0


         if (x_thin[cx] == undefined) {x_thin[cx] = []}
         if (x_thin[bx] == undefined) {x_thin[bx] = []}
         if (y_thin[cy] == undefined) {y_thin[cy] = []}
         if (y_thin[by] == undefined) {y_thin[by] = []}

        var an_intersection = intersection_of_arrays(  x_thin[bx], x_thin[cx], 
                                            y_thin[by], y_thin[cy]  ) 
         if ( an_intersection.length == 1) { 
             var m = an_intersection[0]
             /*  original
             build_verts_and_faces( [ [ bx  , by  ],
                                      [ triangles[i].A.x   , triangles[i].A.y ],
                                      [ cx   , cy ],
                                      [ triangles[m].A.x   , triangles[m].A.y ]
                                     
                                    ], colorzero_name)  // "thin rhomb" or "kite"
           */
           build_verts_and_faces( [   [ triangles[m].A.x   , triangles[m].A.y ],
                                      [ bx  , by  ],
                                      [ triangles[i].A.x   , triangles[i].A.y ],
                                      [ cx   , cy ],
                                     
                                    ], colorzero_name)  // "thin rhomb" or "kite"

          }
          else {

                 x_thin[cx].push(i)
                 x_thin[bx].push(i)
                 y_thin[cy].push(i)
                 y_thin[by].push(i)
          }
     }
     else { // fat triangles have color == 1

         if (x_fat[cx] == undefined) {x_fat[cx] = []}
         if (x_fat[bx] == undefined) {x_fat[bx] = []}
         if (y_fat[cy] == undefined) {y_fat[cy] = []}
         if (y_fat[by] == undefined) {y_fat[by] = []}

        var an_intersection = intersection_of_arrays(  x_fat[bx], x_fat[cx], 
                                            y_fat[by], y_fat[cy]  ) 
         if ( an_intersection.length == 1) { 
             var m = parseFloat(an_intersection[0])
             /* original
             build_verts_and_faces( [ [ bx  , by  ],
                                      [ triangles[i].A.x   , triangles[i].A.y ],
                                      [ cx   , cy ],
                                      [ triangles[m].A.x   , triangles[m].A.y ]
                                     
                                    ], colorone_name)  // "thick rhomb" or "dart"
            */
             build_verts_and_faces( [ [ triangles[m].A.x   , triangles[m].A.y ],
                                      [ cx  , cy  ],
                                      [ triangles[i].A.x   , triangles[i].A.y ],
                                      [ bx   , by ],
                                    
                                     
                                    ], colorone_name)  // "thick rhomb" or "dart"
          }
          else {

                 x_fat[cx].push(i)
                 x_fat[bx].push(i)
                 y_fat[cy].push(i)
                 y_fat[by].push(i)
          }
     }
    } // end of for loop for all triangles
   } // end of type != "Robinson" else clause
} // end of make_penrose_rhombs function


//From: http://stackoverflow.com/questions/11076067/finding-matches-between-multiple-javascript-arrays
  // there are other ways to find the intersection of multiple arrays too.
  // for example, see the reference to the underscore library here: http://stackoverflow.com/questions/5837295/intersection-of-n-lists-via-js
  // my guess is that the underscore solution will be slow, because the library uses filter and other related native functions
  // which are (currently, at least) very slow. (They are slow because they handle all the bizarre cases that can't be rule out a priori)

// Pull this out of the Penrose module and make it  available to all -- it is useful

function intersection_of_arrays(/* pass all arrays here */) {
    var output = [];
    var cntObj = {};
    var array, item, cnt;
    // for each array passed as an argument to the function
    for (var i = 0; i < arguments.length; i++) {
        array = arguments[i];
        // for each element in the array
        for (var j = 0; j < array.length; j++) {
            item = "-" + array[j];
            cnt = cntObj[item] || 0;
            // if cnt is exactly the number of previous arrays, 
            // then increment by one so we count only one per array
            if (cnt == i) {
                cntObj[item] = cnt + 1;
            }
        }
    }
    // now collect all results that are in all arrays
    for (item in cntObj) {
        if (cntObj.hasOwnProperty(item) && cntObj[item] === arguments.length) {
            output.push(item.substring(1));
        }
    }
    return(output);
}    
   
   
    return outsideacess;
}());



// Double transform version
/*

var BinaryTiling_module = (function() {
    var outsideacess = {}
    var t = new Transform();
    var maxLevel;
    var startSize;
    var factor = Math.sqrt(5)/2 + 1/2  // But see below - this isn't the final factor


    outsideacess.make_Binary_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
        
        startSize = 500;
        drawThinRhomb(100,   100,  startSize,  36,  1)
    }

function drawThinRhomb( x,  y,  len,  rot,  level) {
  var rhombcoords = []
  var coords = []
  var t2 = new Transform();
  t.translate(x,y);
  t.rotate(rot*Math.PI/180);
  t2.translate(x,y);
  t2.rotate(rot*Math.PI/180);
     var a = 36.0*Math.PI/180    // 
     var x1, y1, x2, y2, x3, y3, x4, y4;
        x1 = 0
        y1 = 0
        
        x2 = len;
        y2 = 0;

         x3 = len + len*Math.cos(a);
         y3 = -len*Math.sin(a);
          
         x4 = len*Math.cos(a);
         y4 = -len*Math.sin(a);
     rhombcoords = [[x1,y1],  [x2,y2], [x3, y3], [x4, y4]] 
     coords = [[x1,y1],  [x2,y2], [x3, y3], [x4, y4]] 

	
 if (level == maxLevel) {
            for (var i = 0; i < coords.length; i++) {
                 coords[i] = t.transformPoint(coords[i][0], coords[i][1])
             }
            build_verts_and_faces(coords, "Thin Rhomb");
}
 if (level < maxLevel) {
    //  var newlen =len/factor;
      var newlen =len/factor/Math.sin(36*Math.PI/180)/2

        var temp = 
        drawThickRhomb (x1, y1, newlen, 18, level+1);
        var tempB = 
        drawThinRhomb (temp[1][0], temp[1][1], newlen, -18, level+1);
        drawThinRhomb (tempB[2][0], tempB[2][1], newlen, 180+18, level+1);


  }

        t.rotate(-rot*Math.PI/180);
        t.translate(-x, -y);
  for (var i = 0; i<=3; i++) {
      rhombcoords[i] = t2.transformPoint(rhombcoords[i][0],rhombcoords[i][1])
   }

   return rhombcoords
}




function drawThickRhomb( x,  y,  len,  rot,  level) {
  var rhombcoords = []
  var coords = []

  var t2 = new Transform();
  t.translate(x,y);
  t.rotate(rot*Math.PI/180);
  t2.translate(x,y);
  t2.rotate(rot*Math.PI/180);
     var a = 72.0*Math.PI/180    
     var x1, y1, x2, y2, x3, y3, x4, y4;

        x1 = 0
        y1 = 0
        
        x2 = len;
        y2 = 0;

         x3 = len + len*Math.cos(a);
         y3 = -len*Math.sin(a);
          
         x4 = len*Math.cos(a);
         y4 = -len*Math.sin(a);
     rhombcoords = [[x1,y1],  [x2,y2], [x3, y3], [x4, y4]] 
     coords = [[x1,y1],  [x2,y2], [x3, y3], [x4, y4]] 

 if (level == maxLevel) {
           for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "Thick Rhomb"); 
}

 if (level < maxLevel) {
      var newlen =len/factor/Math.sin(36*Math.PI/180)/2
      drawThickRhomb (x1, y1, newlen, -18, level+1);
      drawThickRhomb (x2, y2, newlen, -72-18, level+1);
      var temp = 
      drawThickRhomb (x3, y3, newlen, -72-72-18, level+1);
 drawThinRhomb(temp[1][0], temp[1][1], newlen, -72-72-36-18, level+1);

   }

        t.rotate(-rot*Math.PI/180);
        t.translate(-x, -y);
   for (var i = 0; i<=3; i++) {
      rhombcoords[i] = t2.transformPoint(rhombcoords[i][0],rhombcoords[i][1])
   }

   return rhombcoords
}


    return outsideacess;
}());


*/




var BinaryTiling_module = (function() {
    var outsideacess = {}
    var t = new Transform();
    var maxLevel;
    var startSize;
    var factor = Math.sqrt(5)/2 + 1/2  // But see below - this isn't the final factor


    outsideacess.make_Binary_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
        
        startSize = 500;

       //  drawThinRhomb(100,   100,  startSize,  36,  1)
       drawThickRhomb(100,   100,  startSize,  36,  1)
    }

function drawThinRhomb( x,  y,  len,  rot,  level) {
  var rhombcoords = []
  var coords = []
  t.translate(x,y);
  t.rotate(rot*Math.PI/180);
  var t2 = new Transform();
  t2.translate(x,y);
  t2.rotate(rot*Math.PI/180);
     var a = 36.0*Math.PI/180    // 
     var x1, y1, x2, y2, x3, y3, x4, y4;
        x1 = 0
        y1 = 0
        
        x2 = len;
        y2 = 0;

         x3 = len + len*Math.cos(a);
         y3 = -len*Math.sin(a);
          
         x4 = len*Math.cos(a);
         y4 = -len*Math.sin(a);
     rhombcoords = [[x1,y1],  [x2,y2], [x3, y3], [x4, y4]] 
     coords = [[x1,y1],  [x2,y2], [x3, y3], [x4, y4]] 

	
 if (level == maxLevel) {
            for (var i = 0; i < coords.length; i++) {
                 coords[i] = t.transformPoint(coords[i][0], coords[i][1])
             }
            build_verts_and_faces(coords, "Thin Rhomb");
}
 if (level < maxLevel) {
    //  var newlen =len/factor;
      var newlen =len/factor/Math.sin(36*Math.PI/180)/2

        var temp = 
        drawThickRhomb (x1, y1, newlen, 18, level+1);
        var tempB = 
        drawThinRhomb (temp[1][0], temp[1][1], newlen, -18, level+1);
        drawThinRhomb (tempB[2][0], tempB[2][1], newlen, 180+18, level+1);


  }

        t.rotate(-rot*Math.PI/180);
        t.translate(-x, -y);
  for (var i = 0; i<=3; i++) {
      rhombcoords[i] = t2.transformPoint(rhombcoords[i][0],rhombcoords[i][1])
   }

   return rhombcoords
}




function drawThickRhomb( x,  y,  len,  rot,  level) {
  var rhombcoords = []
  var coords = []

  t.translate(x,y);
  t.rotate(rot*Math.PI/180);
  var t2 = new Transform();
  t2.translate(x,y);
  t2.rotate(rot*Math.PI/180);
     var a = 72.0*Math.PI/180    
     var x1, y1, x2, y2, x3, y3, x4, y4;

        x1 = 0
        y1 = 0
        
        x2 = len;
        y2 = 0;

         x3 = len + len*Math.cos(a);
         y3 = -len*Math.sin(a);
          
         x4 = len*Math.cos(a);
         y4 = -len*Math.sin(a);
     rhombcoords = [[x1,y1],  [x2,y2], [x3, y3], [x4, y4]] 
     coords = [[x1,y1],  [x2,y2], [x3, y3], [x4, y4]] 

 if (level == maxLevel) {
           for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "Thick Rhomb"); 
}

 if (level < maxLevel) {
      var newlen =len/factor/Math.sin(36*Math.PI/180)/2
      drawThickRhomb (x1, y1, newlen, -18, level+1);
      drawThickRhomb (x2, y2, newlen, -72-18, level+1);
      var temp = 
      drawThickRhomb (x3, y3, newlen, -72-72-18, level+1);
 drawThinRhomb(temp[1][0], temp[1][1], newlen, -72-72-36-18, level+1);

   }

        t.rotate(-rot*Math.PI/180);
        t.translate(-x, -y);
   for (var i = 0; i<=3; i++) {
      rhombcoords[i] = t2.transformPoint(rhombcoords[i][0],rhombcoords[i][1])
   }

   return rhombcoords
}



    return outsideacess;
}());








var RhombSquareOctogon_module = (function() {

   
    var outsideacess = {}
    var t = new Transform();


var maxLevel;
var startSize = 400;

var factor = 2+Math.sqrt(2);


    outsideacess.make_RhombSquareOctogon_Tiling = function(n, single_or_rosette) {
                  maxLevel = n;

        
      

      drawOctagon(500,500, startSize, 0, 1);
 
}


function drawSquare(  x,   y,   len,   deg,   level) {
        t.translate(x, y);
        t.rotate(radians(deg));
  
     var x2 = len;
     var y2 = 0;

     var x3 = len;
     var y3 = -len;
     
     var x4 = 0;
     var y4 = -len;
     
  if (level == maxLevel) {
            var coords = [[0,0], [x2, y2],[ x3, y3], [x4, y4]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "square");
  }
  else {
    var newlen =  len/factor;  
    var centerx =  newlen +   Math.sqrt(sq(newlen)/2);  // (x4+x3)/2
    var centery = -( newlen + Math.sqrt(sq(newlen)/2));
    for (var i = 0; i<360; i = i+45) {
       draw8FoldRhombAndSquare (centerx, centery, newlen, i, level+1);
    }
  }
        t.rotate(radians(-deg));
        t.translate(-x, -y);}




function draw8FoldRhombAndSquare(  x,   y,   len,   deg,   level) {
        t.translate(x, y);
        t.rotate(radians(deg));
     var a = 45.0;    // 5 is 360/8, so good for 8fold tilings.
     
     var x2 = len;
     var y2 = 0;

     var x3 = len + len*Math.cos(radians(a));
     var y3 = -len*Math.sin(radians(a));
     
     var x4 = len*Math.cos(radians(a));
     var y4 = -len*Math.sin(radians(a));
     
  drawSquare(x3, y3, len, 135, level);

  if (level == maxLevel) {
 
            var coords = [[0,0], [x2, y2],[ x3, y3], [x4, y4]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "rhomb");

  }
   else {
      var newlen =len/factor;

      draw8FoldRhombAndSquare (0, 0, newlen, 0, level+1);
      draw8FoldRhombAndSquare (x3, y3, newlen, 180, level+1);
      drawOctagon(x2,y2, newlen,225, level+1);


   }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
}

function drawOctagon(  x,   y,   L,   deg,   level) {
        t.translate(x, y);
        t.rotate(radians(deg));
     var z = L * Math.sqrt(2)/2;
     
     var centerx = (L + L*Math.sqrt(2))/2;
     var centery =  L/2;
     
     var ax = 0;
     var ay = 0;     
    
     var bx = 0;
     var by = L;  
     
     var cx = z ;
     var cy = L+z ;
     
     var dx = L + z;
     var dy = L + z;
     
     var ex = L + z*2;
     var ey = L;   
     
     var fx =L +z* 2 ;
     var fy =0 ;    
     
     var gx = L +z;
     var gy = -z;  
     
     var hx =z ;
     var hy = -z ;     
  if (level >= maxLevel) {
  
            var coords = [[ax,ay], [bx, by],[ cx, cy], [dx, dy], [ex, ey], [fx, fy], [gx, gy], [hx, hy] ]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "octogon");          
  }
  else {
    var newlen = L/factor;
    drawOctagon(ax, ay,  newlen, 0,  level+1);
    drawOctagon(bx, by,  newlen, -45,  level+1);
    drawOctagon(cx, cy,  newlen, -90,  level+1);
    drawOctagon(dx, dy,  newlen, -135,  level+1);
    drawOctagon(ex, ey,  newlen, -180,  level+1);
    drawOctagon(fx, fy,  newlen, -225,  level+1);
    drawOctagon(gx, gy,  newlen, -270,  level+1);
    drawOctagon(hx, hy,  newlen, -315,  level+1);
    for (var i = 0; i<360; i = i+45) {
       draw8FoldRhombAndSquare (centerx, centery, newlen, i, level+1);
    }
    drawSquare(ax, ay + newlen,  newlen, 135,  level+1);
    drawSquare(cx +newlen, cy,  newlen, 45,  level+1);
    drawSquare(ex, ey - newlen,  newlen, 315,  level+1);
    drawSquare(gx -newlen, gy,  newlen, 225,  level+1);

    drawSquare(bx +newlen/Math.sqrt(2), by+newlen/Math.sqrt(2),  newlen, 90,  level+1);
    drawSquare(dx +newlen/Math.sqrt(2), by+newlen/Math.sqrt(2),  newlen, 90,  level+1);
    drawSquare(dx +newlen/Math.sqrt(2), fy-+newlen/Math.sqrt(2),  newlen, 0,  level+1);
    drawSquare(bx +newlen/Math.sqrt(2), fy-+newlen/Math.sqrt(2),  newlen, 0,  level+1);


  }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
}

    
    return outsideacess;
}());


var Pinwheel_module = (function() {
    
    
    var outsideacess = {}
    var t = new Transform();

    var maxLevel;
    var factor = 1/Math.sqrt(5);

    outsideacess.make_Pinwheel_Tiling = function(n, single_or_rosette) {
          maxLevel = n;
          var startSize = 300;
         // drawInverseTri(0, 0, startSize, 0, 1);
//drawTri(2*startSize, -startSize, startSize, 180, 1);  // a good single tile

 // drawTri(2*startSize, -startSize, startSize, 180, 1); // good pair
 // drawTri(0,0,  startSize, 0, 1)

  drawTri(startSize, 2*startSize, startSize, 270, 1);
  drawTri(0,0,  startSize, 90, 1)


    }


var smallangle = Math.atan(0.5)*180/Math.PI;
var bigangle = 90 - smallangle;

function  drawTri( x,  y,  sideLength,  deg,  level)
{
        t.translate(x, y);
        t.rotate(radians(deg));
   if (level >= maxLevel) {
        // triangle(0,0,        2*sideLength, 0,           2*sideLength, -sideLength);  
        //  ellipse(sideLength,0,10,10);  // intermediate vertice

            var coords = [[0,0], [sideLength,0], [2*sideLength, 0], [2*sideLength, -sideLength] ]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "triangle");
   } else
  if(level < maxLevel)
  {
     drawInverseTri(2*sideLength, 0, sideLength*factor, bigangle, level + 1);
     drawInverseTri(0, 0, sideLength*factor, bigangle+90, level + 1);
     drawInverseTri(sideLength, 0, sideLength*factor, bigangle+90, level + 1);
     drawTri(sideLength, 0, sideLength*factor, 180+bigangle+90, level + 1);
     drawTri(Math.cos(radians(smallangle))*sideLength*factor*4,-Math.sin(radians(smallangle))*sideLength*factor*4, sideLength*factor, 180-smallangle, level + 1);
  }

        t.rotate(radians(-deg));
        t.translate(-x, -y);
}

function  drawInverseTri( x,  y,  sideLength,  deg,  level)
{
        t.translate(x, y);
        t.rotate(radians(deg));
   if (level >= maxLevel) {
          // triangle(0,0, -2*sideLength,0,  -2*sideLength,-1*sideLength);  
          // ellipse(-sideLength,0,10,10);  // intermediate vertice

            var coords = [[0,0], [-sideLength,0], [-2*sideLength, 0], [-2*sideLength, -sideLength] ]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "triangle");


   } else
  if(level < maxLevel)
  {
     drawTri(-2*sideLength, 0, sideLength*factor, 180-bigangle+180, level + 1);
     drawTri(0, 0, sideLength*factor, 180-bigangle+90, level + 1);
     drawTri(-sideLength, 0, sideLength*factor,180- bigangle+90, level + 1);
     drawInverseTri(-sideLength, 0, sideLength*factor, 180-bigangle+90+180, level + 1);
     drawInverseTri(-Math.cos(radians(smallangle))*sideLength*factor*4,-Math.sin(radians(smallangle))*sideLength*factor*4, sideLength*factor, smallangle+180, level + 1);
  }

        t.rotate(radians(-deg));
        t.translate(-x, -y);
}

    
    return outsideacess;
}());


var Shield_module = (function() {
    
    
    var outsideacess = {}
    var t = new Transform();


var  factor = Math.sqrt (2 + Math.sqrt (3));
var maxLevel;

    outsideacess.make_Shield_Tiling = function(n, single_or_rosette) {
                  maxLevel = n;


  var startSize = 500;

  drawSquare(0,0, startSize, 0, 1);

 // drawTri1(0, 0, startSize, 0, 1);
 //drawTri22(0, 0, startSize, 0, 1);

}
              
function drawTri1(  x,   y,   bottomSize,   deg,  level) 
{
        t.translate(x, y);
        t.rotate(radians(deg));
        
  var  b = bottomSize / 2; 
  var  h = (bottomSize*Math.sqrt (3))/2;


  if (level >= maxLevel) {
            var coords = [[0.0,0.0], [-b, h], [b, h]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "triangle");

   }
   else {
  
   // Let the points of the shield be a through f, starting at the top and going clockwise around the sheild.
   var  ax = 0;
   var  ay = 0;

   var  bx =    bottomSize/factor/factor/2  + (bottomSize/factor/factor*Math.sqrt (3))/2;
   var  by =    bottomSize/factor/factor/2  + (bottomSize/factor/factor*Math.sqrt (3))/2;
   
   var  cx = b;
   var  cy = h;
   
   var  dx = 0;
   var  diff = h - Math.sqrt (sq(bottomSize/factor) *2); 
   var  dy = diff + h;
   
   var  ex = -b;
   var  ey = h;
   
   var  fx = -(bottomSize/factor/factor/2  + (bottomSize/factor/factor*Math.sqrt (3))/2);
   var  fy =  bottomSize/factor/factor/2  + (bottomSize/factor/factor*Math.sqrt (3))/2;
   
   drawShield(ax,ay,bx,by,cx,cy,dx,dy,ex, ey,fx, fy, bottomSize/factor, level+1); 
  }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
}


function drawTri22(  x,   y,   bottomSize,   deg,  level) 
{
        t.translate(x, y);
        t.rotate(radians(deg));
        


 if (level >= maxLevel) {

     var  b = bottomSize / 2; 
     var  h = (bottomSize*Math.sqrt (3))/2;


            var coords = [[0.0,0.0], [-b, h], [b, h]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "triangle");



 }
 else {
  
     drawSquare(0,0,bottomSize/factor, 45, level+1);
     drawTri22(0, Math.sqrt (sq(bottomSize/factor) *2), bottomSize/factor, 105, level+1);
     drawTri22(0, Math.sqrt (sq(bottomSize/factor) *2), bottomSize/factor, -105, level+1);

 }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
}



function drawSquare(  x,   y,   bottomSize,   deg,  level)
{
        t.translate(x, y);
        t.rotate(radians(deg));

  if (level >= maxLevel) {
            var coords = [[0.0,0.0], [0, bottomSize], [bottomSize, bottomSize], [bottomSize, 0]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "square");


  }
  else {

     var  WestBoxCornerX = bottomSize - (bottomSize*Math.sqrt (3))/2;
     var  WestBoxCornerY = bottomSize/2 ;
     drawTri1( WestBoxCornerX, WestBoxCornerY,  bottomSize/factor,  -165,  level + 1);
     drawTri1( WestBoxCornerX, WestBoxCornerY,  bottomSize/factor,  -15,  level + 1);
     
     var  NorthBoxCornerX = bottomSize/2 ;   
     var  NorthBoxCornerY = bottomSize - (bottomSize*Math.sqrt (3))/2;
     drawTri1(NorthBoxCornerX, NorthBoxCornerY, bottomSize/factor, 285,  level + 1);
     
     var  SouthBoxCornerX = bottomSize/2 ; 
     var  SouthBoxCornerY = (bottomSize*Math.sqrt (3))/2;
     drawTri1( SouthBoxCornerX, SouthBoxCornerY,  bottomSize/factor, -105,  level + 1);
     
     var  EastBoxCornerX = WestBoxCornerX + Math.sqrt (sq(bottomSize/factor)+sq(bottomSize/factor));
     var  EastBoxCornerY = WestBoxCornerY;
     drawSquare(EastBoxCornerX, EastBoxCornerY  , bottomSize/factor, 135, level+1);
    }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
}

function drawShield(  ax,   ay,   bx,   by,  cx,  cy,  dx,  dy,  ex,   ey,   fx,   fy,   bottomSize,  level)
{  
     if (level == maxLevel) {

            var coords = [[ax,ay], [bx,by], [cx,cy], [dx,dy],[ex,ey],[fx,fy]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "shield");

      }
    else {

      drawSquare(ax-(bottomSize / 2)/factor,  ay+((bottomSize/factor)*Math.sqrt (3))/2+bottomSize/factor,  bottomSize/factor, -90,  level+1); 

      drawSquare(ax-(bottomSize / 2)/factor,  ay+((bottomSize/factor)*Math.sqrt (3))/2+bottomSize/factor,  bottomSize/factor, 60,  level+1); 
      drawSquare(ax-(bottomSize / 2)/factor+bottomSize/factor,  ay+((bottomSize/factor)*Math.sqrt (3))/2+bottomSize/factor,  bottomSize/factor, 30,  level+1); 
  
      drawTri1( ax, ay,  bottomSize/factor, 0,  level + 1); // Top triangle
    
   
      drawTri1( cx-bottomSize/factor, cy,  bottomSize/factor, -120,  level + 1);  // corner triangle
      drawTri1( ex+bottomSize/factor, ey,  bottomSize/factor, 120,  level + 1);   // corner triangle
    
      drawTri1(fx,  by+bottomSize/factor, bottomSize/factor, -150, level+1);  // left frhomb bottom
      drawTri1(bx,  by+bottomSize/factor,bottomSize/factor,   150, level+1);  // right rhomb bottom
   
      drawTri1(ax,  ay+((bottomSize/factor)*Math.sqrt (3))+bottomSize/factor, bottomSize/factor, 180, level+1);  // center triangle

      drawTri22(ax-(bottomSize / 2)/factor,  ay+((bottomSize/factor)*Math.sqrt (3))/2,  bottomSize/factor, 30, level+1);  //left rhomb top
      drawTri22(ax-(bottomSize / 2)/factor+bottomSize/factor,  ay+((bottomSize/factor)*Math.sqrt (3))/2,  bottomSize/factor,-30, level+1); // right rhomb top

      drawTri1( cx-bottomSize/factor, cy,  bottomSize/factor, 90,  level + 1);  // bottom rhomb right
      drawTri22(ex+bottomSize/factor, ey, bottomSize/factor, -90, level+1);         // bottom rhomb left
     
     }
}

    
    
    return outsideacess;
}());





var Socolar_module = (function() {
    
    
    var outsideacess = {}
    var t = new Transform();

var factor = Math.sqrt(2 + Math.sqrt(3));
var fudge = 1.115355; 

var rhombfudge = 1.93185;

var maxLevel;
var startSize;

var inscribed;

   
    outsideacess.make_Socolar_Tiling = function(n, single_or_rosette, inscribedrhombs_p) {
                  maxLevel = n;
                  inscribed = inscribedrhombs_p


  startSize = 500;

 drawSquare(0,0, startSize, 0, 1);
}
              
function drawTri1(  x,   y,   bottomSize,   deg,   level) 
{
        t.translate(x, y);
        t.rotate(radians(deg));
 
  var b = bottomSize / 2; 
  var h = (bottomSize*Math.sqrt(3))/2;

  if (level >= maxLevel) {
 
   }
   else {
  
   // Let the points of the shield be a through f, starting at the top and going clockwise around the sheild.
   var ax = 0;
   var ay = 0;

   var bx =    bottomSize/factor/factor/2  + (bottomSize/factor/factor*Math.sqrt(3))/2;
   var by =    bottomSize/factor/factor/2  + (bottomSize/factor/factor*Math.sqrt(3))/2;
   
   var cx = b;
   var cy = h;
   
   var dx = 0;
   var diff = h - Math.sqrt(sq(bottomSize/factor) *2); 
   var dy = diff + h;
   
   var ex = -b;
   var ey = h;
   
   var fx = -(bottomSize/factor/factor/2  + (bottomSize/factor/factor*Math.sqrt(3))/2);
   var fy =  bottomSize/factor/factor/2  + (bottomSize/factor/factor*Math.sqrt(3))/2;
   
   drawShield(ax,ay,bx,by,cx,cy,dx,dy,ex, ey,fx, fy, bottomSize/factor, level+1); 
  }

        t.rotate(radians(-deg));
        t.translate(-x, -y);
}


function drawTri22( x,  y,  bottomSize,  deg,  level) 
{
        t.translate(x, y);
        t.rotate(radians(deg));
 if (level >= maxLevel) {

     var b = bottomSize / 2; 
     var h = (bottomSize*Math.sqrt(3))/2;
     
       drawRhomb(b*rhombfudge*fudge,h, -b*rhombfudge*fudge,h);
 }
 else {
  
     drawSquare(0,0,bottomSize/factor, 45, level+1);
     drawTri22(0, Math.sqrt(sq(bottomSize/factor) *2), bottomSize/factor, 105, level+1);  
     drawTri22(0, Math.sqrt(sq(bottomSize/factor) *2), bottomSize/factor, -105, level+1);

 }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
}



function drawSquare( x,  y,  bottomSize,  deg,  level)
{
        t.translate(x, y);
        t.rotate(radians(deg));
  if (level >= maxLevel) {

     t.translate(bottomSize/2, bottomSize/2);
     t.rotate(radians(45));

     t.translate(-bottomSize*fudge/2, -bottomSize*fudge/2);
            var coords = [[0,0], [0, bottomSize*fudge],[bottomSize*fudge, bottomSize*fudge], [bottomSize*fudge, 0]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "square");

        t.translate(bottomSize*fudge/2, bottomSize*fudge/2);
        t.rotate(radians(-45));
        t.translate(-bottomSize/2, -bottomSize/2);
  }
  else {

     var WestBoxCornerX = bottomSize - (bottomSize*Math.sqrt(3))/2;
     var WestBoxCornerY = bottomSize/2 ;
     drawTri1( WestBoxCornerX, WestBoxCornerY,  bottomSize/factor,  -165,  level + 1);
     drawTri1( WestBoxCornerX, WestBoxCornerY,  bottomSize/factor,  -15,  level + 1);
     
     var NorthBoxCornerX = bottomSize/2 ;   
     var NorthBoxCornerY = bottomSize - (bottomSize*Math.sqrt(3))/2;
     drawTri1(NorthBoxCornerX, NorthBoxCornerY, bottomSize/factor, 285,  level + 1);
     
     var SouthBoxCornerX = bottomSize/2 ; 
     var SouthBoxCornerY = (bottomSize*Math.sqrt(3))/2;
     drawTri1( SouthBoxCornerX, SouthBoxCornerY,  bottomSize/factor, -105,  level + 1);
     
     var EastBoxCornerX = WestBoxCornerX + Math.sqrt(sq(bottomSize/factor)+sq(bottomSize/factor));
     var EastBoxCornerY = WestBoxCornerY;
     drawSquare(EastBoxCornerX, EastBoxCornerY  , bottomSize/factor, 135, level+1);

  }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
}

function drawShield( ax,  ay,  bx,  by, cx, cy, dx, dy, ex,  ey,  fx,  fy,  bottomSize,  level)
{  
     if (level == maxLevel) {

    drawHexagon((ax+bx+cx+dx+ex+fx)/6, (ay+by+cy+dy+ey+fy)/6, bottomSize*fudge, 0, maxLevel);
      }
    else {

      drawSquare(ax-(bottomSize / 2)/factor,  ay+((bottomSize/factor)*Math.sqrt(3))/2+bottomSize/factor,  bottomSize/factor, -90,  level+1); 
      drawSquare(ax-(bottomSize / 2)/factor,  ay+((bottomSize/factor)*Math.sqrt(3))/2+bottomSize/factor,  bottomSize/factor, 60,  level+1); 
      drawSquare(ax-(bottomSize / 2)/factor+bottomSize/factor,  ay+((bottomSize/factor)*Math.sqrt(3))/2+bottomSize/factor,  bottomSize/factor, 30,  level+1); 
  
      drawTri1( ax, ay,  bottomSize/factor, 0,  level + 1); // Top triangle
    
   
      drawTri1( cx-bottomSize/factor, cy,  bottomSize/factor, -120,  level + 1);  // corner triangle
      drawTri1( ex+bottomSize/factor, ey,  bottomSize/factor, 120,  level + 1);   // corner triangle
    
      drawTri1(fx,  by+bottomSize/factor, bottomSize/factor, -150, level+1);  // left frhomb bottom
      drawTri1(bx,  by+bottomSize/factor,bottomSize/factor,   150, level+1);  // right rhomb bottom
   
      drawTri1(ax,  ay+((bottomSize/factor)*Math.sqrt(3))+bottomSize/factor, bottomSize/factor, 180, level+1);  // center triangle

      drawTri22(ax-(bottomSize / 2)/factor,  ay+((bottomSize/factor)*Math.sqrt(3))/2,  bottomSize/factor, 30, level+1);  //left rhomb top
      drawTri22(ax-(bottomSize / 2)/factor+bottomSize/factor,  ay+((bottomSize/factor)*Math.sqrt(3))/2,  bottomSize/factor,-30, level+1); // right rhomb top

      drawTri1( cx-bottomSize/factor, cy,  bottomSize/factor, 90,  level + 1);  // bottom rhomb right
      drawTri22(ex+bottomSize/factor, ey, bottomSize/factor, -90, level+1);         // bottom rhomb left
     
     }
}



function drawHexagon( x,  y,  L,  deg,  level)
{
        t.rotate(radians(deg));
        t.translate(x, y);
  if (level >= maxLevel) {

    var a1x = L;

    var a1y = 0.0;

    var b2x = L/2;

    var b2y = L*Math.sqrt(3)/2;

    var c3x = -L/2;

    var c3y =  L*Math.sqrt(3)/2;
    var d4x = -L;
    var d4y =  0.0;
    var e5x = -L/2;

    var e5y =  -L*Math.sqrt(3)/2;

    var f6x = L/2;

    var f6y = -L*Math.sqrt(3)/2;

        if (inscribed) {
            var coords1 = [[0,0],  [a1x,a1y],[  b2x, b2y],  [c3x, c3y]]
            for (var i = 0; i < coords1.length; i++) {
                coords1[i] = t.transformPoint(coords1[i][0], coords1[i][1])
            }
            build_verts_and_faces(coords1, "rhomb");

            var coords2 = [[0,0], [c3x,c3y], [d4x,d4y], [e5x, e5y]]
            for (var i = 0; i < coords2.length; i++) {
                coords2[i] = t.transformPoint(coords2[i][0], coords2[i][1])
            }
            build_verts_and_faces(coords2, "rhomb");

            var coords3 =  [[0,0], [e5x, e5y], [f6x,f6y], [a1x, a1y]]
            for (var i = 0; i < coords3.length; i++) {
                coords3[i] = t.transformPoint(coords3[i][0], coords3[i][1])
            }
            build_verts_and_faces(coords3, "rhomb");



        }
        else { // normal Socolar tiling
          var coords = [[a1x,a1y], [b2x, b2y], [c3x,c3y], [d4x, d4y], [e5x,e5y], [f6x,f6y]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "hexagon");
        }


    }


        t.rotate(radians(-deg));
        t.translate(-x, -y);
}


function drawRhomb( x1,  y1,  x2,  y2) {
   var ax=(x1+x2)/2;
   var ay=(y1+y2)/2;
   var dx=x2-x1;
   var dy=y2-y1;
   var alfa=0.5*Math.tan(Math.PI/12);
   var aax=ax-alfa*dy, aay=ay+alfa*dx;
   var bbx=ax+alfa*dy, bby=ay-alfa*dx;
            var coords = [[x1, y1], [bbx, bby], [x2, y2], [aax, aay]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "rhomb");


};

    
    return outsideacess;
}());


var Watanabe_Ito_Soma_8_Fold_module = (function() {
    
    var outsideacess = {}
    var t = new Transform();

var maxLevel ;
var factor = 2+Math.sqrt(2);

outsideacess.make_Watanabe_Ito_Soma_8_Fold_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
        var startSize = 1000;
        drawSquare(0,0, startSize,90, 1);
  }


function drawSquare( x,  y,  len,  deg,  level) {
        t.translate(x, y);
        t.rotate(radians(deg));
  
     var x2 = len;
     var y2 = 0;

     var x3 = len;
     var y3 = -len;
     
     var x4 = 0;
     var y4 = -len;
     
  if (level == maxLevel) {
            var coords = [[0,0], [x2, y2],[ x3, y3], [x4, y4]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "square");
  }
  else {
    var newlen =  len/factor;  
    var centerx =  newlen +   Math.sqrt(sq(newlen)/2);  // (x4+x3)/2
    var centery = -( newlen + Math.sqrt(sq(newlen)/2));
    for (var i = 0; i<360; i = i+45) {
       draw8FoldRhomb (centerx, centery, newlen, i, level+1);
      
       t.translate(centerx, centery);
       t.rotate(radians(i));

       drawSquare(newlen + newlen*Math.cos(radians(45)),-newlen*Math.sin(radians(45)),newlen, 135, level+1);
       t.rotate(-radians(i));
       t.translate(-centerx, -centery);
    }
  }
        t.rotate(radians(-deg));
        t.translate(-x, -y);
}

function draw8FoldRhomb( x,  y,  len,  deg,  level) {

      t.translate(x, y);
      t.rotate(radians(deg));

     var a = 45.0;    // 5 is 360/8, so good for 8fold tilings.
     
     var x2 = len;
     var y2 = 0;

     var x3 = len + len*Math.cos(radians(a));
     var y3 = -len*Math.sin(radians(a));
     
     var x4 = len*Math.cos(radians(a));
     var y4 = -len*Math.sin(radians(a));
 
  if (level == maxLevel) {
            var coords = [[0,0], [x2, y2],[ x3, y3], [x4, y4]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "rhomb");
  }
   else {
      var newlen =len/factor;

      draw8FoldRhomb (0, 0, newlen, 0, level+1);
      draw8FoldRhomb (x3, y3, newlen, 180, level+1);
      drawSquare(x2,y2, newlen,315, level+1);
      drawSquare(x4,y4, newlen,90, level+1);
      draw8FoldRhomb (newlen + newlen*Math.cos(radians(45)), -newlen*Math.sin(radians(45)), newlen, -45, level+1);
      draw8FoldRhomb (newlen + newlen*Math.cos(radians(45)), -newlen*Math.sin(radians(45)), newlen, 0, level+1);
      draw8FoldRhomb (newlen + newlen*Math.cos(radians(45)), -newlen*Math.sin(radians(45)), newlen, 45, level+1);
      drawSquare(newlen + newlen*Math.cos(radians(45)), -newlen*Math.sin(radians(45)), newlen, -90, level+1);
      drawSquare(newlen + newlen*Math.cos(radians(45)), -newlen*Math.sin(radians(45)), newlen, 135, level+1);
    
      t.translate(x3, y3);
      t.rotate(radians(180));

      drawSquare(newlen + newlen*Math.cos(radians(45)), -newlen*Math.sin(radians(45)), newlen, -90, level+1);
      drawSquare(newlen + newlen*Math.cos(radians(45)), -newlen*Math.sin(radians(45)), newlen, 135, level+1);

            t.translate(newlen + newlen*Math.cos(radians(45)), -newlen*Math.sin(radians(45)));
             draw8FoldRhomb (0, -newlen, newlen, 90, level+1);
            t.translate(-(newlen + newlen*Math.cos(radians(45))),-( -newlen*Math.sin(radians(45))));

      t.rotate(-radians(180));
      t.translate(-x3, -y3);
   }
   t.rotate(radians(-deg))
   t.translate(-x, -y);
}
    return outsideacess;
}());



var Watanabe_Ito_Soma_12_Fold_module = (function() {
    
    var outsideacess = {}
    var t = new Transform();

var maxLevel;


outsideacess.make_Watanabe_Ito_Soma_12_Fold_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
        var startSize = 400;

        drawSquare(0,0, startSize, 0, 1);
}



function draw12FoldRhomb( x,  y,  len,  rot,  level) {
  t.translate(x, y);
  t.rotate(radians(rot));
     var a = 30.0;    // 30 is 360/12, so good for 12fold tilings.
     
     var x2 = len;
     var y2 = 0;

     var x3 = len + len*Math.cos(radians(a));
     var y3 = -len*Math.sin(radians(a));
     
     var x4 = len*Math.cos(radians(a));
     var y4 = -len*Math.sin(radians(a));
     
  if (level == maxLevel) {


            var coords = [[0,0], [x2, y2],[ x3, y3], [x4, y4]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "rhomb");
  }
   else {
          var newlen = len/(2+Math.sqrt(3));
          draw12FoldRhomb(0, 0, newlen,0,level+1);
          
          drawTriangle(newlen, 0, newlen, -90, level+1);
          
          drawSquare(newlen+newlen*Math.cos(radians(a)),-newlen*Math.sin(radians(a)),newlen,30,level+1);
             t.translate(newlen+newlen*Math.cos(radians(a)), -newlen*Math.sin(radians(a)));
             t.rotate(radians(30));

             drawTriangle(0, -newlen, newlen, 30, level+1);
             t.rotate(radians(-30));
             t.translate(-(newlen+newlen*Math.cos(radians(a))), -(-newlen*Math.sin(radians(a))));

           drawTriangle(x2, y2, newlen, 210, level+1);
           drawTriangle(x2, y2, newlen,120, level+1);

          
           drawTriangle(x4, y4, newlen, 300, level+1);
           drawTriangle(x4, y4, newlen,30, level+1);
         
         draw12FoldRhomb(x4, y4, newlen, 90,level+1);


         draw12FoldRhomb(x3, y3, newlen,180,level+1);

          t.translate(x3, y3);
          t.rotate(radians(180));

          drawTriangle(newlen,0, newlen, 270, level+1);
          drawSquare(newlen + newlen*Math.cos(radians(30)),-newlen*Math.sin(radians(30)), newlen,30,level+1);

              t.translate(newlen + newlen*Math.cos(radians(30)),-newlen*Math.sin(radians(30)));
              t.rotate(radians(30));
              drawTriangle(0, -newlen, newlen,30, level+1);
              t.rotate(radians(-30));
              t.translate(-(newlen + newlen*Math.cos(radians(30))),-(-newlen*Math.sin(radians(30))));

          t.rotate(radians(-180));
          t.translate(-x3, -y3);

          
          t.translate(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)));
          t.rotate(radians(30));
                    drawTriangle(0,-newlen, newlen,30,level+1);
          t.rotate(radians(-30));
          t.translate(-(newlen + newlen*Math.cos(radians(30))), -(-newlen*Math.sin(radians(30))));

   }
  t.rotate(radians(-rot));
  t.translate(-x, -y);
}



function drawSquare( x,  y,  len,  rot,  level) {
  t.translate(x, y);
  t.rotate(radians(rot));

  if (level == maxLevel) {

     var x2 = len;
     var y2 = 0;

     var x3 = len;
     var y3 = -len;
     
     var x4 = 0;
     var y4 = -len;

            var coords = [[0,0], [x2, y2], [x3, y3], [x4, y4]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "square");
    }
  else {
    var newlen = len/(2+Math.sqrt(3));

    draw12FoldRhomb(0,0, newlen, 300, level+1);
      t.rotate(radians(300));
      drawSquare(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)),newlen, 30, level+1);
      
      t.rotate(radians(-300));
    
    draw12FoldRhomb(0,0, newlen, 330, level+1);
      t.rotate(radians(330));
            drawTriangle(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, -30, level+1);
            drawTriangle(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, 30, level+1);
            drawSquare(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, 30, level+1);
            drawTriangle(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, 120, level+1);
            drawTriangle(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, 180, level+1);

      t.rotate(radians(-330));
      
       draw12FoldRhomb(0,0, newlen, 0, level+1);
       drawSquare(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, 30, level+1);
   
   
    drawTriangle(newlen, 0, newlen, 270,level+1);
   
  draw12FoldRhomb(len,0, newlen, 270, level+1);
     t.translate(len, 0);
     t.rotate(radians(270));
     drawTriangle(newlen, 0,  newlen, 270, level+1);
     drawTriangle(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, 180, level+1);
     drawTriangle(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, 120, level+1);
     drawTriangle(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, 270, level+1);

     draw12FoldRhomb(newlen + newlen*Math.cos(radians(30)), -newlen*Math.sin(radians(30)), newlen, 330, level+1);
     t.rotate(radians(-270));
     t.translate(-len, 0);

   drawTriangle(len, 0, newlen, 120, level+1);
   drawTriangle(0, -len + newlen, newlen, 0, level+1);
   drawTriangle(0, -len , newlen, 330, level+1);
   
   draw12FoldRhomb(0, -len, newlen, 30, level+1);
     t.translate(0, -len);
     t.rotate(radians(30));
     drawTriangle(newlen + newlen*Math.cos(radians(30)),-newlen*Math.sin(radians(30)), newlen, 30, level+1);
     drawTriangle(newlen + newlen*Math.cos(radians(30)),-newlen*Math.sin(radians(30)), newlen, -30, level+1);

     drawTriangle(newlen + newlen*Math.cos(radians(30)),-newlen*Math.sin(radians(30)), newlen, -120, level+1);
     t.rotate(radians(-30));
     t.translate(0, len);

   drawSquare(len-newlen, -len+newlen, newlen, 0, level+1);
   drawTriangle(len-newlen, -len, newlen, 90, level+1);
   
   
   
  }
  t.rotate(radians(-rot));
  t.translate(-x, -y);
}

 
function drawTriangle( x,  y,  len,  rot,  level) 
{
  t.translate(x, y);
  t.rotate(radians(rot));
  var b = len / 2; 
  var h = (len*Math.sqrt(3))/2;


  if (level >= maxLevel) {

            var coords = [[0.0,0.0], [-b, h], [b, h]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "triangle");
   
   }
   else {
     var newlen = len/(2+Math.sqrt(3));
     draw12FoldRhomb(0, 0, newlen, -270, level+1); // top rhomb
     draw12FoldRhomb(0, 0, newlen, -240, level+1); // bottom rhomb
     drawTriangle(0,newlen, newlen, 0, level+1);
     drawTriangle(newlen*Math.cos(radians(-240)),newlen*Math.sin(radians(-240)), newlen, 30, level+1);
     drawTriangle(0, newlen+2*(newlen*Math.sqrt(3))/2, newlen, 180, level+1);


     t.rotate(radians(120));

     drawSquare(newlen+(newlen*Math.sqrt(3))/2,-newlen/2,newlen, 30, level+1);
     t.rotate(radians(-120));


     t.rotate(radians(90));

     drawSquare(newlen+(newlen*Math.sqrt(3))/2,-newlen/2,newlen, 30, level+1);
     t.rotate(radians(-90));

     drawTriangle(-b, h, newlen, 240, level+1);
      t.translate(-b, h);
      t.rotate(radians(240));
      var bb = newlen / 2; 
      var hh = (newlen*Math.sqrt(3))/2;
      drawTriangle(-bb, hh, newlen, 30, level+1);
      t.rotate(radians(-240));
      t.translate(b, -h);

     drawTriangle( b, h, newlen, 120, level+1);
      t.translate(b, h);
      t.rotate(radians(120));
       bb = newlen / 2; 
       hh = (newlen*Math.sqrt(3))/2;
      drawTriangle(-bb, hh, newlen, 30, level+1);
      t.rotate(radians(-120));
      t.translate(-b, -h);
   }
  t.rotate(radians(-rot));
  t.translate(-x, -y);
}
    
    return outsideacess;
}());


var SphinxTiling_module = (function() {
    var outsideacess = {}
    var t = new Transform();
    var maxLevel;
    var factor = 2;


   outsideacess.make_Sphinx_Tiling = function(n, single_or_rosette) {

        sigdigits = 8
        alert("changing sigdigits!")

        maxLevel = n;
        var startsize = 980  // was 400
        sphinx(0, 0, startsize, 0, 1)
   }

function sphinx ( xcorner,  ycorner,  triside,  angle,  level) {




  t.translate(xcorner,ycorner);
  t.rotate(angle*Math.PI/180);
  var coords = []
   var b =   triside / 2              //roundNumber(triside / 2, 0); 
   var h = (triside*Math.sqrt(3))/2   // roundNumber((triside*Math.sqrt(3))/2, 0);

  if (level >=maxLevel) {
 
     coords = [ [0,0], [triside, -2*h], [triside+b, -h], [triside*2+b, -h], [triside*3, 0], [triside, 0]]
     for (var i = 0; i < coords.length; i++) {
         coords[i] = t.transformPoint(coords[i][0], coords[i][1])
     }
     build_verts_and_faces(coords, "sphinx1");
    
/* 
      // Trapezoids
     coords = [ [0,0], [triside, -2*h], [triside+b, -h],  [triside, 0]]
     for (var i = 0; i < coords.length; i++) {
         coords[i] = t.transformPoint(coords[i][0], coords[i][1])
     }
     build_verts_and_faces(coords, "sphinx1");

     coords = [ [triside+b, -h], [triside*2+b, -h], [triside*3, 0], [triside, 0]]
     for (var i = 0; i < coords.length; i++) {
         coords[i] = t.transformPoint(coords[i][0], coords[i][1])
     }
     build_verts_and_faces(coords, "sphinx1");
*/


    }
   else {
      sphinx(triside, -2*h, triside/factor, 120, level+1)
      flip_sphinx(triside*1.5,0,triside/factor, 0, level+1)
      flip_sphinx(triside*3,0,triside/factor, 0, level+1)
      flip_sphinx(triside,-h,triside/factor, 180, level+1)
   }
        t.rotate(radians(-angle));
        t.translate(-xcorner, -ycorner);
}

function flip_sphinx ( xcorner,  ycorner,  triside,  angle,  level) {
  t.translate(xcorner,ycorner);
  t.rotate(angle*Math.PI/180);
   var coords = []
   var b =   triside / 2              //roundNumber(triside / 2, 0); 
   var h = (triside*Math.sqrt(3))/2   // roundNumber((triside*Math.sqrt(3))/2, 0);
  if (level >=maxLevel) {
 
      coords = [ [0,0], [-1*(triside), -2*h], [-1*(triside+b), -h], [-1*(triside*2+b), -h], [-1*(triside*3), 0], [-1*(triside), 0]]
     for (var i = 0; i < coords.length; i++) {
        coords[i] = t.transformPoint(coords[i][0], coords[i][1])
     }
     build_verts_and_faces(coords, "sphinx1");
/*
       // Trapezoids

      coords = [ [0,0], [-1*(triside), -2*h], [-1*(triside+b), -h], [-1*(triside), 0]]
     for (var i = 0; i < coords.length; i++) {
        coords[i] = t.transformPoint(coords[i][0], coords[i][1])
     }
     build_verts_and_faces(coords, "sphinx1");

      coords = [  [-1*(triside+b), -h], [-1*(triside*2+b), -h], [-1*(triside*3), 0], [-1*(triside), 0]]
     for (var i = 0; i < coords.length; i++) {
        coords[i] = t.transformPoint(coords[i][0], coords[i][1])
     }
     build_verts_and_faces(coords, "sphinx1");
*/
     }

   else {
      flip_sphinx(-1*(triside), -2*h, triside/factor, -1*120, level+1)
      sphinx(-1*triside*1.5,0,triside/factor, 0, level+1)
      sphinx(-1*triside*3,0,triside/factor, 0, level+1)
      sphinx(-1*triside,-h,triside/factor, 180, level+1)
   }
        t.rotate(radians(-angle));
        t.translate(-xcorner, -ycorner);
}
    return outsideacess;
}());


var Diamond_Triangle_module = (function() {
    
    var outsideacess = {}
    var t = new Transform();
    
    var maxLevel;
    var factor = 3

    var triangle_size;

    outsideacess.make_Diamond_BigTriangle_Tiling = function(n, single_or_rosette) {
        triangle_size = "big";
        maxLevel = n;
        var startSize = 500;
        rhomb(0, 0, startSize, 60, 1)
    }

    outsideacess.make_Diamond_SmallTriangle_Tiling = function(n, single_or_rosette) {
        triangle_size = "small";
        maxLevel = n;
        var startSize = 500;
        rhomb(0, 0, startSize, 60, 1)
    }



function tri( xcorner,  ycorner,  sidesize,  angle,  level) {
  var tricoords = []
  t.translate(xcorner,ycorner);
  t.rotate(angle*Math.PI/180);

 var b = sidesize / 2; 
 var h = (sidesize*Math.sqrt(3))/2;
 //tricoords = [ [0,0], [-b, h], [ b, h] ] // without intermediate vertices
 tricoords = [ [0,0], [-b/2, h/2], [-b, h], [0, h], [ b, h] ,[b/2, h/2] ] // with three intermediate vertices

  if (level >= maxLevel) {
   for (var i = 0; i<tricoords.length; i++) {
      tricoords[i] = t.transformPoint(tricoords[i][0],tricoords[i][1])
   }
   if (triangle_size == "big") {
      build_verts_and_faces (tricoords, "triangle")
    }
   else {  // triangle_size == "small"
      build_verts_and_faces ([tricoords[0], tricoords[1], tricoords[3], tricoords[5]], "rhomb")
      build_verts_and_faces ([tricoords[1], tricoords[2], tricoords[3]], "triangle")
      build_verts_and_faces ([tricoords[5], tricoords[4], tricoords[3]], "triangle")
   }

  }
  else {
      var newsize = sidesize/factor
      tri(0,0,newsize, 0, level+1)
      tri(-b,h,newsize, -120, level+1)
      tri(b,h,newsize, 120, level+1)
      rhomb(0,h, newsize/2, 0, level+1)
      rhomb(0,h, newsize/2, -120, level+1)
      rhomb(0,h, newsize/2, -60, level+1)

      var upwards = newsize*Math.sin(60*Math.PI/180)
      rhomb(0,h-upwards, newsize/2, -60, level+1)
      rhomb(0,h-upwards, newsize/2,   0, level+1)
      rhomb(0,h-upwards, newsize/2,  60, level+1)
      rhomb(0,h-upwards, newsize/2, -120, level+1)
      rhomb(0,h-upwards, newsize/2, -180, level+1)

      rhomb(0,h-2*upwards, newsize/2, 60, level+1)
      rhomb(0,h-2*upwards, newsize/2, -180, level+1)

      rhomb(-b/2,h/2, newsize/2, -240, level+1)
      rhomb(b/2,h/2, newsize/2, 120, level+1)
  }

        t.rotate(-angle*Math.PI/180);
        t.translate(-xcorner,-ycorner);
}

function rhomb( x,  y,  len,  angle,  level) {
  var rhombcoords = []
  t.translate(x,y);
  t.rotate(angle*Math.PI/180);
     var a = 60*Math.PI/180    // 
     var x1, y1, x2, y2, x3, y3, x4, y4;
        x1 = 0
        y1 = 0
        
        x2 = len;
        y2 = 0;

         x3 = len + len*Math.cos(a);
         y3 = -len*Math.sin(a);
          
         x4 = len*Math.cos(a);
         y4 = -len*Math.sin(a);
     rhombcoords = [[x1,y1],  [x2,y2], [x3, y3], [x4, y4]] 

 if (level == maxLevel) {
 
   for (var i = 0; i<rhombcoords.length; i++) {
      rhombcoords[i] = t.transformPoint(rhombcoords[i][0],rhombcoords[i][1])
   }
   build_verts_and_faces (rhombcoords, "rhomb")

}
 if (level < maxLevel) {

      var newlen =len/factor;
      tri(x1,y1, newlen*2, 180+60, level+1)
      tri(x3,y3, newlen*2, 60, level+1)
      rhomb(x2,y2, newlen, -60, level+1)
      rhomb(x2,y2, newlen, -120, level+1)

      rhomb(x4,y4, newlen, 60, level+1)
      rhomb(x4,y4, newlen, 120, level+1)

      rhomb(x3/3,y3/3, newlen, 0, level+1)

  }
        t.rotate(-angle*Math.PI/180);
        t.translate(-x, -y);
}
   
    return outsideacess;
}());

//***************************** Experimental Pentagonal Snowflake Section **********************************

var Pentagonal_Snowflake_module = (function() {
    var outsideacess = {}
    var t = new Transform();
    var factor = (1 + Math.sqrt(5))/2   

    var maxLevel;
      
    outsideacess.make_Pentagonal_Snowflake_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
        var radius = 400;


     draw_Pent(0,0, radius, 33, 1 )

    }

/*
Pentagonal_Snowflake_module.make_Pentagonal_Snowflake_Tiling(2, "single")
 document.getElementById("Meshmakers_Div").setAttribute("style", "display: none;")  
initialize()
*/

function s_makePentagon( xcorner,ycorner, size,angle, drawstatus) {
    var pentagoncoords = []
    var coords = []

    t.translate(xcorner,ycorner);
    t.rotate(angle*Math.PI/180);
    // there is not any new t2 here
 //   t2.translate(xcorner,ycorner);
 //   t2.rotate(angle*Math.PI/180);
    var xcenter = 0;
    var ycenter = 0 + size ;  
    pentagoncoords.push([xcenter,ycenter])
    coords.push([xcenter,ycenter])

    for(var i=1;i<=5; ++i){
       th=i * 2 * Math.PI/5;
       x=xcenter+size*Math.sin(th);
       y=ycenter-size*Math.cos(th);
       pentagoncoords.push([x,y])
       coords.push([x,y])

     }
     for (var i = 0; i<pentagoncoords.length; i++) {
         pentagoncoords[i] = t.transformPoint(pentagoncoords[i][0],pentagoncoords[i][1])
     }
    if (drawstatus  == "draw") {
       var verts_but_not_center = pentagoncoords.slice(1, pentagoncoords.length)
       build_verts_and_faces (verts_but_not_center, "pentagon")
    }
    t.rotate(-angle*Math.PI/180);
    t.translate(-xcorner,-ycorner); 

     // there is not any transform of coords here 
    
     return coords
}

function draw_Pent( xcorner,ycorner, size,angle, level ) {

   if (level >= maxLevel)  {
      s_makePentagon(xcorner,ycorner, size,angle, "draw")
   }
   else {
   t.translate(xcorner,ycorner);
   t.rotate(angle*Math.PI/180);
   // t2 = new Transform();
  //  t2.translate(xcorner,ycorner);
  //  t2.rotate(angle*Math.PI/180);

       var outermostcoords = s_makePentagon(xcorner,ycorner, size,angle, "don't draw")
       draw_Pent(outermostcoords[1][0], outermostcoords[1][1], size/factor/factor, 72, level+1)
       draw_Pent(outermostcoords[2][0], outermostcoords[2][1], size/factor/factor, 72+72, level+1)
       draw_Pent(outermostcoords[3][0], outermostcoords[3][1], size/factor/factor, 72+72+72, level+1)
       draw_Pent(outermostcoords[4][0], outermostcoords[4][1], size/factor/factor, 72+72+72+72, level+1)
       draw_Pent(outermostcoords[5][0], outermostcoords[5][1], size/factor/factor, 0, level+1)
       // now draw the center pentagon
       draw_Pent(outermostcoords[0][0], outermostcoords[0][1]+size/factor/factor, size/factor/factor, 180, level+1)

      //    return outermostcoords
  t.rotate(-angle*Math.PI/180);
  t.translate(-xcorner,-ycorner);  

   }
}
  
    return outsideacess
}());

  

// **************************** EXPERIMENTAL DURER RADIAL SECTION *********************************


var Durer_Nonperiodic_module = (function() {
    
    var outsideacess = {}
    var t = new Transform();
    var factor = (1 + Math.sqrt(5))/2   
     var maxLevel;

outsideacess.make_Durer_Radial_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
           radius = 4;
           sidelength = 2 * radius * Math.sin(Math.PI/5)
           apothem = radius * Math.cos(Math.PI/5)

        make_Durer_Radial_toast(0,0, radius, 0);   

}


outsideacess.make_Durer_Spiral_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
           radius = 4;
           sidelength = 2 * radius * Math.sin(Math.PI/5)
           apothem = radius * Math.cos(Math.PI/5)

        make_Durer_Spiral_toast(0,0, radius, 0);   

}


/*
Durer_Nonperiodic_module.make_Durer_Radial_Tiling(1, "single")
 document.getElementById("Meshmakers_Div").setAttribute("style", "display: none;")  
initialize()

Durer_Nonperiodic_module.make_Durer_Radial_Tiling(38, "single")
 document.getElementById("Meshmakers_Div").setAttribute("style", "display: none;")  
initialize()

 or for Kaplan's spiral tiling

Durer_Nonperiodic_module.make_Durer_Spiral_Tiling(38, "single")
 document.getElementById("Meshmakers_Div").setAttribute("style", "display: none;")  
initialize()
*/

function tiling_from_data (x,y, verts_and_faces) { 

        for (var f = verts_and_faces.length; f--;) {
            var theface = verts_and_faces[f].face
            var tempface = Array(theface.length)
            for (var v = theface.length; v--;) {
                tempface[v] = [theface[v][0] + x, theface[v][1] + y]
            }
            for (var i = 0; i<theface.length; i++) {
             tempface[i] = t.transformPoint(tempface[i][0],tempface[i][1])
            }
            build_verts_and_faces (tempface,  verts_and_faces[f].name)
        }

}


function wedge_tiling_from_data (x, y, n_rows, angle, offset_width, offset_height, verts_and_faces, perimeter_verts_and_faces) { 
    t.translate(x,y);
    t.rotate(angle*Math.PI/180);

   tiling_from_data (0,0, verts_and_faces) // n = 1
   var current_y = 0 + offset_height
   for (var n = 2; n <= n_rows; ++n) {
     if (n == n_rows) {verts_and_faces = perimeter_verts_and_faces}
     if (n % 2) { // odd rows
      tiling_from_data (0, current_y, verts_and_faces)

       for (var i = -n/2; i <= -1; i=i+1.0) {
          tiling_from_data (offset_width + i*offset_width*2,current_y, verts_and_faces)
       }
       for (var i = 1; i <= n/2; i=i+1.0) {
          tiling_from_data (0 + i*offset_width*2,current_y, verts_and_faces)
       }   
     }

     else { // even rows
       for (var i = -n/2; i <= -1; i=i+1.0) {
           tiling_from_data (offset_width + i*offset_width*2,current_y, verts_and_faces)
       }
       for (var i =1 ; i <= n/2; i=i+1.0) {
           tiling_from_data (-offset_width + i*offset_width*2,current_y, verts_and_faces)
       }   
    }

     current_y = current_y + offset_height
   }
   
         
    t.rotate(-angle*Math.PI/180);
    t.translate(-x,-y);

}

function get_pentagon_coords(xcorner, ycorner, size) {
    var pentcoords1 = []
    var xcenter = xcorner;
    var ycenter = ycorner + size ;  
    for(var i=0;i<5; ++i){
      var th=i * 2 * Math.PI/5;
      var  x=xcenter+size*Math.sin(th);
      var  y=ycenter-size*Math.cos(th);
      pentcoords1.push([x,y])
     }    
     return pentcoords1
}

function get_pent_just_below_this_one(pentcoords1) {
   var pentcoords2 = [[], [], [], [], []]
   var height =     Math.abs(pentcoords1[0][1] - pentcoords1[3][1])
   var midheight =  Math.abs(pentcoords1[1][1] - pentcoords1[3][1])

   pentcoords2[2] =  pentcoords1[2] 
   pentcoords2[3] =  pentcoords1[3] 

   pentcoords2[0][0] =  pentcoords1[0][0]
   pentcoords2[1][0] =  pentcoords1[1][0]
   pentcoords2[4][0] =  pentcoords1[4][0]

   pentcoords2[0][1] =   pentcoords1[0][1] + 2*height
   pentcoords2[1][1] =   pentcoords1[1][1]  + 2*midheight
   pentcoords2[4][1] =   pentcoords1[4][1]  + 2*midheight

   return pentcoords2
}




function make_Durer_Radial_toast ( xcorner,ycorner, size,angle) {

    var pentcoords1 = []
    var pentcoords2 = []
    var thinrhombcoords1 = []

   pentcoords1 = get_pentagon_coords(0, 0, size)
   pentcoords2 =  get_pent_just_below_this_one(pentcoords1)

   rhomb_x_diff =  Math.abs( pentcoords2[0][0] - pentcoords1[1][0])
   rhomb_y_diff =  Math.abs( pentcoords2[0][1] - pentcoords1[1][1])

   thinrhombcoords1 = [pentcoords1[1], pentcoords1[2] , pentcoords2[1], []]
   thinrhombcoords1[3][0] = pentcoords1[2][0] + 2*(Math.abs( pentcoords1[2][0] - pentcoords1[1][0]))
   thinrhombcoords1[3][1] =  pentcoords1[2][1]
   for (var i = 0; i<4; i++) {
      thinrhombcoords1[i] = [thinrhombcoords1[i][0] -  rhomb_x_diff, thinrhombcoords1[i][1] +  rhomb_y_diff]
   }

    var xoffset = Math.abs(pentcoords1[0][0] - pentcoords1[1][0])
    var yoffset = Math.abs(pentcoords1[0][1] - pentcoords2[1][1])

  var data = [{face: pentcoords1, name: "pentagon"},
              {face: pentcoords2, name: "pentagon"},
              {face: thinrhombcoords1, name: "rhomb"}]

  var perimeter_data = [{face: pentcoords1, name: "pentagon"}, {face: pentcoords2, name: "pentagon"}]




wedge_tiling_from_data (515.2106797860727, 0,  maxLevel, 0, xoffset, yoffset, data,perimeter_data )
var big_outer_pent = get_pentagon_coords(515.2106797860727, 0, radius*factor*factor)
wedge_tiling_from_data (big_outer_pent[4][0],big_outer_pent[4][1],  maxLevel, -72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (big_outer_pent[3][0],big_outer_pent[3][1],  maxLevel, -72-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (big_outer_pent[2][0],big_outer_pent[2][1],  maxLevel, -72-72-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (big_outer_pent[1][0],big_outer_pent[1][1],  maxLevel, -72-72-72-72, xoffset, yoffset, data, perimeter_data)

var small_inner_pent = get_pent_just_below_this_one(get_pentagon_coords(515.2106797860727, 0, radius))
wedge_tiling_from_data (small_inner_pent[3][0],small_inner_pent[3][1],  maxLevel-1, -36, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (small_inner_pent[4][0],small_inner_pent[4][1],  maxLevel-1, -36-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (small_inner_pent[0][0],small_inner_pent[0][1],  maxLevel-1, -36-72-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (small_inner_pent[1][0],small_inner_pent[1][1],  maxLevel-1, -36-72-72-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (small_inner_pent[2][0],small_inner_pent[2][1],  maxLevel-1, -36-72-72-72-72, xoffset, yoffset, data, perimeter_data)


}


function make_Durer_Spiral_toast ( xcorner,ycorner, size,angle) {

    var pentcoords1 = []
    var pentcoords2 = []
    var thinrhombcoords1 = []

   pentcoords1 = get_pentagon_coords(0, 0, size)
   pentcoords2 =  get_pent_just_below_this_one(pentcoords1)

//   rhomb_x_diff =  Math.abs( pentcoords2[0][0] - pentcoords1[1][0])
//   rhomb_y_diff =  Math.abs( pentcoords2[0][1] - pentcoords1[1][1])

   thinrhombcoords1 = [pentcoords1[1], pentcoords1[2] , pentcoords2[1], []]
   thinrhombcoords1[3][0] = pentcoords1[2][0] + 2*(Math.abs( pentcoords1[2][0] - pentcoords1[1][0]))
   thinrhombcoords1[3][1] =  pentcoords1[2][1]
//   for (var i = 0; i<4; i++) {
//      thinrhombcoords1[i] = [thinrhombcoords1[i][0] -  rhomb_x_diff, thinrhombcoords1[i][1] +  rhomb_y_diff]
//   }

    var xoffset = Math.abs(pentcoords1[0][0] - pentcoords1[1][0])
    var yoffset = Math.abs(pentcoords1[0][1] - pentcoords2[1][1])

  var data = [{face: pentcoords1, name: "pentagon"},
              {face: pentcoords2, name: "pentagon"},
              {face: thinrhombcoords1, name: "rhomb"}]


//***************************************** Kaplan's spiral version of Durer ********************

// calculations for Kaplan's spiral version of Durer
// pentradius = 400
// sidelength =  2 * 400 * Math.sin(Math.PI/5)  = 470.22820183397848
// sidelength = 2 * decradius * Math.sin(Math.PI/10) =   2 * pentradius * Math.sin(Math.PI/5) 
// decradius = 470.22820183397848/(2  * Math.sin(Math.PI/10))

    var decradius = get_decagon_radius_from_pentagon_radius(size)
    var decacoords = []
    for(var i=0;i<10; ++i){
      var th=i * 2 * Math.PI/10 + 18*Math.PI/180    // the 18 degrees makes it flat side down instead of vertex down
      var  x=xcorner+decradius*Math.sin(th);
      var  y=ycorner-decradius*Math.cos(th);
      decacoords.push([x,y])
     }    

            build_verts_and_faces (decacoords,  "decagon")

wedge_tiling_from_data (decacoords[0][0], decacoords[0][1],  maxLevel, -36*3, xoffset, yoffset, data, data)
wedge_tiling_from_data (decacoords[1][0], decacoords[1][1],  maxLevel, -36*2, xoffset, yoffset, data, data)
wedge_tiling_from_data (decacoords[2][0], decacoords[2][1],  maxLevel, -36*1, xoffset, yoffset, data, data)
wedge_tiling_from_data (decacoords[3][0], decacoords[3][1],  maxLevel, 0, xoffset, yoffset, data, data)
wedge_tiling_from_data (decacoords[4][0], decacoords[4][1],  maxLevel, 36, xoffset, yoffset, data, data)
wedge_tiling_from_data (decacoords[5][0], decacoords[5][1],  maxLevel, 36*2, xoffset, yoffset, data, data)
wedge_tiling_from_data (decacoords[6][0], decacoords[6][1],  maxLevel, 36*3, xoffset, yoffset, data, data)
wedge_tiling_from_data (decacoords[7][0], decacoords[7][1],  maxLevel, 36*4, xoffset, yoffset, data, data)
wedge_tiling_from_data (decacoords[8][0], decacoords[8][1],  maxLevel, 36*5, xoffset, yoffset, data, data)
wedge_tiling_from_data (decacoords[9][0], decacoords[9][1],  maxLevel, 36*6, xoffset, yoffset, data, data)



}

  
    return outsideacess;
}());

  // ***************************************  Experimental Kepler Aa Tiling section ***********************************


// Probably  this can  eventually be consolidated with Radial Durer Tiling





































var Kepler_Aa_module = (function() {
    
    var outsideacess = {}
    var t = new Transform();
    var factor = (1 + Math.sqrt(5))/2   
     var maxLevel;

      outsideacess.make_Kepler_Aa_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
           radius = 40;
           sidelength = 2 * radius * Math.sin(Math.PI/5)
           apothem = radius * Math.cos(Math.PI/5)

        make_Kepler_Aa_toast(0,0, radius, 0);   

      }

     outsideacess.make_Kepler_Aa_periodic = function(xmax, ymax) {
      
           radius = 40;
          // sidelength = 2 * radius * Math.sin(Math.PI/5)
          // apothem = radius * Math.cos(Math.PI/5)

        make_Kepler_Aa_periodic(xmax, ymax, radius);   

      }


/*
Kepler_Aa_module.make_Kepler_Aa_Tiling(1, "single")
 document.getElementById("Meshmakers_Div").setAttribute("style", "display: none;")  
initialize()

Kepler_Aa_module.make_Kepler_Aa_Tiling(3, "single")
 document.getElementById("Meshmakers_Div").setAttribute("style", "display: none;")  
initialize()

Kepler_Aa_module.make_Kepler_Aa_periodic(10, 10)
 document.getElementById("Meshmakers_Div").setAttribute("style", "display: none;")  
initialize()

*/

function tiling_from_data (x,y, verts_and_faces) { 

        for (var f = verts_and_faces.length; f--;) {
            var theface = verts_and_faces[f].face
            var tempface = Array(theface.length)
            for (var v = theface.length; v--;) {
                tempface[v] = [theface[v][0] + x, theface[v][1] + y]
            }
            for (var i = 0; i<theface.length; i++) {
             tempface[i] = t.transformPoint(tempface[i][0],tempface[i][1])
            }
            build_verts_and_faces (tempface,  verts_and_faces[f].name)
        }

}



function wedge_tiling_from_data (x, y, n_rows, angle, offset_width, offset_height, verts_and_faces, perimeter_verts_and_faces) { 
    t.translate(x,y);
    t.rotate(angle*Math.PI/180);

   tiling_from_data (0,0, verts_and_faces) // n = 1
   var current_y = 0 + offset_height
   for (var n = 2; n <= n_rows; ++n) {
     if (n == n_rows) {verts_and_faces = perimeter_verts_and_faces}
     if (n % 2) { // odd rows
      tiling_from_data (0, current_y, verts_and_faces)

       for (var i = -n/2; i <= -1; i=i+1.0) {
          tiling_from_data (offset_width + i*offset_width*2,current_y, verts_and_faces)
       }
       for (var i = 1; i <= n/2; i=i+1.0) {
          tiling_from_data (0 + i*offset_width*2,current_y, verts_and_faces)
       }   
     }

     else { // even rows
       for (var i = -n/2; i <= -1; i=i+1.0) {
           tiling_from_data (offset_width + i*offset_width*2,current_y, verts_and_faces)
       }
       for (var i =1 ; i <= n/2; i=i+1.0) {
           tiling_from_data (-offset_width + i*offset_width*2,current_y, verts_and_faces)
       }   
    }

     current_y = current_y + offset_height
   }
   
         
    t.rotate(-angle*Math.PI/180);
    t.translate(-x,-y);

}


function get_pentagon_coords(xcorner, ycorner, size, orientation) {
    var pentcoords1 = []
    var xcenter = xcorner;
    var ycenter = ycorner + size ;  
    if (orientation == "pointed up") {addon = 0} else {addon =  180*Math.PI/180}

    for(var i=0;i<5; ++i){
      var th=i * 2 * Math.PI/5 + addon;
      var  x=xcenter+size*Math.sin(th);
      var  y=ycenter-size*Math.cos(th);
      pentcoords1.push([x,y])
     }    
     return pentcoords1
}

/*
function get_pent_just_below_this_one(pentcoords1) {
   var pentcoords2 = [[], [], [], [], []]
   var height =     Math.abs(pentcoords1[0][1] - pentcoords1[3][1])
   var midheight =  Math.abs(pentcoords1[1][1] - pentcoords1[3][1])

   pentcoords2[2] =  pentcoords1[2] 
   pentcoords2[3] =  pentcoords1[3] 

   pentcoords2[0][0] =  pentcoords1[0][0]
   pentcoords2[1][0] =  pentcoords1[1][0]
   pentcoords2[4][0] =  pentcoords1[4][0]

   pentcoords2[0][1] =   pentcoords1[0][1] + 2*height
   pentcoords2[1][1] =   pentcoords1[1][1]  + 2*midheight
   pentcoords2[4][1] =   pentcoords1[4][1]  + 2*midheight

   return pentcoords2
}
*/

function get_pent_just_below_this_one(pentcoords1) {
  return mirror_y_coords(pentcoords1, pentcoords1[2][1])
 }



function mirror_y_coords (coords, axis) {
  var result = []
  var dist;
  for (var i = 0; i<coords.length; i++) {
    dist = axis - coords[i][1] 
    result.push([coords[i][0], axis + dist])
  }
  return result
}

    

function get_star_coords(xcorner, ycorner, size, orientation) {
    var starcoords = []
    var outerStarCoords = []
    var innerPentCoords = []
 
    var xcenter = xcorner;
    var ycenter = ycorner + size ;   
    if (orientation == "pointed up") {addon = 0} else {addon =  180*Math.PI/180}
 
    for(var i=1;i<=5; ++i){
     
       th=i * 4 * Math.PI/5 + addon
       x=xcenter+size*Math.sin(th);
       y=ycenter-size*Math.cos(th);
       outerStarCoords.push([x,y])
     }

    if (addon == 0) {addon =  180*Math.PI/180} else {addon = 0}

    for(var i=1;i<=5; ++i){
       th=i * 2 * Math.PI/5 + addon
       x=xcenter+size/factor/factor*Math.sin(th);
       y=ycenter-size/factor/factor*Math.cos(th);
       innerPentCoords.push([x,y])
     }


 return [ outerStarCoords[4], innerPentCoords[2], outerStarCoords[2], innerPentCoords[3],outerStarCoords[0], innerPentCoords[4],outerStarCoords[3],innerPentCoords[0],outerStarCoords[1], innerPentCoords[1]]


}

function get_decagon_coords(xcenter, ycenter, size,orientation) {
    var decacoords1 = []
    for(var i=0;i<10; ++i){
      if (orientation == "pointed up") {addon = 0} else {addon =  180*Math.PI/180}
      var th=i * 2 * Math.PI/10 + 18*Math.PI/180  + addon;  // the 18 degrees makes it flat side down instead of vertex down
      var  x=xcenter+size*Math.sin(th);
      var  y=ycenter-size*Math.cos(th);
      decacoords1.push([x,y])
     }    
     return decacoords1
}

function get_Kepler_Monster_coords(xcenter, ycenter, size,orientation) {
    var decacoords1 = []
    for(var i=0;i<10; ++i){
      if (orientation == "pointed up") {addon = 0} else {addon =  180*Math.PI/180}
      var th=i * 2 * Math.PI/10 + 18*Math.PI/180  + addon;  // the 18 degrees makes it flat side down instead of vertex down
      var  x=xcenter+size*Math.sin(th);
      var  y=ycenter-size*Math.cos(th);
      decacoords1.push([x,y])
    } 
    var dec_sidelength =  Math.abs( decacoords1[9][0] - decacoords1[0][0])
    var dec_x_offset =    Math.abs( decacoords1[0][0] - decacoords1[1][0])
    var decacoords2 = []
    for (var i = 0; i<10; i++) {
      decacoords2[i] = [decacoords1[i][0] + 2*dec_x_offset + dec_sidelength, decacoords1[i][1] ]
    }
   // how to make a monster: dec1:  0 1, dec2: 9, 0, 1, 2, 3,4, 5,  dec1: 3, 4, 5, 6, 7, 8, 9

     return [decacoords1[0],decacoords1[1],decacoords2[9],decacoords2[0],decacoords2[1],decacoords2[2],decacoords2[3],decacoords2[4],decacoords2[5],decacoords1[3],decacoords1[4],decacoords1[5],decacoords1[6],decacoords1[7],decacoords1[8],decacoords1[9]]
}

/*
deccoords1 = get_decagon_coords(0, 0, radius, "pointed up")
dec_sidelength =  Math.abs( deccoords1[9][0] - deccoords1[0][0])
dec_x_offset =    Math.abs( deccoords1[0][0] - deccoords1[1][0])
var deccoords2 = []
   for (var i = 0; i<10; i++) {
      deccoords2[i] = [deccoords1[i][0] + 2*dec_x_offset + dec_sidelength, deccoords1[i][1] ]
   }
*/

/*
deccoords1 = get_decagon_coords(0, 0, radius, "pointed up")
build_verts_and_faces (deccoords1, "decagon")
         //  dec_sidelength = 2 * radius * Math.sin(Math.PI/10)

//2*dec_sidelength+dec_sidelength*Math.cos(36*Math.PI/180)
// dec_sidelength*Math.cos(36*Math.PI/180) 

dec_sidelength =  Math.abs( deccoords1[9][0] - deccoords1[0][0])
dec_x_offset = Math.abs( deccoords1[0][0] - deccoords1[1][0])
var deccoords2 = []
   for (var i = 0; i<10; i++) {
      deccoords2[i] = [deccoords1[i][0] + 2*dec_x_offset + dec_sidelength, deccoords1[i][1] ]
   }
build_verts_and_faces (deccoords2, "decagon")

*/



function make_Kepler_Aa_toast ( xcorner,ycorner, size,angle) {

    var pentcoords1 = []
    var pentcoords2 = []
    var thinrhombcoords1 = []

   pentcoords1 = get_pentagon_coords(0, 0, size, "pointed up")
   pentcoords2 =  get_pent_just_below_this_one(pentcoords1)

   var topstar = get_star_coords(0, ycorner+size-size/factor/factor, size/factor/factor, "pointed down")
   var top_small_6oclock_pent = get_pentagon_coords(0, ycorner+size+size/factor/factor, size/factor/factor/factor, "pointed up")
   var smallheight = Math.abs(top_small_6oclock_pent[0][1]  - top_small_6oclock_pent[2][1])
   var top_small_12oclock_pent = get_pentagon_coords(0, ycorner+size/factor/factor, size/factor/factor/factor, "pointed down")
   var top_small_3oclock_pent = get_pentagon_coords(topstar[2][0], topstar[2][1]-smallheight, size/factor/factor/factor, "pointed down")
   var top_small_7_oclock =  get_pent_just_below_this_one(get_pentagon_coords(topstar[4][0], topstar[4][1],size/factor/factor/factor, "pointed up")    )
   var top_small_5_oclock =  get_pent_just_below_this_one(get_pentagon_coords(topstar[6][0], topstar[6][1],size/factor/factor/factor, "pointed up")    )

   var decagon_radius = get_decagon_radius_from_pentagon_radius(size/factor/factor/factor)

   var imag_12dec = get_decagon_coords(xcorner, ycorner,  decagon_radius, "pointed up")
   var top_small_1oclock = get_pentagon_coords(imag_12dec[3][0], imag_12dec[3][1], size/factor/factor/factor, "pointed up")
   var top_small_3oclock  = get_pent_just_below_this_one(top_small_1oclock)
   var top_small_11oclock = get_pentagon_coords(imag_12dec[6][0], imag_12dec[6][1], size/factor/factor/factor, "pointed up")
   var top_small_9oclock  = get_pent_just_below_this_one(top_small_11oclock)

   var top_small_4oclock = get_pentagon_coords(top_small_3oclock[1][0], top_small_3oclock[1][1], size/factor/factor/factor, "pointed up")
   var top_small_8oclock = get_pentagon_coords(top_small_9oclock[4][0], top_small_9oclock[4][1], size/factor/factor/factor, "pointed up")

   rhomb_x_diff =  Math.abs( pentcoords2[0][0] - pentcoords1[1][0])
   rhomb_y_diff =  Math.abs( pentcoords2[0][1] - pentcoords1[1][1])

   thinrhombcoords1 = [pentcoords1[1], pentcoords1[2] , pentcoords2[1], []]
   thinrhombcoords1[3][0] = pentcoords1[2][0] + 2*(Math.abs( pentcoords1[2][0] - pentcoords1[1][0]))
   thinrhombcoords1[3][1] =  pentcoords1[2][1]
   for (var i = 0; i<4; i++) {
      thinrhombcoords1[i] = [thinrhombcoords1[i][0] -  rhomb_x_diff, thinrhombcoords1[i][1] +  rhomb_y_diff]
   }
  var top_decagon = get_decagon_coords(thinrhombcoords1[0][0], thinrhombcoords1[0][1], decagon_radius, "pointed up")
  var bottom_decagon = get_decagon_coords(thinrhombcoords1[2][0], thinrhombcoords1[2][1], decagon_radius, "pointed up")





   

    var xoffset = Math.abs(pentcoords1[0][0] - pentcoords1[1][0])
    var yoffset = Math.abs(pentcoords1[0][1] - pentcoords2[1][1])

     var yaxis = pentcoords2[2][1]

  var temp = mirror_y_coords(top_small_5_oclock, yaxis)

  var pent_in_rhomb1 =   get_pentagon_coords(thinrhombcoords1[0][0],temp[0][1]+rhomb_y_diff, size/factor/factor/factor, "pointed up")
  var temp = mirror_y_coords(top_small_12oclock_pent, yaxis)

  var pent_in_rhomb2 =    mirror_y_coords(pent_in_rhomb1, thinrhombcoords1[1][1])
  var Kepler_monster = get_Kepler_Monster_coords(thinrhombcoords1[1][0], thinrhombcoords1[1][1], decagon_radius, "pointed up")


/*
  var data = [{face: pentcoords1, name: "pentagon"},
              {face: pentcoords2, name: "pentagon"},
              {face: thinrhombcoords1, name: "rhomb"}]
*/
  var data = [{face: topstar, name: "star"},
              {face: top_small_6oclock_pent, name: "pentagon"},
              {face: top_small_12oclock_pent, name: "pentagon"},
              {face: top_small_1oclock, name: "pentagon"},
              {face: top_small_3oclock, name: "pentagon"},
              {face: top_small_4oclock, name: "pentagon"},

              {face: top_small_5_oclock, name: "pentagon"},
              {face: top_small_7_oclock, name: "pentagon"},
              {face: top_small_8oclock, name: "pentagon"},
              {face: top_small_9oclock, name: "pentagon"},
              {face: top_small_11oclock, name: "pentagon"},

              {face: mirror_y_coords(topstar, yaxis), name: "star"},
              {face: mirror_y_coords(top_small_6oclock_pent, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_12oclock_pent, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_1oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_3oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_4oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_5_oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_7_oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_8oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_9oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_11oclock, yaxis), name: "pentagon"},

              {face: top_decagon, name: "decagon"},
                       {face: pent_in_rhomb1, name: "pentagon"},
                       {face: Kepler_monster, name: "Kepler_Monster"},
                       {face: pent_in_rhomb2, name: "pentagon"},
              {face: bottom_decagon, name: "decagon"}]

   var perimeter_data = [{face: topstar, name: "star"},
              {face: top_small_6oclock_pent, name: "pentagon"},
              {face: top_small_12oclock_pent, name: "pentagon"},
              {face: top_small_1oclock, name: "pentagon"},
              {face: top_small_3oclock, name: "pentagon"},
              {face: top_small_4oclock, name: "pentagon"},

              {face: top_small_5_oclock, name: "pentagon"},
              {face: top_small_7_oclock, name: "pentagon"},
              {face: top_small_8oclock, name: "pentagon"},
              {face: top_small_9oclock, name: "pentagon"},
              {face: top_small_11oclock, name: "pentagon"},

              {face: mirror_y_coords(topstar, yaxis), name: "star"},
              {face: mirror_y_coords(top_small_6oclock_pent, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_12oclock_pent, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_1oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_3oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_4oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_5_oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_7_oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_8oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_9oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_11oclock, yaxis), name: "pentagon"}]

   var perimeter_data2 = [{face: topstar, name: "star"},
              {face: top_small_6oclock_pent, name: "pentagon"},
              {face: top_small_12oclock_pent, name: "pentagon"},
              {face: top_small_1oclock, name: "pentagon"},
              {face: top_small_3oclock, name: "pentagon"},
              {face: top_small_4oclock, name: "pentagon"},

              {face: top_small_5_oclock, name: "pentagon"},
              {face: top_small_7_oclock, name: "pentagon"},
              {face: top_small_8oclock, name: "pentagon"},
              {face: top_small_9oclock, name: "pentagon"},
              {face: top_small_11oclock, name: "pentagon"},

              {face: mirror_y_coords(topstar, yaxis), name: "star"},
              {face: mirror_y_coords(top_small_6oclock_pent, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_12oclock_pent, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_1oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_3oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_4oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_5_oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_7_oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_8oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_9oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_11oclock, yaxis), name: "pentagon"}]
 



//build_verts_and_faces (get_Kepler_Monster_coords(515.2106797860727, 0, radius*factor*factor, "pointed up"), "monster")

//build_verts_and_faces (get_star_coords(515.2106797860727, 0, radius*factor*factor, "pointed down"), "star")

wedge_tiling_from_data (515.2106797860727, 0,  maxLevel, 0, xoffset, yoffset, data, perimeter_data)

var big_outer_pent = get_pentagon_coords(515.2106797860727, 0, radius*factor*factor, "pointed up")
wedge_tiling_from_data (big_outer_pent[4][0],big_outer_pent[4][1],  maxLevel, -72, xoffset, yoffset, data, perimeter_data)

wedge_tiling_from_data (big_outer_pent[3][0],big_outer_pent[3][1],  maxLevel, -72-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (big_outer_pent[2][0],big_outer_pent[2][1],  maxLevel, -72-72-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (big_outer_pent[1][0],big_outer_pent[1][1],  maxLevel, -72-72-72-72, xoffset, yoffset, data, perimeter_data)

var small_inner_pent = get_pent_just_below_this_one(get_pentagon_coords(515.2106797860727, 0, radius, "pointed up"))
wedge_tiling_from_data (small_inner_pent[3][0],small_inner_pent[3][1],  maxLevel-1, -36, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (small_inner_pent[4][0],small_inner_pent[4][1],  maxLevel-1, -36-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (small_inner_pent[0][0],small_inner_pent[0][1],  maxLevel-1, -36-72-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (small_inner_pent[1][0],small_inner_pent[1][1],  maxLevel-1, -36-72-72-72, xoffset, yoffset, data, perimeter_data)
wedge_tiling_from_data (small_inner_pent[2][0],small_inner_pent[2][1],  maxLevel-1, -36-72-72-72-72, xoffset, yoffset, data, perimeter_data)


}

function make_Kepler_Aa_periodic ( xmax,ymax, size) {
    var xcorner = 0
    var ycorner = 0
    var pentcoords1 = []
    var pentcoords2 = []
    var thinrhombcoords1 = []

   pentcoords1 = get_pentagon_coords(0, 0, size, "pointed up")
   pentcoords2 =  get_pent_just_below_this_one(pentcoords1)

   var topstar = get_star_coords(0, ycorner+size-size/factor/factor, size/factor/factor, "pointed down")
   var top_small_6oclock_pent = get_pentagon_coords(0, ycorner+size+size/factor/factor, size/factor/factor/factor, "pointed up")
   var smallheight = Math.abs(top_small_6oclock_pent[0][1]  - top_small_6oclock_pent[2][1])
   var top_small_12oclock_pent = get_pentagon_coords(0, ycorner+size/factor/factor, size/factor/factor/factor, "pointed down")
   var top_small_3oclock_pent = get_pentagon_coords(topstar[2][0], topstar[2][1]-smallheight, size/factor/factor/factor, "pointed down")
   var top_small_7_oclock =  get_pent_just_below_this_one(get_pentagon_coords(topstar[4][0], topstar[4][1],size/factor/factor/factor, "pointed up")    )
   var top_small_5_oclock =  get_pent_just_below_this_one(get_pentagon_coords(topstar[6][0], topstar[6][1],size/factor/factor/factor, "pointed up")    )

   var decagon_radius = get_decagon_radius_from_pentagon_radius(size/factor/factor/factor)

   var imag_12dec = get_decagon_coords(xcorner, ycorner,  decagon_radius, "pointed up")
   var top_small_1oclock = get_pentagon_coords(imag_12dec[3][0], imag_12dec[3][1], size/factor/factor/factor, "pointed up")
   var top_small_3oclock  = get_pent_just_below_this_one(top_small_1oclock)
   var top_small_11oclock = get_pentagon_coords(imag_12dec[6][0], imag_12dec[6][1], size/factor/factor/factor, "pointed up")
   var top_small_9oclock  = get_pent_just_below_this_one(top_small_11oclock)

   var top_small_4oclock = get_pentagon_coords(top_small_3oclock[1][0], top_small_3oclock[1][1], size/factor/factor/factor, "pointed up")
   var top_small_8oclock = get_pentagon_coords(top_small_9oclock[4][0], top_small_9oclock[4][1], size/factor/factor/factor, "pointed up")

   rhomb_x_diff =  0 // Math.abs( pentcoords2[0][0] - pentcoords1[1][0])
   rhomb_y_diff =  0 // Math.abs( pentcoords2[0][1] - pentcoords1[1][1])

   thinrhombcoords1 = [pentcoords1[1], pentcoords1[2] , pentcoords2[1], []]
   thinrhombcoords1[3][0] = pentcoords1[2][0] + 2*(Math.abs( pentcoords1[2][0] - pentcoords1[1][0]))
   thinrhombcoords1[3][1] =  pentcoords1[2][1]
   for (var i = 0; i<4; i++) {
      thinrhombcoords1[i] = [thinrhombcoords1[i][0] -  rhomb_x_diff, thinrhombcoords1[i][1] +  rhomb_y_diff]
   }
  var top_decagon = get_decagon_coords(thinrhombcoords1[0][0], thinrhombcoords1[0][1], decagon_radius, "pointed up")
  var bottom_decagon = get_decagon_coords(thinrhombcoords1[2][0], thinrhombcoords1[2][1], decagon_radius, "pointed up")





   

    var xoffset = Math.abs(pentcoords1[0][0] - pentcoords1[1][0])
    var yoffset = Math.abs(pentcoords1[0][1] - pentcoords2[1][1])

     var yaxis = pentcoords2[2][1]

  var temp = mirror_y_coords(top_small_5_oclock, yaxis)

  var pent_in_rhomb1 =   get_pentagon_coords(thinrhombcoords1[0][0],temp[0][1]+rhomb_y_diff, size/factor/factor/factor, "pointed up")
  var temp = mirror_y_coords(top_small_12oclock_pent, yaxis)

  var pent_in_rhomb2 =    mirror_y_coords(pent_in_rhomb1, thinrhombcoords1[1][1])
  var Kepler_monster = get_Kepler_Monster_coords(thinrhombcoords1[1][0], thinrhombcoords1[1][1], decagon_radius, "pointed up")


/*
  var data = [{face: pentcoords1, name: "pentagon"},
              {face: pentcoords2, name: "pentagon"},
              {face: thinrhombcoords1, name: "rhomb"}]
*/
  var data = [{face: topstar, name: "star"},
              {face: top_small_6oclock_pent, name: "pentagon"},
              {face: top_small_12oclock_pent, name: "pentagon"},
              {face: top_small_1oclock, name: "pentagon"},
              {face: top_small_3oclock, name: "pentagon"},
              {face: top_small_4oclock, name: "pentagon"},

              {face: top_small_5_oclock, name: "pentagon"},
              {face: top_small_7_oclock, name: "pentagon"},
              {face: top_small_8oclock, name: "pentagon"},
              {face: top_small_9oclock, name: "pentagon"},
              {face: top_small_11oclock, name: "pentagon"},

              {face: mirror_y_coords(topstar, yaxis), name: "star"},
              {face: mirror_y_coords(top_small_6oclock_pent, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_12oclock_pent, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_1oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_3oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_4oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_5_oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_7_oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_8oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_9oclock, yaxis), name: "pentagon"},
              {face: mirror_y_coords(top_small_11oclock, yaxis), name: "pentagon"},

              {face: top_decagon, name: "decagon"},
                       {face: pent_in_rhomb1, name: "pentagon"},
                       {face: Kepler_monster, name: "Kepler_Monster"},
                       {face: pent_in_rhomb2, name: "pentagon"},
              {face: bottom_decagon, name: "decagon"}]



wedge_tiling_from_data (515.2106797860727, 0,  ymax, 0, xoffset, yoffset, data)
//square_tiling_from_data (xmax, ymax, xoffset*2, yoffset*2, data)

}


  
    return outsideacess;
}());

  

//********* relationship between a pentagon's radius and a decagon's radius when the two share a sidelength:
//  * decradius * Math.sin(Math.PI/10) =  2 * pentradius * Math.sin(Math.PI/5)  
function get_decagon_radius_from_pentagon_radius(pentradius) {
 return 2 * pentradius * Math.sin(Math.PI/5) /(2*Math.sin(Math.PI/10))
}




//***************************************** Kaplan's spiral version of Durer ********************

// calculations for Kaplan's spiral version of Durer
// pentradius = 400
// sidelength =  2 * 400 * Math.sin(Math.PI/5)  = 470.22820183397848
// sidelength = 2 * decradius * Math.sin(Math.PI/10) =   2 * pentradius * Math.sin(Math.PI/5) 
// decradius = 470.22820183397848/(2  * Math.sin(Math.PI/10))















var Penrose_P1_module = (function() {
    var outsideacess = {}
    var t = new Transform();
    var factor = (1 + Math.sqrt(5))/2   

    var maxLevel;
      
outsideacess.make_Penrose_P1_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
        var radius = 400;
    if (single_or_rosette == "single") {
        drawPentagon("Type 0", 900,600, radius, 0, 1)
    } 
    else {  // create a decagon consisting of one boat, two type two pentagons, one type one pentagon, and two rhombs
 
     var boatcoords =   
       drawStar("boat", 900, 600, radius*factor, 180, 1)
       t.translate(900,600); 
       t.rotate(180*Math.PI/180);
       var pent1coords = 
           drawPentagon("Type 2", boatcoords[4][0], boatcoords[4][1], radius, 72*2, 1)
            t.translate(boatcoords[4][0], boatcoords[4][1]); 
            t.rotate(72*2*Math.PI/180);
            draw10FoldRhomb (pent1coords[2][0],pent1coords[2][1], radius * (2*Math.sin(36*Math.PI/180)), 180, 1) 
            t.rotate(-72*2*Math.PI/180);
            t.translate(-boatcoords[4][0], -boatcoords[4][1]); 
       var pent1coords = 
            drawPentagon("Type 2", boatcoords[6][0], boatcoords[6][1], radius, 72*3, 1)
            t.translate(boatcoords[6][0], boatcoords[6][1]); 
            t.rotate(72*3*Math.PI/180);
            draw10FoldRhomb (pent1coords[3][0],pent1coords[3][1], radius * (2*Math.sin(36*Math.PI/180)), 180-108-36, 1) 
            t.rotate(-72*3*Math.PI/180);
            t.translate(-boatcoords[6][0], -boatcoords[6][1]);       
       t.rotate(-180*Math.PI/180);
       t.translate(-900,-600); 
      drawPentagon("Type 1", 900,600, radius, 0, 1)
    }


}


function makePentagon( xcorner,ycorner, size,angle, type) {  // see snowflake code to convert to substitution module

    var pentagoncoords = []
    var coords = []

    t.translate(xcorner,ycorner);
    t.rotate(angle*Math.PI/180);
    var xcenter = 0;
    var ycenter = 0 + size ;  
    pentagoncoords.push([xcenter,ycenter])
    coords.push([xcenter,ycenter])

    for(var i=1;i<=5; ++i){
       th=i * 2 * Math.PI/5;
       x=xcenter+size*Math.sin(th);
       y=ycenter-size*Math.cos(th);
       pentagoncoords.push([x,y])
       coords.push([x,y])

     }
     for (var i = 0; i<pentagoncoords.length; i++) {
         pentagoncoords[i] = t.transformPoint(pentagoncoords[i][0],pentagoncoords[i][1])
     }
    if (type  != "don't draw") {
       var verts_but_not_center = pentagoncoords.slice(1, pentagoncoords.length)
       build_verts_and_faces (verts_but_not_center, type)
    }
    t.rotate(-angle*Math.PI/180);
    t.translate(-xcorner,-ycorner); 
    return coords
}



 
function drawPentagon(type, xcorner,ycorner, size,angle, level) {
   if (level >= maxLevel) {
      return makePentagon(xcorner,ycorner, size,angle, type)
   }
  else {

   t.translate(xcorner,ycorner);
   t.rotate(angle*Math.PI/180);

        var tempcoords =  makePentagon(xcorner,ycorner, size,angle, "don't draw")

 
     // First  draw the five small pentagons, immediately below, 
    var subtype;
    if (type != "Type 2") {
        subtype = "Type 1" 
        drawPentagon(subtype, tempcoords[1][0], tempcoords[1][1], size/factor/factor, 72, level+1);  // 1 o clock
        drawPentagon(subtype, tempcoords[4][0], tempcoords[4][1], size/factor/factor, 72+72+72+72, level+1); // 11 o clock
    }
    else {
      
          var subcoords =  makePentagon(tempcoords[1][0], tempcoords[1][1], size/factor/factor,72, "don't draw");
             t.translate(tempcoords[1][0], tempcoords[1][1]);
             t.rotate((72)*Math.PI/180);
             drawPentagon("Type 2", subcoords[4][0], subcoords[4][1], size/factor/factor,-72, level+1);  
             t.rotate((-72)*Math.PI/180);
             t.translate(-tempcoords[1][0], -tempcoords[1][1]);

         subcoords = makePentagon(tempcoords[4][0], tempcoords[4][1], size/factor/factor,72+72+72+72, "don't draw");
             t.translate(tempcoords[4][0], tempcoords[4][1]);
             t.rotate((72+72+72+72)*Math.PI/180);
             drawPentagon("Type 2", subcoords[1][0], subcoords[1][1], size/factor/factor,72, level+1); 
             t.rotate(-(72+72+72+72)*Math.PI/180); 
             t.translate(-tempcoords[4][0], -tempcoords[4][1]);
    }




    if (type == "Type 0") {
          drawPentagon("Type 1", tempcoords[2][0], tempcoords[2][1], size/factor/factor,72+72, level+1);  // 5 o clock
          drawPentagon("Type 1", tempcoords[3][0], tempcoords[3][1], size/factor/factor, 72+72+72, level+1); // 7 o clock' 
    }

    if (type == "Type 1") {
          var subcoords = makePentagon(tempcoords[2][0], tempcoords[2][1], size/factor/factor,72+72, "don't draw");

             t.translate( tempcoords[2][0], tempcoords[2][1]);
             t.rotate((72+72)*Math.PI/180);
             drawPentagon("Type 2", subcoords[4][0], subcoords[4][1], size/factor/factor,-72, level+1);  
             t.rotate(-(72+72)*Math.PI/180);
             t.translate( -tempcoords[2][0], -tempcoords[2][1]);
         subcoords = makePentagon(tempcoords[3][0], tempcoords[3][1], size/factor/factor,72+72+72, "don't draw");
             t.translate(tempcoords[3][0], tempcoords[3][1]);
             t.rotate((72+72+72)*Math.PI/180);
             drawPentagon("Type 2", subcoords[1][0], subcoords[1][1], size/factor/factor,72, level+1);  
             t.rotate(-(72+72+72)*Math.PI/180);
             t.translate(-tempcoords[3][0], -tempcoords[3][1]);
          
    }

    if (type == "Type 2") {
          var subcoords = makePentagon(tempcoords[2][0], tempcoords[2][1], size/factor/factor,72+72, "don't draw");
             t.translate( tempcoords[2][0], tempcoords[2][1] );
             t.rotate((72+72)*Math.PI/180  );
             drawPentagon("Type 2", subcoords[1][0], subcoords[1][1], size/factor/factor,72, level+1);  
             t.rotate( -(72+72)*Math.PI/180  );
             t.translate( -tempcoords[2][0], -tempcoords[2][1] );

         subcoords = makePentagon(tempcoords[3][0], tempcoords[3][1], size/factor/factor,72+72+72, "don't draw");
             t.translate(tempcoords[3][0], tempcoords[3][1]  );
             t.rotate((72+72+72)*Math.PI/180  );
             drawPentagon("Type 2", subcoords[4][0], subcoords[4][1], size/factor/factor,-72, level+1);  
             t.rotate( -(72+72+72)*Math.PI/180 );
             t.translate( -tempcoords[3][0], -tempcoords[3][1] );
    }


     
   drawPentagon("Type 1", tempcoords[5][0], tempcoords[5][1], size/factor/factor, 0, level+1);  // 12 o clock position // Then draw the center pentagon

    var tempcoords2 = []
    tempcoords2 = drawPentagon("Type 0", tempcoords[0][0], tempcoords[0][1]+size/factor/factor, size/factor/factor, 180, level+1); // this is the center pentagon, which is always type 0
    
       // And finally draw the rhombs - zero rhombs, one rhombs, or two rhombs.   
      // note that draw10FoldRhomb requires the sidelength, not the pentagon center-to-corner size.

    //Start Rhomb section


             t.translate(  tempcoords[0][0],tempcoords[0][1]+size/factor/factor );
             t.rotate( 180*Math.PI/180 );

     if (type == "Type 1") { 
       draw10FoldRhomb (tempcoords2[5][0], tempcoords2[5][1], size * (2*Math.sin(36*Math.PI/180))/factor/factor, -72, level+1) 


      }

     if (type == "Type 2" ) { 
          draw10FoldRhomb (tempcoords2[1][0], tempcoords2[1][1], size * (2*Math.sin(36*Math.PI/180))/factor/factor,0, level+1) 
          draw10FoldRhomb (tempcoords2[4][0], tempcoords2[4][1], size * (2*Math.sin(36*Math.PI/180))/factor/factor, -72-72, level+1) 

     }


             t.rotate(-180*Math.PI/180 );
             t.translate(  -tempcoords[0][0],-(tempcoords[0][1]+size/factor/factor) );


   // End Rhomb section

  t.rotate(-angle*Math.PI/180);
  t.translate(-xcorner,-ycorner);  

  return tempcoords    
   }     
}




function draw10FoldRhomb (x, y, len, rot, level) {

    t.translate(x,y);
    t.rotate(rot*Math.PI/180);

    var a = 36.0
    var a_radians = a*Math.PI/180

    var x2 = len
    var y2 = 0

    var x3 = len + len*Math.cos(a_radians)
    var y3 = -len*Math.sin(a_radians)

    var x4 = len*Math.cos(a_radians)
    var y4 = -len*Math.sin(a_radians)

    if (level == maxLevel) {
         var rhombcoords = [[0,0],[x2,y2], [x3, y3], [x4,y4]]
        // var coords = [[[0,0],[x2,y2], [x3, y3], [x4,y4]]]
         for (var i = 0; i<rhombcoords.length; i++) {
             rhombcoords[i] = t.transformPoint(rhombcoords[i][0],rhombcoords[i][1])
         }
         build_verts_and_faces (rhombcoords, "rhomb")

      }
      else {
       
         var tempcoords = []
         tempcoords = drawStar("star", 0, 0, len/(2*Math.sin(36*Math.PI/180))/factor, -108, level+1)
         t.translate(tempcoords[9][0],tempcoords[9][1]);
         t.rotate(-108*Math.PI/180);
         drawPentagon("Type 2", tempcoords[10][0], tempcoords[10][1], len/(2*Math.sin(36*Math.PI/180))/factor/factor, 0, level+1, "rhomb");
         t.rotate(108*Math.PI/180);
         t.translate(-tempcoords[9][0],-tempcoords[9][1]);
         drawStar("boat", x3, y3, len/(2*Math.sin(36*Math.PI/180))/factor, 72, level+1)
     
                
      }

   t.rotate(-rot*Math.PI/180);
   t.translate(-x,-y);
}





function drawStar(type, xcorner,ycorner, size,angle, level) {
    var starcoords = []
    var outerStarCoords = []
    var innerPentCoords = []

    t.translate(xcorner,ycorner);
    t.rotate(angle*Math.PI/180);

    var xcenter = 0;
    var ycenter = 0 + size ;   
 
    outerStarCoords.push([xcenter,ycenter])
    for(var i=1;i<=5; ++i){
       var th=i * 4 * Math.PI/5;
       var x=xcenter+size*Math.sin(th);
       var y=ycenter-size*Math.cos(th);
       outerStarCoords.push([x,y])
     }

    innerPentCoords.push([xcenter,ycenter])
    for(var i=1;i<=5; ++i){
       var th=i * 2 * Math.PI/5 + 180*Math.PI/180 ;
       var x=xcenter+size/factor/factor*Math.sin(th);
       var y=ycenter-size/factor/factor*Math.cos(th);
       innerPentCoords.push([x,y])
     }

    starcoords.push([xcenter,ycenter])
    for(var i=1;i<=5; ++i){
      starcoords.push(outerStarCoords[i])
      starcoords.push(innerPentCoords[i])
     }


  if (level == maxLevel) {
    var transformcoords = []
    if (type.match("oat") == null) {
       transformcoords = [starcoords[1], starcoords[10], starcoords[7], starcoords[2], starcoords[3], starcoords[4], starcoords[9], starcoords[6], starcoords[5], starcoords[8]]
       for (var i = 0; i<transformcoords.length; i++) {
          transformcoords[i] = t.transformPoint(transformcoords[i][0],transformcoords[i][1])
        }
       build_verts_and_faces (transformcoords, "star")
    }
    else {
       transformcoords = [ starcoords[2], starcoords[3], starcoords[4], starcoords[9], starcoords[6], starcoords[5], starcoords[8]]
       for (var i = 0; i<transformcoords.length; i++) {
          transformcoords[i] = t.transformPoint(transformcoords[i][0],transformcoords[i][1])
        }
       build_verts_and_faces (transformcoords, "boat")

    }

  }
  else {
    drawStar("boat", starcoords[9][0], starcoords[9][1], size/factor/factor, 0, level+1)
    drawStar("boat", starcoords[5][0], starcoords[5][1], size/factor/factor, 72, level+1)
    if (type.match("oat") == null) {
     drawStar("boat", starcoords[1][0], starcoords[1][1], size/factor/factor, 72+72, level+1)
     drawStar("boat", starcoords[7][0], starcoords[7][1], size/factor/factor, 72+72+72, level+1)
    }
    drawStar("boat", starcoords[3][0], starcoords[3][1], size/factor/factor, 72+72+72+72, level+1)


    var tempcoords = []
    tempcoords = drawStar("star", starcoords[0][0], starcoords[0][1]+size/factor/factor, size/factor/factor, 180, level+1)

     t.translate(starcoords[0][0], starcoords[0][1]+size/factor/factor);
     t.rotate(180*Math.PI/180);

    drawPentagon("Type 2", tempcoords[2][0], tempcoords[2][1], size/factor/factor/factor,72, level+1)
    if (type.match("oat") == null) {  // Test for the "oat" in Boat and boat.
      drawPentagon("Type 2", tempcoords[4][0], tempcoords[4][1], size/factor/factor/factor,72+72, level+1)
      drawPentagon("Type 2", tempcoords[6][0], tempcoords[6][1], size/factor/factor/factor,72+72+72, level+1)
     }
    drawPentagon("Type 2", tempcoords[8][0], tempcoords[8][1], size/factor/factor/factor,72+72+72+72, level+1)
    drawPentagon("Type 2", tempcoords[10][0], tempcoords[10][1], size/factor/factor/factor,0, level+1)

     t.rotate(-180*Math.PI/180);
     t.translate(-starcoords[0][0], -(starcoords[0][1]+size/factor/factor));
  }
   

  t.rotate(-angle*Math.PI/180);
  t.translate(-xcorner,-ycorner);  

   return starcoords
}


  
    return outsideacess
}());



var Lord_module = (function() {
    
    var outsideacess = {}
    var t = new Transform();

var maxLevel ;
var factor = Math.sqrt(3);

outsideacess.make_Lord_Tiling = function(n, single_or_rosette) {
        maxLevel = n;
        var startSize = 1000;
        var initangle = 30
        draw3FoldRhomb(-1000.456,-10.456, startSize/Math.pow(factor, maxLevel-1), 0, maxLevel); // dummy rhomb to test initial hole bug
        draw3FoldRhomb(0,0, startSize, initangle, 1);
  }


/*
Lord_module.make_Lord_Tiling(2, "single")
 document.getElementById("Meshmakers_Div").setAttribute("style", "display: none;")  
initialize()
*/

function draw3FoldRhomb( x,  y,  len,  deg,  level) {

      t.translate(x, y);
      t.rotate(radians(deg));

     var a = 120;    // 5 is 360/8, so good for 8fold tilings.
     
     var x2 = len;
     var y2 = 0;

     var x3 = len + len*Math.cos(radians(a));
     var y3 = -len*Math.sin(radians(a));
     
     var x4 = len*Math.cos(radians(a));
     var y4 = -len*Math.sin(radians(a));
 
  if (level == maxLevel) {
            var coords = [[0,0], [x2, y2],[ x3, y3], [x4, y4]]
            for (var i = 0; i < coords.length; i++) {
                coords[i] = t.transformPoint(coords[i][0], coords[i][1])
            }
            build_verts_and_faces(coords, "rhomb");
  }
   else {
      var newlen =len/factor;

      draw3FoldRhomb (0, 0, newlen, -90, level+1);
      draw3FoldRhomb (0, 0, newlen, -90+120, level+1);
    //   draw3FoldRhomb (x2, y2, newlen, -90+120+180, level+1);   // non-essential?
      draw3FoldRhomb (x2, y2, newlen, -90+120+180+120, level+1); // essential
   //   draw3FoldRhomb (x3, y3, newlen, -90+120+120, level+1);   // non-essential?
      draw3FoldRhomb (x3, y3, newlen, -90+120+120+120, level+1); // essential
      draw3FoldRhomb (x4, y4, newlen, -90+180, level+1);

     
     }
   t.rotate(radians(-deg))
   t.translate(-x, -y);
}
    return outsideacess;
}());


Anon7 - 2021