比较画布上的线条

时间:2013-05-16 10:31:52

标签: javascript html5 canvas

我有一个画布,我画了4行。 然后我需要将绘制的线条的精度与4条预定义线条的坐标进行比较。 我可以用帆布做到这一点吗?

感谢。

2 个答案:

答案 0 :(得分:0)

正如JJPA所说,试一试!

您可以采取的一条路线是存储绘制线和预期线的坐标。每一行形成一个向量。您可以使用简单的公式获取Euclidean distance between the lines。距离越近,线条就越准确。

我刚刚写了这个。

var expected =  {from: {x:10, y:10}, to:{x:20, y:20}}
var identical = {from: {x:10, y:10}, to:{x:20, y:20}}
var close =     {from: {x:9,  y:9},  to:{x:21, y:21}}
var lessClose = {from: {x:8,  y:13}, to:{x:25, y:15}}

var distance = function(a, b) {
    return Math.sqrt(Math.pow(a.from.x - b.from.y, 2) + 
                     Math.pow(a.to.x - b.to.y, 2))
}

console.log("identical", distance(expected, identical))
console.log("close", distance(expected, close))
console.log("lessclose", distance(expected, lessClose))

给出

identical  0
close      1.4142135623730951
lessclose  5.830951894845301 

如果你不知道这些线的方向,你可以交换起点和终点并采取最小距离。

答案 1 :(得分:0)

好吧,你可以在javascript中的rgb数组中得到画布的像素: var pixelarray= canvas.getImageData(x, y, width, height).data; 然后pixelarray[0]整数是第一个像素的红色值,pixelarray[3]是第二个像素的红色值,依此类推。 在宽度为100px(第一行中像素索引为0到299)的画布中,pixelarray[299]将是第一行中最后一个像素的蓝色值,pixelarray[300]是第一行中的红色值在第二行。

然后你可以得到代表你要比较的4行的函数,并执行类似

的操作
function isblack(x,y,width,height){
return pixelarray[(y*width+x)*3]==255&&pixelarray[(y*width+x)*3+1]==255&&pixelarray[(y*width+x)*3+2]==255||x<0||x>width||y<0||y>height;
}
function f(x){return a*x+b;}
var lineblackness=0;
for(var x=0;x<picturewidth;x++)if(isblack(x,f(x),picturewidth,pictureheight))lineblackness++;
if(lineblackness==picturewidth)line_is_drawn();

其中fx(x)代表线......

好吧,如果您使用图片或坐标线,可能会更容易:

getcoord(data){
var ar=new array();
for(var i=0;i<data.length/3;i++)if(data[i*3]==255)ar.push(i);
return ar;
}
var comparecoords=getcoord(comparecanvas.getImageData(x, y, width, height).data);
var thisdata=canvas.getImageData(x, y, width, height).data;
var linehits=0;
for(var i=0;i<comparecoords.length;i++){if(thisdata[comparecoords[i]*3]==255)linehits++;}
if(comparecoords.length==linehits)all_coords_are_hit();

这里我只比较了红色值,假设你有黑白图像。

如果你想比较不完全适合的行,你可以用一些额外的ifs改变== 255,例如。

function isblack(x,y,width,height,blurr,treshhold){
    for(var i=-blurr;i<blurr;i++)if(x-i>0&&x+i<width&&pixelarray[(y*width+(x+i))*3]>=treshhold)return true;
    for(var i=-blurr;i<blurr;i++)if(y-i>0&&y+i<height&&pixelarray[((y+i)*width+(x))*3]>=treshhold)return true;
    return false;
    }

此功能也只使用红色,但使用了一个treshhold也让灰色有效。它还接受一个模糊值,用于在像素之前/之后检查x方向,然后再次在y方向检查。

您还可以组合两个循环来检查像素周围的矩形。

return true更改为return i也会让您与要检查的像素保持距离。如果你将两个循环组合成一个i和一个j值,返回sqrt(i ^ 2 + j ^ 2)并对所有检查求和,你可以得到一个指示你的行的准确度。

要实现sqareroot-error,只需比较y距离并总结平方距离i ^ 2就足够了。

请注意,这些程序是建议,可能存在更好的实施,我的代码仍可能包含错误。