turtlestitch/stitchcode/turtleShepherd.js

562 wiersze
15 KiB
JavaScript
Czysty Zwykły widok Historia

2017-01-20 09:49:47 +00:00
/*
TurtleShepherd
2017-01-25 11:10:31 +00:00
turltestich's embroidery intelligence agency
2017-01-20 09:49:47 +00:00
*/
2017-01-19 22:00:37 +00:00
2017-01-21 11:29:20 +00:00
function TurtleShepherd() {
this.init();
}
TurtleShepherd.prototype.init = function() {
2017-01-19 22:00:37 +00:00
this.clear();
2017-01-25 11:10:31 +00:00
this.gridSize = 50;
this.showJumpStitches = false;
this.showStitches = false;
this.showGrid = false;
this.showTurtle = false;
2017-05-22 22:04:48 +00:00
this.metric = true;
2017-10-06 13:45:32 +00:00
this.pixels_per_millimeter = 5;
2017-01-21 11:29:20 +00:00
};
2017-01-19 22:00:37 +00:00
2017-05-22 22:04:48 +00:00
2017-01-20 09:49:47 +00:00
TurtleShepherd.prototype.clear = function() {
this.cache = [];
2017-01-25 11:10:31 +00:00
this.w = 0;
this.h = 0;
2017-01-20 09:49:47 +00:00
this.minX = 0;
this.minY = 0;
this.maxX = 0;
this.maxY = 0;
this.initX = 0;
this.initY = 0;
this.scale = 1;
2017-01-24 15:23:00 +00:00
this.steps = 0;
2017-01-24 14:26:11 +00:00
this.stitchCount = 0;
this.jumpCount = 0;
2017-01-21 11:29:20 +00:00
};
2017-05-22 22:04:48 +00:00
TurtleShepherd.prototype.toggleMetric = function() {
return this.metric = !this.metric;
};
TurtleShepherd.prototype.setMetric = function(b) {
this.metric = b;
};
TurtleShepherd.prototype.isMetric = function() {
return this.metric;
};
2017-01-20 09:49:47 +00:00
TurtleShepherd.prototype.hasSteps = function() {
return this.steps > 0;
};
2017-01-24 15:23:00 +00:00
TurtleShepherd.prototype.getStepCount = function() {
return this.steps;
};
TurtleShepherd.prototype.getJumpCount = function() {
return this.jumpCount;
};
TurtleShepherd.prototype.getDimensions = function() {
2017-05-22 22:04:48 +00:00
if (this.metric) {
2017-06-15 21:14:37 +00:00
//c = 1;
//unit = "mm";
c = 0.1
unit = "cm";
2017-05-22 22:04:48 +00:00
} else {
c = 0.03937;
unit = "in";
2017-06-15 21:14:37 +00:00
}
2017-10-06 13:45:32 +00:00
w= ((this.maxX - this.minX)/ this.pixels_per_millimeter * c).toFixed(2).toString();
h= ((this.maxY - this.minY)/ this.pixels_per_millimeter * c).toFixed(2).toString();
2017-05-22 22:04:48 +00:00
return w + " x " + h + " " + unit;
2017-01-24 15:23:00 +00:00
};
TurtleShepherd.prototype.getMetricWidth = function() {
c = 0.1
return ((this.maxX - this.minX)/5 * c).toFixed(2).toString();
};
TurtleShepherd.prototype.getMetricHeight = function() {
c = 0.1
return((this.maxY - this.minY)/5 * c).toFixed(2).toString();
};
2017-01-24 15:23:00 +00:00
TurtleShepherd.prototype.moveTo= function(x1, y1, x2, y2, penState) {
2017-01-21 15:50:09 +00:00
x = Math.round(x);
y = Math.round(y);
2017-01-25 11:10:31 +00:00
2017-01-20 09:49:47 +00:00
if (this.steps === 0) {
2017-01-24 15:23:00 +00:00
this.initX = x1;
this.initY = y1;
this.minX = x1;
this.minY = y1;
this.maxX = x1;
this.maxY = y1;
2017-01-25 11:10:31 +00:00
this.cache.push(
{
"cmd":"move",
"x":x1,
"y":y1,
"penDown":penState,
}
);
2017-01-19 22:00:37 +00:00
} else {
2017-01-24 15:23:00 +00:00
if (x2 < this.minX) this.minX = x2;
if (x2 > this.maxX) this.maxX = x2;
2017-01-19 22:00:37 +00:00
2017-01-24 15:23:00 +00:00
if (y2 < this.minY) this.minY = y2;
if (y2 > this.maxY) this.maxY = y2;
2017-01-19 22:00:37 +00:00
}
2017-01-25 11:10:31 +00:00
this.cache.push(
{
"cmd":"move",
"x":x2,
"y":y2,
"penDown":penState,
}
);
this.w = this.maxX - this.minX;
this.h = this.maxY - this.minY;
2017-01-24 15:23:00 +00:00
if (!penState)
this.jumpCount++;
else {
this.steps++;
}
2017-01-19 22:00:37 +00:00
};
2017-01-20 09:32:01 +00:00
TurtleShepherd.prototype.addColorChange= function(color) {
2017-01-19 22:00:37 +00:00
this.cache.push(
{
"cmd":"color",
"color":{
r: Math.round(color.r),
g: Math.round(color.g),
b: Math.round(color.b),
a: Math.round(color.a) || 0
},
2017-01-19 22:00:37 +00:00
}
);
};
2017-01-20 09:32:01 +00:00
TurtleShepherd.prototype.toSVG = function() {
2017-01-19 22:00:37 +00:00
2017-01-25 11:10:31 +00:00
var svgStr = "<?xml version=\"1.0\" standalone=\"no\"?>\n";
svgStr += "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \n\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
svgStr += '<svg width="' + (this.w) + '" height="' + (this.h) + '"' +
2017-01-26 21:38:17 +00:00
' viewBox="0 0 ' + (this.w) + ' ' + (this.h) + '"';
2017-01-19 22:00:37 +00:00
svgStr += ' xmlns="http://www.w3.org/2000/svg" version="1.1">\n';
svgStr += '<title>Embroidery export</title>\n';
hasFirst = false;
tagOpen = false;
lastStitch = null;
color = { r:0, g:0, b:0 };
2017-01-20 09:49:47 +00:00
2017-01-19 22:00:37 +00:00
for (var i=0; i < this.cache.length; i++) {
if (this.cache[i].cmd == "color") {
/*if (tagOpen) svgStr += '" />\n';
color = {
r: this.cache[i].color.r,
g: this.cache[i].color.g,
b: this.cache[i].color.b
};
tagOpen = false;*/
} else if (this.cache[i].cmd == "move") {
2017-01-19 22:00:37 +00:00
stitch = this.cache[i];
if (!hasFirst) {
if (stitch.penDown) {
svgStr += '<path fill="none" style="stroke:rgb('+
color.r + ',' + color.g + ',' + color.b +
')" d="M ' +
2017-01-26 21:38:17 +00:00
(this.initX - this.minX) +
2017-01-19 22:00:37 +00:00
' ' +
2017-01-26 21:38:17 +00:00
(this.maxY - this.initY) ;
2017-01-19 22:00:37 +00:00
hasFirst = true;
tagOpen = true;
} else {
2017-01-25 11:10:31 +00:00
/* is jum
2017-01-19 22:00:37 +00:00
svgStr += '<path stroke="red" stroke-dasharray="4 4" d="M ' +
this.initX +
' ' +
this.initY +
' L ' +
(stitch.x) +
' ' +
(stitch.y) +
'" />\n' ;
2017-01-25 11:10:31 +00:00
*/
//hasFirst = true;
2017-01-19 22:00:37 +00:00
}
2017-01-19 22:00:37 +00:00
} else {
if (stitch.penDown ) {
if (!lastStich.penDown ) {
svgStr +=' <path fill="none" style="stroke:rgb('+
color.r + ',' + color.g + ',' + color.b +
')" d="M ' +
(lastStich.x - this.minX) +
2017-01-19 22:00:37 +00:00
' ' +
(lastStich.y - this.minY ) +
2017-01-19 22:00:37 +00:00
' L ' +
2017-01-26 21:38:17 +00:00
(stitch.x - this.minX) +
2017-01-19 22:00:37 +00:00
' ' +
2017-01-26 21:38:17 +00:00
(this.maxY - stitch.y);
2017-01-19 22:00:37 +00:00
}
svgStr += ' L ' +
2017-01-26 21:38:17 +00:00
(stitch.x- this.minX) +
2017-01-19 22:00:37 +00:00
' ' +
2017-01-26 21:38:17 +00:00
(this.maxY - stitch.y);
2017-01-19 22:00:37 +00:00
tagOpen = true;
} else {
2017-01-25 11:10:31 +00:00
if (tagOpen) svgStr += '" />\n';
tagOpen = false;
/* is jump
2017-01-19 22:00:37 +00:00
svgStr += '<path stroke="red" stroke-dasharray="4 4" d="M ' +
(this.cache[i-1].x) +
' ' +
(this.cache[i-1].y) +
' L ' +
(stitch.x) +
' ' +
(stitch.y) +
'" />\n' ;
2017-01-25 11:10:31 +00:00
*/
2017-01-19 22:00:37 +00:00
}
}
lastStich = stitch;
2017-01-19 22:00:37 +00:00
}
}
if (tagOpen) svgStr += '" />\n';
svgStr += '</svg>\n';
return svgStr;
};
2017-01-20 09:49:47 +00:00
TurtleShepherd.prototype.toEXP = function() {
2017-01-25 11:10:31 +00:00
var expArr = [];
2017-10-06 13:45:32 +00:00
pixels_per_millimeter = this.pixels_per_millimeter;
2017-01-25 11:10:31 +00:00
scale = 10 / pixels_per_millimeter;
lastStitch = null;
hasFirst = false;
2017-01-25 11:10:31 +00:00
function move(x, y) {
y *= -1;
if (x<0) x = x + 256;
expArr.push(Math.round(x));
if (y<0) y = y + 256;
expArr.push(Math.round(y));
2017-01-20 17:33:32 +00:00
}
2017-01-20 16:43:55 +00:00
for (var i=0; i < this.cache.length; i++) {
if (this.cache[i].cmd == "color") {
//expArr.push(0x01);
//expArr.push(0x01);
} else if (this.cache[i].cmd == "move") {
stitch = this.cache[i];
if (hasFirst) {
x1 = Math.round(stitch.x * scale);
y1 = -Math.round(stitch.y * scale);
x0 = Math.round(lastStitch.x * scale);
y0 = -Math.round(lastStitch.y * scale);
sum_x = 0;
sum_y = 0;
dmax = Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
2017-07-10 18:32:55 +00:00
dsteps = Math.abs(dmax / 127);
if (dsteps <= 1) {
if (!stitch.penDown) {
//ignore color
//expArr.push(0x80);
//expArr.push(0x04);
2017-01-25 11:10:31 +00:00
}
move(Math.round(x1 - x0), Math.round(y1 - y0));
} else {
for(j=0;j<dsteps;j++) {
if (!stitch.penDown) {
expArr.push(0x80);
expArr.push(0x04);
}
if (j < dsteps -1) {
move((x1 - x0)/dsteps, (y1 - y0)/dsteps);
sum_x += (x1 - x0)/dsteps;
sum_y += (y1 - y0)/dsteps;
} else {
move(Math.round((x1 - x0) - sum_x),
Math.round((y1 - y0) - sum_y));
}
2017-01-25 11:10:31 +00:00
}
}
2017-01-20 17:33:32 +00:00
}
lastStitch = stitch;
hasFirst = true;
2017-01-20 16:43:55 +00:00
}
}
2017-01-25 11:10:31 +00:00
expUintArr = new Uint8Array(expArr.length);
for (i=0;i<expArr.length;i++) {
expUintArr[i] = Math.round(expArr[i]);
}
return expUintArr;
2017-01-20 16:43:55 +00:00
};
TurtleShepherd.prototype.toDST = function() {
var expArr = [];
lastStitch = null;
hasFirst = false;
2017-10-06 13:45:32 +00:00
pixels_per_millimeter = this.pixels_per_millimeter;
scale = 10 / pixels_per_millimeter;
function encodeTajimaStitch(dx, dy, jump) {
b1 = 0;
b2 = 0;
b3 = 0;
if (dx > 40) {
b3 |= 0x04;
dx -= 81;
}
if (dx < -40) {
b3 |= 0x08;
dx += 81;
}
if (dy > 40) {
b3 |= 0x20;
dy -= 81;
}
if (dy < -40) {
b3 |= 0x10;
dy += 81;
}
if (dx > 13) {
b2 |= 0x04;
dx -= 27;
}
if (dx < -13) {
b2 |= 0x08;
dx += 27;
}
if (dy > 13) {
b2 |= 0x20;
dy -= 27;
}
if (dy < -13) {
b2 |= 0x10;
dy += 27;
}
if (dx > 4) {
b1 |= 0x04;
dx -= 9;
}
if (dx < -4) {
b1 |= 0x08;
dx += 9;
}
if (dy > 4) {
b1 |= 0x20;
dy -= 9;
}
if (dy < -4) {
b1 |= 0x10;
dy += 9;
}
if (dx > 1) {
b2 |= 0x01;
dx -= 3;
}
if (dx < -1) {
b2 |= 0x02;
dx += 3;
}
if (dy > 1) {
b2 |= 0x80;
dy -= 3;
}
if (dy < -1) {
b2 |= 0x40;
dy += 3;
}
if (dx > 0) {
b1 |= 0x01;
dx -= 1;
}
if (dx < 0) {
b1 |= 0x02;
dx += 1;
}
if (dy > 0) {
b1 |= 0x80;
dy -= 1;
}
if (dy < 0) {
b1 |= 0x40;
dy += 1;
}
expArr.push(b1);
expArr.push(b2);
if (jump) {
expArr.push(b3 | 0x83);
} else {
expArr.push(b3 | 0x03);
}
}
function writeHeader(str, length, padWithSpace=false) {
for(var i = 0; i<length-2; i++) {
if (i < str.length) {
expArr.push("0xF1" + str[i].charCodeAt(0).toString(16));
} else {
if (padWithSpace) {
expArr.push(0x20);
} else {
expArr.push(0x00);
}
}
}
expArr.push(0x0A);
expArr.push(0x1A);
}
writeHeader("LA:turtlestitch", 20, true);
writeHeader("ST:" + this.steps.toString(), 11);
writeHeader("CO:1", 7);
2017-10-06 13:45:32 +00:00
writeHeader("+X:" + Math.round(this.maxX / this.pixels_per_millimeter), 9); // Math.round(this.getMetricWidth()*10), 9);
writeHeader("-X:" + Math.round(this.minX / this.pixels_per_millimeter), 9);
writeHeader("+Y:" + Math.round(this.maxY/ this.pixels_per_millimeter), 9); //Math.round(this.getMetricHeight()*10), 9);
writeHeader("-Y:" + Math.round(this.minY / this.pixels_per_millimeter), 9);
needle_end_x = 0;
needle_end_y = 0;
for (i=0; i < this.cache.length; i++) {
if (this.cache[i].cmd == "move")
needle_end_x = this.cache[i].x;
needle_end_y = this.cache[i].y;
}
writeHeader("AX:+" + Math.round(needle_end_x / this.pixels_per_millimeter), 10);
writeHeader("AY:+" + Math.round(needle_end_y / this.pixels_per_millimeter), 10);
writeHeader("MX:0", 10);
writeHeader("MY:0", 10);
2017-10-05 16:11:54 +00:00
writeHeader("PD:******", 10);
expArr.push(0x1a);
expArr.push(0x00);
expArr.push(0x00);
expArr.push(0x00);
// Print empty header
for (var i=0; i<384; i++) {
expArr.push(0x20);
}
2017-07-10 18:32:55 +00:00
for (i=0; i < this.cache.length; i++) {
if (this.cache[i].cmd == "color") {
//expArr.push(0x01);
//expArr.push(0x01);
} else if (this.cache[i].cmd == "move") {
2017-07-10 18:32:55 +00:00
stitch = this.cache[i];
if (hasFirst) {
x1 = Math.round(stitch.x * scale);
y1 = Math.round(stitch.y * scale);
x0 = Math.round(lastStitch.x * scale);
y0 = Math.round(lastStitch.y * scale);
sum_x = 0;
sum_y = 0;
2017-07-10 18:32:55 +00:00
dmax = Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
dsteps = Math.abs(dmax / 121);
2017-07-10 18:32:55 +00:00
if (dsteps <= 1) {
encodeTajimaStitch((x1 - x0), (y1 - y0),
!stitch.penDown);
} else {
for(j=0;j<dsteps;j++) {
//if (tStitch.stitches.jump[i]) {
// expArr.push(0x80);
// expArr.push(0x04);
//}
if (j < dsteps -1) {
encodeTajimaStitch(
Math.round((x1 - x0)/dsteps),
Math.round((y1 - y0)/dsteps),
!stitch.penDown
);
sum_x += (x1 - x0)/dsteps;
sum_y += (y1 - y0)/dsteps;
} else {
encodeTajimaStitch(
Math.round((x1 - x0) - sum_x),
Math.round((y1 - y0) - sum_y),
!stitch.penDown
);
encodeTajimaStitch(0,0,false);
}
}
}
}
lastStitch = stitch;
hasFirst = true;
}
}
expArr.push(0x00);
expArr.push(0x00);
expArr.push(0xF3);
expUintArr = new Uint8Array(expArr.length);
for (i=0;i<expArr.length;i++) {
expUintArr[i] = Math.round(expArr[i]);
}
return expUintArr;
};
2017-01-20 09:49:47 +00:00
TurtleShepherd.prototype.debug_msg = function (st, clear) {
o = "";
if (!clear) {
o = document.getElementById("debug").innerHTML;
} else {
o = "";
}
o = st + "<br />" + o;
document.getElementById("debug").innerHTML = o;
};