我使用dxf解析器(https://github.com/bjnortier/dxf)读取NodeJS中dxf文件(仅2D)的内容,然后我得到一个包含以下输出的数组:
我根据Bresenham算法编写了3个函数来设置数组中所需的像素,我想稍后用它来绘制画布。
输入参数是
module.exports: {
processLINE: function(data, coordSystem) {
var setPixel = function(x, y) {
x = Math.ceil(x);
y = Math.ceil(y);
coordSystem[x][y] = 1;
}
var line = function(x0, y0, x1, y1) {
var dx = Math.abs(x1-x0);
var dy = Math.abs(y1-y0);
var sx = (x0 < x1) ? 1 : -1;
var sy = (y0 < y1) ? 1 : -1;
var err = dx-dy;
var e2;
while(true) {
setPixel(x0,y0);
if ((x0===x1) && (y0===y1)) break;
e2 = 2*err;
if (e2 >-dy){ err -= dy; x0 += sx; }
if (e2 < dx){ err += dx; y0 += sy; }
}
}
line(Math.ceil(data.start.x), Math.ceil(data.start.y), Math.ceil(data.end.x), Math.ceil(data.end.y))
return coordSystem;
},
processCIRCLE: function(data, coordSystem) {
var setPixel = function(x, y) {
x = Math.ceil(x);
y = Math.ceil(y);
coordSystem[x][y] = 1;
}
var createCircle = function(x0, y0, radius)
{
var f = 1 - radius;
var ddF_x = 0;
var ddF_y = -2 * radius;
var x = 0;
var y = radius;
setPixel(x0, y0 + radius);
setPixel(x0, y0 - radius);
setPixel(x0 + radius, y0);
setPixel(x0 - radius, y0);
while(x < y)
{
if(f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x + 1;
setPixel(x0 + x, y0 + y);
setPixel(x0 - x, y0 + y);
setPixel(x0 + x, y0 - y);
setPixel(x0 - x, y0 - y);
setPixel(x0 + y, y0 + x);
setPixel(x0 - y, y0 + x);
setPixel(x0 + y, y0 - x);
setPixel(x0 - y, y0 - x);
}
}
createCircle(data.x, data.y, data.r);
return coordSystem;
},
processARC: function(data, coordSystem) {
var setPixel = function(x, y, coordinates) {
x = Math.ceil(x);
y = Math.ceil(y);
coordSystem[x][y] = 1;
}
var createPartialcircle = function()
{
startAngle = data.startAngle*180/Math.PI;
endAngle = data.endAngle*180/Math.PI;
if(startAngle>endAngle) {
for (var i=startAngle; i>endAngle; i--) {
var radians = i * Math.PI / 180;
var px = data.x - data.r * Math.cos(radians);
var py = data.y - data.r * Math.sin(radians);
setPixel(px, py, coordinates);
}
} else {
for (var i=startAngle; i<endAngle; i++) {
var radians = i * Math.PI / 180;
var px = data.x + data.r * Math.cos(radians);
var py = data.y + data.r * Math.sin(radians);
setPixel(px, py, coordinates);
}
}
}
createPartialcircle(data.x, data.y, data.r);
return coordSystem;
}
}
有了这个,我得到以下形状: 你可以看到它的工作原理,但是有一些“漏洞”,因此我的最后一个函数应该填充孔形状(扫描线算法),效果不好......
以下是填充形状的方法 我从HERE获取了这段代码,并用JavaScript-Style编写了它。
function scanLineFill(config, data, x, y, fillColor) {
function getPixel(x,y) {
return data[x][y];
}
function setPixel(x,y) {
data[x][y] = fillColor;
}
// Config
var nMinX = 0;
var nMinY = 0;
var nMaxX = config.maxValues.x;
var nMaxY = config.maxValues.y;
var seedColor = getPixel(x,y);
function lineFill(x1, x2, y) {
var xL,xR;
if( y < nMinY || nMaxY < y || x1 < nMinX || nMaxX < x1 || x2 < nMinX || nMaxX < x2 )
return;
for( xL = x1; xL >= nMinX; --xL ) { // scan left
if( getPixel(xL,y) !== seedColor )
break;
setPixel(xL,y);
}
if( xL < x1 ) {
lineFill(xL, x1, y-1); // fill child
lineFill(xL, x1, y+1); // fill child
++x1;
}
for( xR = x2; xR <= nMaxX; ++xR ) { // scan right
console.log('FOR: xR --> ', xR)
if( getPixel(xR,y) !== seedColor )
break;
setPixel(xR,y);
}
if( xR > x2 ) {
lineFill(x2, xR, y-1); // fill child
lineFill(x2, xR, y+1); // fill child
--x2;
}
for( xR = x1; xR <= x2 && xR <= nMaxX; ++xR ) { // scan betweens
if( getPixel(xR,y) === seedColor )
setPixel(xR,y);
else {
if( x1 < xR ) {
// fill child
lineFill(x1, xR-1, y-1);
// fill child
lineFill(x1, xR-1, y+1);
x1 = xR;
}
// Note: This function still works if this step is removed.
for( ; xR <= x2 && xR <= nMaxX; ++xR) { // skip over border
if( getPixel(xR,y) === seedColor ) {
x1 = xR--;
break;
}
}
}
}
}
if( fillColor !== seedColor ) {
lineFill(x, x, y);
}
return data;
}
结果如下:
我认为如果形状没有孔,填充功能会填充正确的形状。但是我怎么能实现这个目标呢?