use of org.apache.sis.math.Line in project sis by apache.
the class LinearTransformBuilder method create.
/**
* Creates a linear transform approximation from the source positions to the target positions.
* This method assumes that source positions are precise and that all uncertainty is in the target positions.
*
* @param factory the factory to use for creating the transform, or {@code null} for the default factory.
* The {@link MathTransformFactory#createAffineTransform(Matrix)} method of that factory
* shall return {@link LinearTransform} instances.
* @return the fitted linear transform.
* @throws FactoryException if the transform can not be created,
* for example because the source or target points have not be specified.
*
* @since 0.8
*/
@Override
@SuppressWarnings("serial")
public LinearTransform create(final MathTransformFactory factory) throws FactoryException {
if (transform == null) {
// Protect from changes.
final double[][] sources = this.sources;
final double[][] targets = this.targets;
if (targets == null) {
throw new InvalidGeodeticParameterException(noData());
}
final int sourceDim = (sources != null) ? sources.length : gridSize.length;
final int targetDim = targets.length;
correlation = new double[targetDim];
final MatrixSIS matrix = Matrices.create(targetDim + 1, sourceDim + 1, ExtendedPrecisionMatrix.ZERO);
matrix.setElement(targetDim, sourceDim, 1);
for (int j = 0; j < targetDim; j++) {
final double c;
switch(sourceDim) {
case 1:
{
final int row = j;
final Line line = new Line() {
@Override
public void setEquation(final Number slope, final Number y0) {
super.setEquation(slope, y0);
// Preserve the extended precision (double-double).
matrix.setNumber(row, 0, slope);
matrix.setNumber(row, 1, y0);
}
};
if (sources != null) {
c = line.fit(vector(sources[0]), vector(targets[j]));
} else {
c = line.fit(Vector.createSequence(0, 1, gridSize[0]), Vector.create(targets[j], false));
}
break;
}
case 2:
{
final int row = j;
final Plane plan = new Plane() {
@Override
public void setEquation(final Number sx, final Number sy, final Number z0) {
super.setEquation(sx, sy, z0);
// Preserve the extended precision (double-double).
matrix.setNumber(row, 0, sx);
matrix.setNumber(row, 1, sy);
matrix.setNumber(row, 2, z0);
}
};
if (sources != null) {
c = plan.fit(vector(sources[0]), vector(sources[1]), vector(targets[j]));
} else
try {
c = plan.fit(gridSize[0], gridSize[1], Vector.create(targets[j], false));
} catch (IllegalArgumentException e) {
// This may happen if the z vector still contain some "NaN" values.
throw new InvalidGeodeticParameterException(noData(), e);
}
break;
}
default:
{
throw new FactoryException(Errors.format(Errors.Keys.ExcessiveNumberOfDimensions_1, sourceDim));
}
}
correlation[j] = c;
}
transform = (LinearTransform) nonNull(factory).createAffineTransform(matrix);
}
return transform;
}
Aggregations