package nbtool.gui.logviews.images; public class WeightedFit { double sumW; double sumX, sumY, sumXY, sumX2, sumY2; boolean solved; double pLen1, pLen2; // principal lengths, pLen1 >= pLen2 double uPAI, vPAI; // components of unit vector along 1st principal axis double ssError; public WeightedFit() { clear(); } public void clear() { sumW = sumX = sumY = sumXY = sumX2 = sumY2 = 0; solved = false; } public double getArea() { return sumW; } public double getCenterX() { return sumX / sumW; } public double getCenterY() { return sumY / sumW; } public double getFirstPrincipalLength() { solve(); return pLen1; } public double getSecondPrincipalLength() { solve(); return pLen2; } public boolean hasPrincipalAxes() { solve(); return (uPAI != 0 || vPAI != 0); } public double getFirstPrincipalAxisU() { solve(); return uPAI; } public double getFirstPrincipalAxisV() { solve(); return vPAI; } public double getSecondPrincipalAxisU() { solve(); return -vPAI; } public double getSecondPrincipalAxisV() { solve(); return uPAI; } public double getFirstPrincipalAngle() { solve(); return Math.atan2(vPAI, uPAI); } public double getSecondPrincipalAngle() { solve(); return Math.atan2(uPAI, -vPAI); } public double getSumSquaredError() { solve(); return ssError; } public double getRmsError() { return Math.sqrt(getSumSquaredError() / sumW); } public void add(double w, double x, double y) { sumW += w;; sumX += w * x; sumY += w * y; sumX2 += w * x * x; sumY2 += w * y * y; sumXY += w * x * y; solved = false; } public void add(double x, double y) { add(1.0, x, y); } public void sub(double w, double x, double y) { sumW -= w;; sumX -= w * x; sumY -= w * y; sumX2 -= w * x * x; sumY2 -= w * y * y; sumXY -= w * x * y; solved = false; } public void sub(double x, double y) { sub(1.0, x, y); } void solve() { if (solved) return; double a = sumW * sumX2 - sumX * sumX; double b = sumW * sumY2 - sumY * sumY; double c = 2.0 * ((double)sumW * sumXY - (double)sumX * sumY); double d = Math.sqrt(c * c + (a - b) * (a - b)); pLen1 = Math.sqrt(1.5 * (a + b + d)) / sumW; pLen2 = Math.sqrt(1.5 * (a + b - d)) / sumW; if (d == 0.0) uPAI = vPAI = 0.0; else { uPAI = Math.sqrt(((a - b) / d + 1) / 2); vPAI = Math.sqrt((1 - (a - b) / d) / 2); if (c < 0) uPAI = -uPAI; } solved = true; } }