throw new IllegalArgumentException(Errors.format(
ErrorKeys.INCOMPATIBLE_COORDINATE_SYSTEM_TYPE));
}
final AxisDirection[] sourceAxis = getAxisDirections(sourceCS);
final AxisDirection[] targetAxis = getAxisDirections(targetCS);
final GeneralMatrix matrix = new GeneralMatrix(sourceAxis, targetAxis);
assert Arrays.equals(sourceAxis, targetAxis) == matrix.isIdentity() : matrix;
/*
* The previous code computed a matrix for swapping axis. Usually, this
* matrix contains only 0 and 1 values with only one "1" value by row.
* For example, the matrix operation for swapping x and y axis is:
*
* [y] [ 0 1 0 ] [x]
* [x] = [ 1 0 0 ] [y]
* [1] [ 0 0 1 ] [1]
*
* Now, take in account units conversions. Each matrix's element (j,i)
* is multiplied by the conversion factor from sourceCS.getUnit(i) to
* targetCS.getUnit(j). This is an element-by-element multiplication,
* not a matrix multiplication. The last column is processed in a special
* way, since it contains the offset values.
*/
final int sourceDim = matrix.getNumCol()-1;
final int targetDim = matrix.getNumRow()-1;
assert sourceDim == sourceCS.getDimension() : sourceCS;
assert targetDim == targetCS.getDimension() : targetCS;
for (int j=0; j<targetDim; j++) {
final Unit<?> targetUnit = targetCS.getAxis(j).getUnit();
for (int i=0; i<sourceDim; i++) {
final double element = matrix.getElement(j,i);
if (element == 0) {
// There is no dependency between source[i] and target[j]
// (i.e. axis are orthogonal).
continue;
}
final Unit<?> sourceUnit = sourceCS.getAxis(i).getUnit();
if (Utilities.equals(sourceUnit, targetUnit)) {
// There is no units conversion to apply
// between source[i] and target[j].
continue;
}
final UnitConverter converter = sourceUnit.getConverterTo(targetUnit);
if (!converter.isLinear()) {
throw new ConversionException(Errors.format(
ErrorKeys.NON_LINEAR_UNIT_CONVERSION_$2, sourceUnit, targetUnit));
}
final double offset = converter.convert(0);
// JSR-275 final double scale = converter.derivative(0);
final double scale = converter.convert(1) - offset;
matrix.setElement(j,i, element*scale);
matrix.setElement(j,sourceDim, matrix.getElement(j,sourceDim) + element*offset);
}
}
return matrix;
}