|
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 : |
// 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;
}());