使用最小二乘法拟合一条直线的JavaScript代码
其中x在一个input内,并且输入首尾不得有空格,不能有连续的空格(要解决可以自己去掉空字符)。
let xstring = this.x;
let ystring = this.y;
let xs = xstring.split(" ");
let ys = ystring.split(" ");
if(xs.length!=ys.length){
return;
}
let xsum=0,ysum=0;
for(let i = 0 ;i<xs.length;i++){
xsum+=Number(xs[i]);
}
for(let i = 0 ;i<ys.length;i++){
ysum+=Number(ys[i]);
}
let xave=xsum/xs.length,yave=ysum/ys.length;
let num=-xs.length*xave*yave;
let den = -xs.length*xave*xave;
let maxx=xs[0],maxy=ys[0],minx=xs[0],miny=ys[0];
for (let i = 0; i < xs.length; i++) {
if(xs[i]>maxx) maxx = xs[i];
if(xs[i]<minx) minx = xs[i];
if(ys[i]>maxy) maxy = ys[i];
if(ys[i]<miny) miny = ys[i];
num+=xs[i]*ys[i];
den+=xs[i]*xs[i];
}
miny = -miny;
minx = -minx;
if(maxx<0) maxx = -maxx;
if(maxy<0) maxy = -maxy;
if(maxx<minx) maxx = minx;
if(maxy<miny) maxy = miny;
maxx =1.2*maxx;
maxy =1.2*maxy;
let perx = 200/maxx,pery = 200/maxy;
this.a = Number(num /den);
this.b = Number(yave - this.a * xave);
var context = wx.createCanvasContext('firstCanvas')
context.setStrokeStyle("#ff0000")
context.setLineWidth(2);
if(perx >pery) perx = pery;
for (let i = 0; i < xs.length; i++) {
context.moveTo(200+perx*Number(xs[i]),200-perx*Number(ys[i]));
context.arc( 200+perx*Number(xs[i]),200-perx*Number(ys[i]),2,0,2 * Math.PI, true)
}
let xt = -maxx;
context.moveTo(0,200-perx*(this.a*xt+this.b));
xt=-xt;
context.lineTo(400,200-perx*(this.a*xt+this.b));
context.moveTo(0,200);
context.lineTo(400,200);
context.moveTo(200,0);
context.lineTo(200,400);
context.stroke();
context.draw()
这是在wxml内运行的结果,供参考。