package edu.stanford.rsl.conrad.fitting;
import edu.stanford.rsl.conrad.numerics.SimpleMatrix;
import edu.stanford.rsl.conrad.numerics.SimpleOperators;
import edu.stanford.rsl.conrad.numerics.SimpleVector;
public class Quadric extends Surface {
/**
*
*/
private static final long serialVersionUID = 6104784792939859900L;
private int degree =3;
private double [] params;
public Quadric (){
params = new double [degree*degree];
}
/**
* @return the degree
*/
public int getDegree() {
return degree;
}
@Override
public double[] getParametersAsDoubleArray() {
return params;
}
@Override
public void fitToPoints(double[] x, double[] y, double [] z) {
// setup observation vector
SimpleVector observations = new SimpleVector(x.length);
// setup measurement matrix:
SimpleMatrix measurements = new SimpleMatrix(x.length, degree*degree);
for (int i = 0; i < x.length; i++){
measurements.setElementValue(i, 0, Math.pow(x[i], 2));
measurements.setElementValue(i, 1, Math.pow(y[i], 2));
measurements.setElementValue(i, 2, Math.pow(z[i], 2));
measurements.setElementValue(i, 3, x[i]*y[i]);
measurements.setElementValue(i, 4, x[i]*z[i]);
measurements.setElementValue(i, 5, y[i]*z[i]);
measurements.setElementValue(i, 6, x[i]);
measurements.setElementValue(i, 7, y[i]);
measurements.setElementValue(i, 8, z[i]);
observations.setElementValue(i, 1);
}
SimpleMatrix inverseMeasurements = measurements.inverse(SimpleMatrix.InversionType.INVERT_SVD);
SimpleVector parameters = SimpleOperators.multiply(inverseMeasurements, observations);
parameters.copyTo(params);
}
public void fitEllipticParaboloidToPoints(float[] x, float[] y, float [] z) {
// setup observation vector
SimpleVector observations = new SimpleVector(x.length);
// setup measurement matrix:
SimpleMatrix measurements = new SimpleMatrix(x.length, degree*degree);
for (int i = 0; i < x.length; i++){
measurements.setElementValue(i, 0, Math.pow(x[i], 2));
measurements.setElementValue(i, 1, Math.pow(y[i], 2));
measurements.setElementValue(i, 2, Math.pow(z[i], 2));
measurements.setElementValue(i, 3, x[i]*y[i]);
measurements.setElementValue(i, 4, x[i]*z[i]);
measurements.setElementValue(i, 5, y[i]*z[i]);
measurements.setElementValue(i, 6, x[i]);
measurements.setElementValue(i, 7, y[i]);
measurements.setElementValue(i, 8, z[i]);
observations.setElementValue(i, 1);
}
SimpleMatrix inverseMeasurements = measurements.inverse(SimpleMatrix.InversionType.INVERT_SVD);
SimpleVector parameters = SimpleOperators.multiply(inverseMeasurements, observations);
parameters.copyTo(params);
}
@Override
public double evaluate(double x, double y, double z) {
double revan = 0;
revan = x*x*params[0] + y*y*params[1] + z*z*params[2] + x*y*params[3] + x*z*params[4] + y*z*params[5] +x*params[6] * y*params[7] + z*params[8] -1;
return revan;
}
@Override
public String toString() {
String revan = " ";
return revan;
}
@Override
public int getMinimumNumberOfCorrespondences() {
return degree*degree;
}
}