EllipseFitData doEllipseFit() { //Data preparation: normalize data List <double> xData = symmetricNormalize(m_xData); List <double> yData = symmetricNormalize(m_yData); //Bulid n*6 design matrix, n is size of xData or yData List <List <double> > dMtrx = getDesignMatrix(xData, yData); //Bulid 6*6 scatter matrix List <List <double> > sMtrx = getScatterMatrix(dMtrx); //Build 6*6 constraint matrix List <List <double> > cMtrx = getConstraintMatrix(); //Solve eigensystem List <List <double> > eigVV = new List <List <double> >(); bool flag = solveGeneralEigens(sMtrx, cMtrx, eigVV); if (!flag) { throw (new ApplicationException("Eigenvalue calculatin failed")); } EllipseFitData ellip = calcEllipsePara(eigVV); return(ellip); }
/** * @brief calcEllipsePara: calculate ellipse parameter form eigen information * @param eigVV: eigenvalues and eigenvectors * @return ellipse parameter */ EllipseFitData calcEllipsePara(List <List <double> > eigVV) { //Extract eigenvector corresponding to negative eigenvalue int eigIdx = -1; for (int i = 0; i < eigVV.Count; ++i) { double tmpV = eigVV[i][0]; if (tmpV < 1e-6 & !double.IsInfinity(tmpV)) { eigIdx = i; break; } } if (eigIdx < 0) { return(new EllipseFitData()); } //Unnormalize and get coefficients of conic section double tA = eigVV[eigIdx][1]; double tB = eigVV[eigIdx][2]; double tC = eigVV[eigIdx][3]; double tD = eigVV[eigIdx][4]; double tE = eigVV[eigIdx][5]; double tF = eigVV[eigIdx][6]; double mx = getMeanValue(m_xData); double my = getMeanValue(m_yData); double sx = getScaleValue(m_xData); double sy = getScaleValue(m_yData); EllipseFitData ellip = new EllipseFitData(); ellip.a = tA * sy * sy; ellip.b = tB * sx * sy; ellip.c = tC * sx * sx; ellip.d = -2 * tA * sy * sy * mx - tB * sx * sy * my + tD * sx * sy * sy; ellip.e = -tB * sx * sy * mx - 2 * tC * sx * sx * my + tE * sx * sx * sy; ellip.f = tA * sy * sy * mx * mx + tB * sx * sy * mx * my + tC * sx * sx * my * my - tD * sx * sy * sy * mx - tE * sx * sx * sy * my + tF * sx * sx * sy * sy; ellip.algeFlag = true; ellip.alge2geom(); return(ellip); }