Issue #146 : Improve shift+stroke to draw more uniform lines
This commit is contained in:
parent
c70e339296
commit
20b7eb2a3c
2 changed files with 64 additions and 51 deletions
|
@ -98,11 +98,11 @@
|
||||||
var pixels = [];
|
var pixels = [];
|
||||||
var dx = Math.abs(x1 - x0);
|
var dx = Math.abs(x1 - x0);
|
||||||
var dy = Math.abs(y1 - y0);
|
var dy = Math.abs(y1 - y0);
|
||||||
|
|
||||||
var sx = (x0 < x1) ? 1 : -1;
|
var sx = (x0 < x1) ? 1 : -1;
|
||||||
var sy = (y0 < y1) ? 1 : -1;
|
var sy = (y0 < y1) ? 1 : -1;
|
||||||
var err = dx - dy;
|
var err = dx - dy;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
// Do what you need to for this
|
// Do what you need to for this
|
||||||
pixels.push({'col': x0, 'row': y0});
|
pixels.push({'col': x0, 'row': y0});
|
||||||
|
|
||||||
|
@ -120,6 +120,65 @@
|
||||||
y0 += sy;
|
y0 += sy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return pixels;
|
||||||
|
};
|
||||||
|
|
||||||
|
var dist = function (x0, x1, y0, y1) {
|
||||||
|
var dx = Math.abs(x1 - x0);
|
||||||
|
var dy = Math.abs(y1 - y0);
|
||||||
|
return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
||||||
|
};
|
||||||
|
|
||||||
|
var MAX_STEP = 5;
|
||||||
|
ns.BaseTool.prototype.getUniformLinePixels_ = function (x0, x1, y0, y1) {
|
||||||
|
var pixels = [];
|
||||||
|
|
||||||
|
x1 = pskl.utils.normalize(x1, 0);
|
||||||
|
y1 = pskl.utils.normalize(y1, 0);
|
||||||
|
|
||||||
|
var dx = Math.abs(x1 - x0);
|
||||||
|
var dy = Math.abs(y1 - y0);
|
||||||
|
|
||||||
|
var ratio = Math.max(dx, dy) / Math.min(dx, dy);
|
||||||
|
// in pixel art, lines should use uniform number of pixels for each step
|
||||||
|
var pixelStep = Math.round(ratio);
|
||||||
|
// invalid step, bail out
|
||||||
|
if (pixelStep === 0 || isNaN(pixelStep)) {
|
||||||
|
return pixels;
|
||||||
|
}
|
||||||
|
// the tool should make it easy to draw straight lines
|
||||||
|
if (pixelStep > MAX_STEP && pixelStep < MAX_STEP * 2) {
|
||||||
|
pixelStep = MAX_STEP;
|
||||||
|
} else if (pixelStep >= MAX_STEP * 2) {
|
||||||
|
pixelStep = Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sx = (x0 < x1) ? 1 : -1;
|
||||||
|
var sy = (y0 < y1) ? 1 : -1;
|
||||||
|
|
||||||
|
var x = x0;
|
||||||
|
var y = y0;
|
||||||
|
var maxDistance = dist(x0, x1, y0, y1);
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
while (true) {
|
||||||
|
i++;
|
||||||
|
|
||||||
|
pixels.push({'col': x, 'row': y});
|
||||||
|
if (dist(x0, x, y0, y) >= maxDistance) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isAtStep = i % pixelStep === 0;
|
||||||
|
if (dx >= dy || isAtStep) {
|
||||||
|
x += sx;
|
||||||
|
}
|
||||||
|
if (dy >= dx || isAtStep) {
|
||||||
|
y += sy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return pixels;
|
return pixels;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -90,13 +90,13 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Stroke.prototype.draw_ = function (col, row, color, targetFrame, penSize, isStraight) {
|
ns.Stroke.prototype.draw_ = function (col, row, color, targetFrame, penSize, isStraight) {
|
||||||
|
var linePixels;
|
||||||
if (isStraight) {
|
if (isStraight) {
|
||||||
var coords = this.getStraightLineCoordinates_(col, row);
|
linePixels = this.getUniformLinePixels_(this.startCol, col, this.startRow, row);
|
||||||
col = coords.col;
|
} else {
|
||||||
row = coords.row;
|
linePixels = this.getLinePixels_(col, this.startCol, row, this.startRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
var linePixels = this.getLinePixels_(this.startCol, col, this.startRow, row);
|
|
||||||
pskl.PixelUtils.resizePixels(linePixels, penSize).forEach(function (point) {
|
pskl.PixelUtils.resizePixels(linePixels, penSize).forEach(function (point) {
|
||||||
targetFrame.setPixel(point[0], point[1], color);
|
targetFrame.setPixel(point[0], point[1], color);
|
||||||
});
|
});
|
||||||
|
@ -108,50 +108,4 @@
|
||||||
this.draw_(replayData.col, replayData.row, replayData.color, frame, replayData.penSize, replayData.isStraight);
|
this.draw_(replayData.col, replayData.row, replayData.color, frame, replayData.penSize, replayData.isStraight);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert col, row to be on the nearest straight line or 45 degrees diagonal.
|
|
||||||
*/
|
|
||||||
ns.Stroke.prototype.getStraightLineCoordinates_ = function(col, row) {
|
|
||||||
// coordinates translated using startCol, startRow as origin
|
|
||||||
var tCol = col - this.startCol;
|
|
||||||
var tRow = this.startRow - row;
|
|
||||||
|
|
||||||
var dist = Math.sqrt(Math.pow(tCol, 2) + Math.pow(tRow, 2));
|
|
||||||
|
|
||||||
var axisDistance = Math.round(dist);
|
|
||||||
var diagDistance = Math.round(dist / Math.sqrt(2));
|
|
||||||
|
|
||||||
var PI8 = Math.PI / 8;
|
|
||||||
var angle = Math.atan2(tRow, tCol);
|
|
||||||
if (angle < PI8 && angle >= -PI8) {
|
|
||||||
row = this.startRow;
|
|
||||||
col = this.startCol + axisDistance;
|
|
||||||
} else if (angle >= PI8 && angle < 3 * PI8) {
|
|
||||||
row = this.startRow - diagDistance;
|
|
||||||
col = this.startCol + diagDistance;
|
|
||||||
} else if (angle >= 3 * PI8 && angle < 5 * PI8) {
|
|
||||||
row = this.startRow - axisDistance;
|
|
||||||
col = this.startCol;
|
|
||||||
} else if (angle >= 5 * PI8 && angle < 7 * PI8) {
|
|
||||||
row = this.startRow - diagDistance;
|
|
||||||
col = this.startCol - diagDistance;
|
|
||||||
} else if (angle >= 7 * PI8 || angle < -7 * PI8) {
|
|
||||||
row = this.startRow;
|
|
||||||
col = this.startCol - axisDistance;
|
|
||||||
} else if (angle >= -7 * PI8 && angle < -5 * PI8) {
|
|
||||||
row = this.startRow + diagDistance;
|
|
||||||
col = this.startCol - diagDistance;
|
|
||||||
} else if (angle >= -5 * PI8 && angle < -3 * PI8) {
|
|
||||||
row = this.startRow + axisDistance;
|
|
||||||
col = this.startCol;
|
|
||||||
} else if (angle >= -3 * PI8 && angle < -PI8) {
|
|
||||||
row = this.startRow + diagDistance;
|
|
||||||
col = this.startCol + diagDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
col : col,
|
|
||||||
row : row
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})();
|
})();
|
||||||
|
|
Loading…
Reference in a new issue