stitch-compute
Version:
compute stitch adjustments for knitting
192 lines (191 loc) • 7.39 kB
JavaScript
/*
* Copyright (C) 2021 Christian Garbs <mitch@cgarbs.de>
* Licensed under GNU GPL v3 or later.
*
* This file is part of stitch-compute.
*
* stitch-compute is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* stitch-compute is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with stitch-compute. If not, see <http://www.gnu.org/licenses/>.
*/
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StitchCompute = void 0;
var greatest_common_divisor_1 = require("./greatest-common-divisor");
var group_formatter_1 = require("./group-formatter");
var list_formatter_1 = require("./list-formatter");
var number_formatter_1 = require("./number-formatter");
var StitchCompute = /** @class */ (function () {
function StitchCompute() {
this.keepFormatter = new number_formatter_1.NumberFormatter('K%d');
this.addFormatter = new number_formatter_1.NumberFormatter('A%d');
this.combineFormatter = new number_formatter_1.NumberFormatter('C%d');
this.groupFormatter = new group_formatter_1.GroupFormatter('%dx ( %s )');
this.listFormatter = new list_formatter_1.ListFormatter(' ');
}
StitchCompute.prototype.adjustEvenly = function (from, to) {
if (from === to) {
return this.keep(from);
}
var max = 2 * from;
var min = Math.floor((from + 1) / 2);
if (to > max) {
throw new Error("too many stitches to add - ".concat(from, " can grow to ").concat(max, " max"));
}
if (to < min) {
throw new Error("too few stitches to keep - ".concat(from, " can shrink to ").concat(min, " min"));
}
var repetitions = (0, greatest_common_divisor_1.greatestCommonDivisor)(from, to);
if (repetitions > 1) {
var group = this.adjustEvenly(from / repetitions, to / repetitions);
return this.groupFormatter.format(repetitions, group);
}
else {
var actions = this.calculateActions(to, from);
this.combineActions(actions);
this.normalizeActions(actions);
var elements = this.formatActions(actions);
return this.listFormatter.format(elements);
}
};
StitchCompute.prototype.setFormatters = function (formatters) {
if (this.isSet(formatters.keepStitches)) {
this.keepFormatter = new number_formatter_1.NumberFormatter(formatters.keepStitches);
}
if (this.isSet(formatters.addStitches)) {
this.addFormatter = new number_formatter_1.NumberFormatter(formatters.addStitches);
}
if (this.isSet(formatters.combineStitches)) {
this.combineFormatter = new number_formatter_1.NumberFormatter(formatters.combineStitches);
}
if (this.isSet(formatters.groupInstructions)) {
this.groupFormatter = new group_formatter_1.GroupFormatter(formatters.groupInstructions);
}
if (this.isSet(formatters.listSeparator)) {
this.listFormatter = new list_formatter_1.ListFormatter(formatters.listSeparator);
}
};
StitchCompute.prototype.isSet = function (string) {
return string != undefined && string != null;
};
StitchCompute.prototype.calculateActions = function (to, from) {
var actions = [];
var grow = to > from;
var shrink = to < from;
var allshrink = to * 2 == from;
var oldpos = 0;
var newpos = 0.0;
while (oldpos < from || newpos < to) {
var diff = oldpos - (newpos / to) * from;
if (allshrink || (diff < 0 && shrink)) {
actions.push(new Action(Type.Combine));
oldpos += 2;
newpos++;
}
else if (diff > 0 && grow) {
actions.push(new Action(Type.Add));
newpos++;
}
else {
actions.push(new Action(Type.Keep));
oldpos++;
newpos++;
}
}
return actions;
};
StitchCompute.prototype.normalizeActions = function (actions) {
if (actions.length < 2) {
return;
}
var first = actions[0];
var last = actions[actions.length - 1];
if (first.type === last.type) {
this.equalizeActionCounts(first, last);
}
else if (first.count === 1 && last.count > 1) {
this.moveHalfOfLastActionToFront(actions);
}
};
StitchCompute.prototype.equalizeActionCounts = function (first, last) {
var diff = Math.floor((first.count - last.count) / 2);
first.count -= diff;
last.count += diff;
};
StitchCompute.prototype.moveHalfOfLastActionToFront = function (actions) {
var last = actions[actions.length - 1];
var toMove = Math.floor(last.count / 2);
var extraAction = __assign({}, last);
last.count -= toMove;
extraAction.count = toMove;
actions.unshift(extraAction);
};
StitchCompute.prototype.combineActions = function (actions) {
var lastType = null;
var pos = 0;
while (pos < actions.length) {
var current = actions[pos];
if (lastType === current.type) {
actions[pos - 1].count++;
actions.splice(pos, 1);
}
else {
lastType = current.type;
pos++;
}
}
};
StitchCompute.prototype.formatActions = function (actions) {
var _this = this;
return actions.map(function (action) {
var count = action.count;
var type = action.type;
switch (type) {
case Type.Keep:
return _this.keepFormatter.format(count);
case Type.Combine:
return _this.combineFormatter.format(count);
case Type.Add:
return _this.addFormatter.format(count);
}
});
};
StitchCompute.prototype.keep = function (count) {
return this.keepFormatter.format(count);
};
return StitchCompute;
}());
exports.StitchCompute = StitchCompute;
var Type;
(function (Type) {
Type[Type["Keep"] = 0] = "Keep";
Type[Type["Combine"] = 1] = "Combine";
Type[Type["Add"] = 2] = "Add";
})(Type || (Type = {}));
var Action = /** @class */ (function () {
function Action(type) {
this.count = 1;
this.type = type;
}
return Action;
}());
;