@imaginary-maths/durden
Version:
Pentagonal tiling animation
1,022 lines (892 loc) • 31.7 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Durden = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
var _tiling = _interopRequireDefault(require("./tiling"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Durden =
/*#__PURE__*/
function () {
/**
* Constructor
*
* @param {HTMLElement} container
* The container for the tiling
* @param {Number} n
* Number of supertiles horizontally
* @param {Number} m
* Number of supertiles vertically
* @param {Number} angle
* Starting angle (in Durden.MIN_ANGLE, Durden.MAX_ANGLE range)
*/
function Durden(container, n, m) {
var angle = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : Durden.MAX_ANGLE;
_classCallCheck(this, Durden);
this.canvas = window.document.createElement('canvas');
container.appendChild(this.canvas);
paper.setup(this.canvas);
paper.view.applyMatrix = false;
this.tiling = new _tiling["default"](n, m);
this.bcdeLen = 50;
this.transformTiles(this.bcdeLen, angle, true);
paper.view.update();
paper.view.on('frame', function () {
TWEEN.update();
});
}
/**
* Returns a randomly shuffled list of all the tiles in the tiling.
* @return {Array}
*/
_createClass(Durden, [{
key: "getShuffledTiles",
value: function getShuffledTiles() {
return Durden.shuffle(this.tiling.getAllTiles());
}
/**
* Returns a randomly shuffled list of all the tiles in the tiling.
* @return {Array}
*/
}, {
key: "getShuffledSuperTiles",
value: function getShuffledSuperTiles() {
return Durden.shuffle(this.tiling.getAllSuperTiles());
}
}, {
key: "showTilesRandom",
/**
* Shows the tiles progressively in random order
*
* @param {Number} duration
* Length of the animation in seconds
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
value: function showTilesRandom(duration) {
return Durden.setTileVisibilityAnimated(this.getShuffledTiles(), true, duration);
}
/**
* Shows supertiles progressively in random order
*
* @param {Number} duration
* Length of the animation in seconds
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
}, {
key: "showSuperTilesRandom",
value: function showSuperTilesRandom(duration) {
return Durden.setTileVisibilityAnimated(this.getShuffledSuperTiles(), true, duration);
}
/**
* Shows tiles progressively in random order
*
* @param {Number} duration
* Length of the animation in seconds
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
}, {
key: "hideTilesRandom",
value: function hideTilesRandom(duration) {
return Durden.setTileVisibilityAnimated(this.getShuffledTiles(), false, duration);
}
/**
* Hides supertiles progressively in random order
*
* @param {Number} duration
* Length of the animation in seconds
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
}, {
key: "hideSuperTilesRandom",
value: function hideSuperTilesRandom(duration) {
return Durden.setTileVisibilityAnimated(this.getShuffledSuperTiles(), false, duration);
}
/**
* Shows the tiles progressively in order
*
* @param {Number} duration
* Length of the animation in seconds
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
}, {
key: "showTilesOrdered",
value: function showTilesOrdered(duration) {
return Durden.setTileVisibilityAnimated(this.tiling.getAllTiles(), true, duration);
}
/**
* Hides tiles progressively in order
*
* @param {Number} duration
* Length of the animation in seconds
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
}, {
key: "hideTilesOrdered",
value: function hideTilesOrdered(duration) {
return Durden.setTileVisibilityAnimated(this.tiling.getAllTiles(), false, duration);
}
/**
* Shows supertiles progressively in order
*
* @param {Number} duration
* Length of the animation in seconds
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
}, {
key: "showSuperTilesOrdered",
value: function showSuperTilesOrdered(duration) {
return Durden.setTileVisibilityAnimated(this.tiling.getAllSuperTiles(), true, duration);
}
/**
* Hides supertiles progressively in order
*
* @param {Number} duration
* Length of the animation in seconds
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
}, {
key: "hideSuperTilesOrdered",
value: function hideSuperTilesOrdered(duration) {
return Durden.setTileVisibilityAnimated(this.tiling.getAllSuperTiles(), false, duration);
}
/**
* Set the visibility of all tiles
*
* @param {boolean} visibility
* True if they should be shown, false if hidden
*/
}, {
key: "setTileVisibility",
value: function setTileVisibility(visibility) {
this.tiling.getAllTiles().forEach(function (tile) {
tile.path.opacity = visibility ? 1 : 0;
});
}
/**
* Change the visibility of an (ordered) list of tiles progressively
*
* @param {Array} tiles
* Ordered list of tiles or supertiles to show
* @param {boolean} visibility
* True if tiles should be made visible
* @param {Number} duration
* Length of the animation in seconds
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
}, {
key: "getBounds",
/**
* Returns the inner bounding box of the tiling.
*
* The inner bounding box should be the maximal rectangle which is, at all points in the
* transformation, completely covered by tiles.
*
* @return {paper.Rectangle}
*/
value: function getBounds() {
var corner1 = this.tiling.superTiles[0][0].group.bounds.center;
var corner2 = this.tiling.superTiles[0][this.tiling.m - 1].group.bounds.center;
var corner3 = this.tiling.superTiles[this.tiling.n - 1][0].group.bounds.center;
var corner4 = this.tiling.superTiles[this.tiling.n - 1][this.tiling.m - 1].group.bounds.center;
var minX = Math.min(corner1.x, corner3.x);
var maxX = Math.max(corner2.x, corner4.x);
var minY = Math.min(corner1.y, corner2.y, corner3.y, corner4.y);
var maxY = Math.max(corner1.y, corner2.y, corner3.y, corner4.y);
return new paper.Rectangle({
from: new paper.Point(minX, minY),
to: new paper.Point(maxX, maxY)
});
}
/**
* Animates the transformation of the shape of the tiles while maintaining the tiling.
*
* The angles and side length of the tiles are modified within the parameters
* of a Type 8 pentagonal tiling.
*
* @param {Number} duration
* Length of the animation
* @param {Number} angleFrom
* Starting angle (in range Durden.MIN_ANGLE, Durden.MAX_ANGLE)
* @param {Number} angleTo
* Ending angle (in range Durden.MIN_ANGLE, Durden.MAX_ANGLE)
* Whether to rescale the animation viewport to completely fill the container
* @param {boolean} rescale
* If true the tiling will be stretched to fill the container
* @return {Tween}
* An instance of Tween (check tweenjs docs)
*/
}, {
key: "transformTilesAnimated",
value: function transformTilesAnimated(duration) {
var _this = this;
var angleFrom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Durden.MIN_ANGLE;
var angleTo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Durden.MAX_ANGLE;
var rescale = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
return new TWEEN.Tween({
angle: angleFrom
}).to({
angle: angleTo
}, duration).easing(TWEEN.Easing.Sinusoidal.InOut).onUpdate(function (progress) {
_this.transformTiles(_this.bcdeLen, progress.angle, rescale);
}).repeat(Infinity).yoyo(true).start();
}
/**
* Transforms the shape of the tiles and adjusts the view.
*
* @param {Number} segmentLen
* Length of the segments. Only the E-A segment has a different length.
* @param {Number} angB
* Angle for vertex B (in degrees)
* @param {boolean} rescale
* Whether the tiling should be rescaled to fill the container
*/
}, {
key: "transformTiles",
value: function transformTiles(segmentLen, angB) {
var rescale = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
this.tiling.transform(segmentLen, angB);
var bounds = this.getBounds();
if (rescale) {
if (paper.view.getViewSize().width > bounds.width || paper.view.getViewSize().height > bounds.height) {
paper.view.setScaling(Math.max(paper.view.getViewSize().width / bounds.width, paper.view.getViewSize().height / bounds.height));
} else {
paper.view.setScaling(Math.max(paper.view.getViewSize().width / bounds.width, paper.view.getViewSize().height / bounds.height));
}
}
paper.view.setCenter(bounds.getCenter());
}
/**
* Set the stroke (contour line) of all the tiles
*
* @param {Number} width
* Stroke width
* @param {String} fillColor
* Stroke color (in #rrggbb format)
*/
}, {
key: "setStroke",
value: function setStroke(width, fillColor) {
this.tiling.getAllTiles().forEach(function (tile) {
tile.setStroke(width, fillColor);
});
}
/**
* Color the supertiles in the tiling randomly.
*
* @param {Array} colors
* List of colors (as '#rrggbb' strings).
*/
}, {
key: "colorSuperTilesRandom",
value: function colorSuperTilesRandom(colors) {
this.tiling.getAllSuperTiles().forEach(function (superTile) {
var color = colors[Math.floor(Math.random() * colors.length)];
superTile.tile1.path.fillColor = color;
superTile.tile2.path.fillColor = color;
superTile.tile3.path.fillColor = color;
superTile.tile4.path.fillColor = color;
});
}
/**
* Color the tiles in the tiling randomly
*
* @param {Array} colors
* List of colors (as '#rrggbb' strings).
*/
}, {
key: "colorTilesRandom",
value: function colorTilesRandom(colors) {
this.tiling.getAllTiles().forEach(function (tile) {
tile.path.fillColor = colors[Math.floor(Math.random() * colors.length)];
});
}
/**
* Color the tiles in the tiling cyclically using the colors in order.
*
* @param {Array} colors
* List of colors (as '#rrggbb' strings).
*/
}, {
key: "colorTilesPeriodic",
value: function colorTilesPeriodic(colors) {
this.tiling.getAllTiles().forEach(function (tile, i) {
tile.path.fillColor = colors[i % colors.length];
});
}
/**
* Color the supertiles in the tiling cyclically using the colors in order.
*
* @param {Array} colors
* List of colors (as '#rrggbb' strings).
*/
}, {
key: "colorSuperTilesPeriodic",
value: function colorSuperTilesPeriodic(colors) {
this.tiling.getAllTiles().forEach(function (tile, i) {
tile.path.fillColor = colors[Math.floor(i / 4) % colors.length];
});
}
}], [{
key: "shuffle",
value: function shuffle(anArray) {
var currentIndex = anArray.length; // While there remain elements to shuffle...
while (currentIndex !== 0) {
// Pick a remaining element...
var randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1; // And swap it with the current element.
var temporaryValue = anArray[currentIndex];
anArray[currentIndex] = anArray[randomIndex];
anArray[randomIndex] = temporaryValue;
}
return anArray;
}
}, {
key: "setTileVisibilityAnimated",
value: function setTileVisibilityAnimated(tiles, visibility, duration) {
var shown = 0;
return new TWEEN.Tween({
last: 0
}).to({
last: tiles.length - 1
}, duration).easing(TWEEN.Easing.Cubic.In).onUpdate(function (progress) {
var last = Math.floor(progress.last);
for (var i = shown; i <= last; i += 1) {
tiles[i].setVisibility(visibility);
}
shown = last;
}).start();
}
}]);
return Durden;
}();
Durden.MAX_ANGLE = _tiling["default"].MAX_B;
Durden.MIN_ANGLE = _tiling["default"].MIN_B;
Durden.Themes = {
RGB: ['#ff9999', '#99ff99', '#9999ff', '#ff99ff'],
Spring: ['#54678C', '#9BDAF2', '#F2C12E', '#F2E1C2', '#D95252'],
Flowers: ['#D95B96', '#BABF1B', '#D9981E', '#D9751E', '#8C1616'],
Autumn: ['#A62447', '#D9326F', '#525F43', '#6C2A35', '#D9936A'],
Winter: ['#0B0340', '#263973', '#495F8C', '#A0CCF2', '#514071'],
Christmas: ['#F2293A', '#F24464', '#678C5D', '#730202', '#BFBFBD']
};
module.exports = {
Durden: Durden,
Themes: Durden.Themes,
MIN_ANGLE: Durden.MIN_ANGLE,
MAX_ANGLE: Durden.MAX_ANGLE
};
},{"./tiling":4}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _tile = _interopRequireDefault(require("./tile"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
/**
* A SuperTile is a group of four adjacent tiles, each of which is flipped
* in each of the four different ways. SuperTiles can be placed in a grid
* to create a Tiling.
*
* Each of the "outer" vertexes of a SuperTile has a name according to its position:
* N = North, NNE = North-northeast, NEE=Northeast-east, etc.
*/
var SuperTile =
/*#__PURE__*/
function () {
function SuperTile() {
_classCallCheck(this, SuperTile);
this.tile1 = new _tile["default"]('#ff9999', false, false);
this.tile2 = new _tile["default"]('#99ff99', true, false);
this.tile3 = new _tile["default"]('#9999ff', false, true);
this.tile4 = new _tile["default"]('#ff99ff', true, true);
this.group = new paper.Group([this.tile1.path, this.tile2.path, this.tile3.path, this.tile4.path]);
this.group.applyMatrix = false;
}
/**
* Alters the shape of the SuperTile according to the arguments
*
* @param {Number} segmentLength
* Length of the segments. Only the E-A segment has a different length.
* @param {Number} angB
* Angle for vertex B (in degrees)
*/
_createClass(SuperTile, [{
key: "transform",
value: function transform(segmentLength, angB) {
this.tile1.transform(segmentLength, angB);
this.tile2.copyShape(this.tile1, false);
this.tile3.copyShape(this.tile1, false);
this.tile4.copyShape(this.tile1, false); // Align segment E-A of tile2 to E-A of tile1
this.tile2.path.rotate(this.tile1.vE.subtract(this.tile1.vA).getAngle() - this.tile2.vE.subtract(this.tile2.vA).getAngle()); // Move vertex A of tile2 to vertex A of tile1
this.tile2.path.translate(this.tile1.vA.subtract(this.tile2.vA)); // Align segment D-C of tile3 to E-D of tile1
this.tile3.path.rotate(this.tile1.vE.subtract(this.tile1.vD).getAngle() - this.tile3.vD.subtract(this.tile3.vC).getAngle()); // Move vertex D of tile3 to vertex E of tile1
this.tile3.path.translate(this.tile1.vE.subtract(this.tile3.vD)); // Align segment E-A of tile4 to E-A of tile3
this.tile4.path.rotate(this.tile3.vE.subtract(this.tile3.vA).getAngle() - this.tile4.vE.subtract(this.tile4.vA).getAngle()); // Move vertex A of tile4 to vertex A of tile3
this.tile4.path.translate(this.tile3.vA.subtract(this.tile4.vA));
}
/**
* Sets visibility of the supertile
*
* @param {boolean} visible
* True if it should be made visible, false to hide it.
*/
}, {
key: "setVisibility",
value: function setVisibility(visible) {
this.tile1.setVisibility(visible);
this.tile2.setVisibility(visible);
this.tile3.setVisibility(visible);
this.tile4.setVisibility(visible);
}
/**
* North vertex
* @return {paper.Point}
*/
}, {
key: "copyShape",
/**
* Makes this tile copy the shape of another supertile.
*
* The "shape" is defined by the shape of all the tiles and their transformation matrixes.
*
*/
value: function copyShape(superTile) {
this.tile1.copyShape(superTile.tile1);
this.tile2.copyShape(superTile.tile2);
this.tile3.copyShape(superTile.tile3);
this.tile4.copyShape(superTile.tile4);
}
}, {
key: "north",
get: function get() {
return this.group.localToParent(this.tile1.vA);
}
/**
* North-northeast vertex
* @return {paper.Point}
*/
}, {
key: "nne",
get: function get() {
return this.group.localToParent(this.tile1.vB);
}
/**
* Northeast-east vertex
* @return {paper.Point}
*/
}, {
key: "nee",
get: function get() {
return this.group.localToParent(this.tile1.vC);
}
/**
* South vertex
* @return {paper.Point}
*/
}, {
key: "south",
get: function get() {
return this.group.localToParent(this.tile3.vA);
}
/**
* Southeast vertex
* @return {paper.Point}
*/
}, {
key: "se",
get: function get() {
return this.group.localToParent(this.tile3.vB);
}
/**
* South-southwest vertex
* @return {paper.Point}
*/
}, {
key: "ssw",
get: function get() {
return this.group.localToParent(this.tile4.vB);
}
/**
* Southwest-west vertex
* @return {paper.Point}
*/
}, {
key: "sww",
get: function get() {
return this.group.localToParent(this.tile4.vC);
}
/**
* East vertex
* @return {paper.Point}
*/
}, {
key: "east",
get: function get() {
return this.group.localToParent(this.tile1.vD);
}
/**
* West vertex
* @return {paper.Point}
*/
}, {
key: "west",
get: function get() {
return this.group.localToParent(this.tile2.vC);
}
/**
* Northwest vertex
* @return {paper.Point}
*/
}, {
key: "nw",
get: function get() {
return this.group.localToParent(this.tile2.vB);
}
}]);
return SuperTile;
}();
exports["default"] = SuperTile;
},{"./tile":3}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
/* globals paper */
/**
* A single tile
*
* D
* / \
* / \
* E \
* | C
* | |
* | |
* | |
* A-------------B
*
*/
var Tile =
/*#__PURE__*/
function () {
/**
* Constructor
*
* @param {string} fillColor
* Tile color
* @param {boolean} flipH
* If true the tile will be flipped horizontally
* @param {boolean} flipV
* If true the tile will be flipped vertically
*/
function Tile(fillColor) {
var flipH = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var flipV = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
_classCallCheck(this, Tile);
this.path = new paper.Path();
this.path.closed = true;
this.path.applyMatrix = false;
this.path.scale(flipH ? -1 : 1, flipV ? -1 : 1);
this.path.fillColor = fillColor;
this.path.strokeColor = '#999999';
this.path.strokeWidth = 1;
this.path.strokeJoin = 'bevel';
for (var i = 0; i < 5; i += 1) {
this.path.add(new paper.Point(0, 0));
}
}
/**
* Alters the shape of the tile according to the arguments
*
* @param {Number} segmentLen
* Length of the segments. Only the E-A segment has a different length.
* @param {Number} angB
* Angle for vertex B (in degrees)
*/
_createClass(Tile, [{
key: "transform",
value: function transform(segmentLen, angB) {
var segments = this.path.segments;
var angC = 360.0 - 2.0 * angB;
var beta = (180 - angB) / 2;
var lengtha = 2 * Math.sin(angB / 2 * Math.PI / 180); // Law of cosines
var lengthb = Math.sqrt(lengtha * lengtha + 2 * 2 - 2 * lengtha * 2 * Math.cos((angC - beta) * Math.PI / 180)); // Law of sines: sin((angC - beta))/lengthb = sin(d/2)/lengtha
var angD = 2 * Math.asin(Math.sin((angC - beta) * Math.PI / 180) / lengthb * lengtha) * 180 / Math.PI; // If you don't read the next line you're not an accomplice and your soul is still saved. SORRY.
// const angD = angB * 1.51 - 99.38
// + ((1 - Math.cos((angB - 109) * Math.PI / 180)) * 17.5 - 0.5); // UGLY
var angles = [0, angB, angC, angD];
var angle = 0;
[1, 2, 3, 4].forEach(function (i) {
angle += 180 - angles[i - 1];
segments[i].point.set(segments[i - 1].point.add(new paper.Point({
length: segmentLen,
angle: angle
})));
});
}
/**
* Modify the tile's stroke (contour line)
*
* @param {Number} width
* Stroke width
* @param {String} color
* Stroke color (in #rrggbb format)
*/
}, {
key: "setStroke",
value: function setStroke(width, color) {
this.path.strokeWidth = width;
this.path.strokeColor = color;
}
/**
* Set the inner color of the tile
*
* @param {String} color
* Fill color (in #rrggbb format)
*/
}, {
key: "setColor",
value: function setColor(color) {
this.path.fillColor = color;
}
/**
* Sets visibility of the tile
*
* @param {boolean} visible
* True if it should be made visible, false to hide it.
*/
}, {
key: "setVisibility",
value: function setVisibility(visible) {
this.path.opacity = visible ? 1 : 0;
}
/**
* Vertex A
* @return {paper.Point}
*/
}, {
key: "copyShape",
/**
* Makes this tile copy the shape of another tile
*
* The "shape" includes the position of all vertices and the transformation matrix.
*
* @param {Tile} tile
* @param {boolean} copyMatrix
* Whether to copy the transformation matrix
*/
value: function copyShape(tile) {
var copyMatrix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
for (var i = 1; i <= 4; i += 1) {
this.path.segments[i].point.set(tile.path.segments[i].point);
}
if (copyMatrix) {
this.path.setMatrix(tile.path.getMatrix());
}
}
}, {
key: "vA",
get: function get() {
return this.path.localToParent(this.path.segments[0].point);
}
/**
* Vertex B
* @return {paper.Point}
*/
}, {
key: "vB",
get: function get() {
return this.path.localToParent(this.path.segments[1].point);
}
/**
* Vertex C
* @return {paper.Point}
*/
}, {
key: "vC",
get: function get() {
return this.path.localToParent(this.path.segments[2].point);
}
/**
* Vertex D
* @return {paper.Point}
*/
}, {
key: "vD",
get: function get() {
return this.path.localToParent(this.path.segments[3].point);
}
/**
* Vertex E
* @return {paper.Point}
*/
}, {
key: "vE",
get: function get() {
return this.path.localToParent(this.path.segments[4].point);
}
}]);
return Tile;
}();
exports["default"] = Tile;
},{}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _supertile = _interopRequireDefault(require("./supertile"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
/**
* A pentagonal tiling
*/
var Tiling =
/*#__PURE__*/
function () {
/**
* Builds a tiling of n x m SuperTiles
*
* @param {Number} n
* @param {Number} m
*/
function Tiling(n, m) {
_classCallCheck(this, Tiling);
this.n = n;
this.m = m;
this.superTiles = Tiling.createMatrix(this.n, this.m); // Create and connect supertiles
for (var i = 0; i < this.n; i += 1) {
for (var j = 0; j < this.m; j += 1) {
this.superTiles[i][j] = new _supertile["default"]();
if (j % 2 === 1) {
// Supertiles in odd rows are flipped and rotated
this.superTiles[i][j].group.scale(1, -1);
}
}
}
}
/**
* Alters the shape of the tiles according to the arguments
*
* @param {Number} segmentLen
* Length of the segments. Only the E-A segment has a different length.
* @param {Number} angB
* Angle for vertex B (in degrees)
*/
_createClass(Tiling, [{
key: "transform",
value: function transform(segmentLen, angB) {
var firstTile = this.superTiles[0][0];
firstTile.transform(segmentLen, angB); // This baseAngle produces an almost rectangular "stacking" of supertiles
var baseAngle = 180 - firstTile.tile4.vB.subtract(firstTile.tile1.vC).getAngle();
var flippedAngle = angB + firstTile.tile2.vB.subtract(firstTile.tile2.vA).getAngle();
this.superTiles[0][0].group.rotation = baseAngle;
for (var i = 0; i < this.n; i += 1) {
for (var j = 0; j < this.m; j += 1) {
if (i === 0 && j === 0) {
// eslint-disable-next-line no-continue
continue;
}
this.superTiles[i][j].copyShape(firstTile);
if (j % 2 === 1) {
// Supertiles in odd rows are rotated
this.superTiles[i][j].group.rotation = baseAngle + flippedAngle;
} else {
this.superTiles[i][j].group.rotation = baseAngle;
}
var distances = [];
if (i > 0) {
if (j % 2 === 1) {
distances.push(this.superTiles[i - 1][j].sww.subtract(this.superTiles[i][j].nne));
} else {
distances.push(this.superTiles[i - 1][j].nne.subtract(this.superTiles[i][j].sww));
}
}
if (j > 0) {
distances.push(this.superTiles[i][j - 1].south.subtract(this.superTiles[i][j].west));
}
if (distances.length === 1) {
this.superTiles[i][j].group.translate(distances[0]);
}
if (distances.length === 2) {
this.superTiles[i][j].group.translate(distances[0].add(distances[1]).multiply(0.5));
}
}
}
}
/**
* Returns all the tiles in the tiling
* @return {[]}
*/
}, {
key: "getAllTiles",
value: function getAllTiles() {
var tiles = [];
this.superTiles.forEach(function (row) {
row.forEach(function (superTile) {
tiles.push(superTile.tile1);
tiles.push(superTile.tile2);
tiles.push(superTile.tile3);
tiles.push(superTile.tile4);
});
});
return tiles;
}
}, {
key: "getAllSuperTiles",
value: function getAllSuperTiles() {
var superTiles = [];
this.superTiles.forEach(function (row) {
row.forEach(function (superTile) {
superTiles.push(superTile);
});
});
return superTiles;
}
/**
* Creates an empty matrix of size n x m
*
* @param {Number} n
* @param {Number} m
* @return {[]}
*/
}], [{
key: "createMatrix",
value: function createMatrix(n, m) {
var matrix = [];
for (var i = 0; i < n; i += 1) {
var newRow = [];
for (var j = 0; j < m; j += 1) {
newRow.push([]);
}
matrix.push(newRow);
}
return matrix;
}
}]);
return Tiling;
}();
exports["default"] = Tiling;
Tiling.MIN_B = 74;
Tiling.MAX_B = 156;
},{"./supertile":2}]},{},[1])(1)
});