CPD Results

The following document contains the results of PMD's CPD 7.14.0.

Duplications

File Line
com/irurueta/geometry/Conic.java 315
com/irurueta/geometry/Ellipse.java 662
final Point2D point5) throws CoincidentPointsException {

        // normalize points to increase accuracy
        point1.normalize();
        point2.normalize();
        point3.normalize();
        point4.normalize();
        point5.normalize();

        try {
            // each point belonging to a conic follows equation:
            // p' * C * p = 0 ==>
            // x^2 + y^2 + w^2 + 2*x*y + 2*x*w + 2*y*w = 0
            final var m = new Matrix(5, 6);
            var x = point1.getHomX();
            var y = point1.getHomY();
            var w = point1.getHomW();
            m.setElementAt(0, 0, x * x);
            m.setElementAt(0, 1, 2.0 * x * y);
            m.setElementAt(0, 2, y * y);
            m.setElementAt(0, 3, 2.0 * x * w);
            m.setElementAt(0, 4, 2.0 * y * w);
            m.setElementAt(0, 5, w * w);
            x = point2.getHomX();
            y = point2.getHomY();
            w = point2.getHomW();
            m.setElementAt(1, 0, x * x);
            m.setElementAt(1, 1, 2.0 * x * y);
            m.setElementAt(1, 2, y * y);
            m.setElementAt(1, 3, 2.0 * x * w);
            m.setElementAt(1, 4, 2.0 * y * w);
            m.setElementAt(1, 5, w * w);
            x = point3.getHomX();
            y = point3.getHomY();
            w = point3.getHomW();
            m.setElementAt(2, 0, x * x);
            m.setElementAt(2, 1, 2.0 * x * y);
            m.setElementAt(2, 2, y * y);
            m.setElementAt(2, 3, 2.0 * x * w);
            m.setElementAt(2, 4, 2.0 * y * w);
            m.setElementAt(2, 5, w * w);
            x = point4.getHomX();
            y = point4.getHomY();
            w = point4.getHomW();
            m.setElementAt(3, 0, x * x);
            m.setElementAt(3, 1, 2.0 * x * y);
            m.setElementAt(3, 2, y * y);
            m.setElementAt(3, 3, 2.0 * x * w);
            m.setElementAt(3, 4, 2.0 * y * w);
            m.setElementAt(3, 5, w * w);
            x = point5.getHomX();
            y = point5.getHomY();
            w = point5.getHomW();
            m.setElementAt(4, 0, x * x);
            m.setElementAt(4, 1, 2.0 * x * y);
            m.setElementAt(4, 2, y * y);
            m.setElementAt(4, 3, 2.0 * x * w);
            m.setElementAt(4, 4, 2.0 * y * w);
            m.setElementAt(4, 5, w * w);

            // normalize each row to increase accuracy
            final var row = new double[6];
            double rowNorm;

            for (var j = 0; j < 5; j++) {
                m.getSubmatrixAsArray(j, 0, j, 5, row);
                rowNorm = com.irurueta.algebra.Utils.normF(row);
                for (var i = 0; i < 6; i++) {
                    m.setElementAt(j, i, m.getElementAt(j, i) / rowNorm);
                }
            }

            final var decomposer = new SingularValueDecomposer(m);
            decomposer.decompose();

            if (decomposer.getRank() < 5) {
                throw new CoincidentPointsException();
File Line
com/irurueta/geometry/estimators/PinholeCameraEstimator.java 324
com/irurueta/geometry/estimators/PinholeCameraRobustEstimator.java 397
}

    /**
     * Indicates whether skewness value is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if skewness value is suggested, false otherwise.
     */
    public boolean isSuggestSkewnessValueEnabled() {
        return suggestSkewnessValueEnabled;
    }

    /**
     * Specifies whether skewness value is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestSkewnessValueEnabled true if skewness value is suggested,
     *                                    false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestSkewnessValueEnabled(final boolean suggestSkewnessValueEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestSkewnessValueEnabled = suggestSkewnessValueEnabled;
    }

    /**
     * Gets suggested skewness value to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested skewness value.
     */
    public double getSuggestedSkewnessValue() {
        return suggestedSkewnessValue;
    }

    /**
     * Sets suggested skewness value to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedSkewnessValue suggested skewness value.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedSkewnessValue(final double suggestedSkewnessValue) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedSkewnessValue = suggestedSkewnessValue;
    }

    /**
     * Indicates whether horizontal focal length is suggested or not. When
     * enabled, the estimator will attempt to enforce suggested value in an
     * iterative manner starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if horizontal focal length is suggested, false otherwise.
     */
    public boolean isSuggestHorizontalFocalLengthEnabled() {
        return suggestHorizontalFocalLengthEnabled;
    }

    /**
     * Specifies whether horizontal focal length is suggested or not. When
     * enabled, the estimator will attempt to enforce suggested value in an
     * iterative manner starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestHorizontalFocalLengthEnabled true if horizontal focal
     *                                            length is suggested, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestHorizontalFocalLengthEnabled(final boolean suggestHorizontalFocalLengthEnabled)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestHorizontalFocalLengthEnabled =
                suggestHorizontalFocalLengthEnabled;
    }

    /**
     * Gets suggested horizontal focal length value to be reached when
     * suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested horizontal focal length value.
     */
    public double getSuggestedHorizontalFocalLengthValue() {
        return suggestedHorizontalFocalLengthValue;
    }

    /**
     * Sets suggested horizontal focal length value to be reached when
     * suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedHorizontalFocalLengthValue suggested horizontal focal
     *                                            length value.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedHorizontalFocalLengthValue(final double suggestedHorizontalFocalLengthValue)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedHorizontalFocalLengthValue = suggestedHorizontalFocalLengthValue;
    }

    /**
     * Indicates whether vertical focal length is suggested or not. When
     * enabled, the estimator will attempt to enforce suggested value in an
     * iterative manner starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if vertical focal length is suggested, false otherwise.
     */
    public boolean isSuggestVerticalFocalLengthEnabled() {
        return suggestVerticalFocalLengthEnabled;
    }

    /**
     * Specifies whether vertical focal length is suggested or not. When
     * enabled, the estimator will attempt to enforce suggested value in an
     * iterative manner starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestVerticalFocalLengthEnabled true if vertical focal length is
     *                                          suggested, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestVerticalFocalLengthEnabled(final boolean suggestVerticalFocalLengthEnabled)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestVerticalFocalLengthEnabled = suggestVerticalFocalLengthEnabled;
    }

    /**
     * Gets suggested vertical focal length value to be reached when suggestion
     * is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested vertical focal length.
     */
    public double getSuggestedVerticalFocalLengthValue() {
        return suggestedVerticalFocalLengthValue;
    }

    /**
     * Sets suggested vertical focal length value to be reached when suggestion
     * is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedVerticalFocalLengthValue suggested vertical focal length.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedVerticalFocalLengthValue(final double suggestedVerticalFocalLengthValue)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedVerticalFocalLengthValue = suggestedVerticalFocalLengthValue;
    }

    /**
     * Indicates whether aspect ratio is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if aspect ratio is suggested, false otherwise.
     */
    public boolean isSuggestAspectRatioEnabled() {
        return suggestAspectRatioEnabled;
    }

    /**
     * Specifies whether aspect ratio is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestAspectRatioEnabled true if aspect ratio is suggested, false
     *                                  otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestAspectRatioEnabled(final boolean suggestAspectRatioEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestAspectRatioEnabled = suggestAspectRatioEnabled;
    }

    /**
     * Gets suggested aspect ratio value to be reached when suggestion is
     * enabled. Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested aspect ratio value.
     */
    public double getSuggestedAspectRatioValue() {
        return suggestedAspectRatioValue;
    }

    /**
     * Sets suggested aspect ratio value to be reached when suggestion is
     * enabled. Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedAspectRatioValue suggested aspect ratio value.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedAspectRatioValue(final double suggestedAspectRatioValue) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedAspectRatioValue = suggestedAspectRatioValue;
    }

    /**
     * Indicates whether principal point is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if principal point is suggested, false otherwise.
     */
    public boolean isSuggestPrincipalPointEnabled() {
        return suggestPrincipalPointEnabled;
    }

    /**
     * Specifies whether principal point is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestPrincipalPointEnabled true if principal point is suggested,
     *                                     false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestPrincipalPointEnabled(final boolean suggestPrincipalPointEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestPrincipalPointEnabled = suggestPrincipalPointEnabled;
        if (suggestPrincipalPointEnabled && suggestedPrincipalPointValue == null) {
            suggestedPrincipalPointValue = new InhomogeneousPoint2D();
        }
    }

    /**
     * Gets suggested principal point value to be reached when suggestion is
     * enabled. Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested principal point value to be reached when suggestion is
     * enabled.
     */
    public InhomogeneousPoint2D getSuggestedPrincipalPointValue() {
        return suggestedPrincipalPointValue;
    }

    /**
     * Sets suggested principal point value to be reached when suggestion is
     * enabled. Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedPrincipalPointValue suggested principal point value to be
     *                                     reached when suggestion is enabled.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedPrincipalPointValue(final InhomogeneousPoint2D suggestedPrincipalPointValue)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedPrincipalPointValue = suggestedPrincipalPointValue;
    }

    /**
     * Indicates whether camera rotation is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if camera rotation is suggested, false otherwise.
     */
    public boolean isSuggestRotationEnabled() {
        return suggestRotationEnabled;
    }

    /**
     * Specifies whether camera rotation is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestRotationEnabled true if camera rotation is suggested, false
     *                               otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestRotationEnabled(final boolean suggestRotationEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestRotationEnabled = suggestRotationEnabled;
        if (suggestRotationEnabled && suggestedRotationValue == null) {
            suggestedRotationValue = new Quaternion();
        }
    }

    /**
     * Gets suggested rotation to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested rotation to be reached when suggestion is enabled.
     */
    public Quaternion getSuggestedRotationValue() {
        return suggestedRotationValue;
    }

    /**
     * Sets suggested rotation to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedRotationValue suggested rotation to be reached when
     *                               suggestion is enabled.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedRotationValue(final Quaternion suggestedRotationValue) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedRotationValue = suggestedRotationValue;
    }

    /**
     * Indicates whether camera center is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if camera center is suggested, false otherwise.
     */
    public boolean isSuggestCenterEnabled() {
        return suggestCenterEnabled;
    }

    /**
     * Specifies whether camera center is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestCenterEnabled true if camera is suggested, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestCenterEnabled(final boolean suggestCenterEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestCenterEnabled = suggestCenterEnabled;
        if (suggestCenterEnabled && suggestedCenterValue == null) {
            suggestedCenterValue = new InhomogeneousPoint3D();
        }
    }

    /**
     * Gets suggested center to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested center to be reached when suggestion is enabled.
     */
    public InhomogeneousPoint3D getSuggestedCenterValue() {
        return suggestedCenterValue;
    }

    /**
     * Sets suggested center to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedCenterValue suggested center to be reached when
     *                             suggestion is enabled.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedCenterValue(final InhomogeneousPoint3D suggestedCenterValue) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedCenterValue = suggestedCenterValue;
    }

    /**
     * Gets minimum suggestion weight. This weight is used to slowly draw
     * original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @return minimum suggestion weight.
     */
    public double getMinSuggestionWeight() {
File Line
com/irurueta/geometry/estimators/PinholeCameraEstimator.java 324
com/irurueta/geometry/refiners/PinholeCameraRefiner.java 336
}

    /**
     * Indicates whether skewness value is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if skewness value is suggested, false otherwise.
     */
    public boolean isSuggestSkewnessValueEnabled() {
        return suggestSkewnessValueEnabled;
    }

    /**
     * Specifies whether skewness value is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestSkewnessValueEnabled true if skewness value is suggested,
     *                                    false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestSkewnessValueEnabled(final boolean suggestSkewnessValueEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestSkewnessValueEnabled = suggestSkewnessValueEnabled;
    }

    /**
     * Gets suggested skewness value to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested skewness value.
     */
    public double getSuggestedSkewnessValue() {
        return suggestedSkewnessValue;
    }

    /**
     * Sets suggested skewness value to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedSkewnessValue suggested skewness value.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedSkewnessValue(final double suggestedSkewnessValue) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedSkewnessValue = suggestedSkewnessValue;
    }

    /**
     * Indicates whether horizontal focal length is suggested or not. When
     * enabled, the estimator will attempt to enforce suggested value in an
     * iterative manner starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if horizontal focal length is suggested, false otherwise.
     */
    public boolean isSuggestHorizontalFocalLengthEnabled() {
        return suggestHorizontalFocalLengthEnabled;
    }

    /**
     * Specifies whether horizontal focal length is suggested or not. When
     * enabled, the estimator will attempt to enforce suggested value in an
     * iterative manner starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestHorizontalFocalLengthEnabled true if horizontal focal
     *                                            length is suggested, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestHorizontalFocalLengthEnabled(final boolean suggestHorizontalFocalLengthEnabled)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestHorizontalFocalLengthEnabled =
                suggestHorizontalFocalLengthEnabled;
    }

    /**
     * Gets suggested horizontal focal length value to be reached when
     * suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested horizontal focal length value.
     */
    public double getSuggestedHorizontalFocalLengthValue() {
        return suggestedHorizontalFocalLengthValue;
    }

    /**
     * Sets suggested horizontal focal length value to be reached when
     * suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedHorizontalFocalLengthValue suggested horizontal focal
     *                                            length value.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedHorizontalFocalLengthValue(final double suggestedHorizontalFocalLengthValue)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedHorizontalFocalLengthValue = suggestedHorizontalFocalLengthValue;
    }

    /**
     * Indicates whether vertical focal length is suggested or not. When
     * enabled, the estimator will attempt to enforce suggested value in an
     * iterative manner starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if vertical focal length is suggested, false otherwise.
     */
    public boolean isSuggestVerticalFocalLengthEnabled() {
        return suggestVerticalFocalLengthEnabled;
    }

    /**
     * Specifies whether vertical focal length is suggested or not. When
     * enabled, the estimator will attempt to enforce suggested value in an
     * iterative manner starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestVerticalFocalLengthEnabled true if vertical focal length is
     *                                          suggested, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestVerticalFocalLengthEnabled(final boolean suggestVerticalFocalLengthEnabled)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestVerticalFocalLengthEnabled = suggestVerticalFocalLengthEnabled;
    }

    /**
     * Gets suggested vertical focal length value to be reached when suggestion
     * is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested vertical focal length.
     */
    public double getSuggestedVerticalFocalLengthValue() {
        return suggestedVerticalFocalLengthValue;
    }

    /**
     * Sets suggested vertical focal length value to be reached when suggestion
     * is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedVerticalFocalLengthValue suggested vertical focal length.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedVerticalFocalLengthValue(final double suggestedVerticalFocalLengthValue)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedVerticalFocalLengthValue = suggestedVerticalFocalLengthValue;
    }

    /**
     * Indicates whether aspect ratio is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if aspect ratio is suggested, false otherwise.
     */
    public boolean isSuggestAspectRatioEnabled() {
        return suggestAspectRatioEnabled;
    }

    /**
     * Specifies whether aspect ratio is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestAspectRatioEnabled true if aspect ratio is suggested, false
     *                                  otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestAspectRatioEnabled(final boolean suggestAspectRatioEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestAspectRatioEnabled = suggestAspectRatioEnabled;
    }

    /**
     * Gets suggested aspect ratio value to be reached when suggestion is
     * enabled. Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested aspect ratio value.
     */
    public double getSuggestedAspectRatioValue() {
        return suggestedAspectRatioValue;
    }

    /**
     * Sets suggested aspect ratio value to be reached when suggestion is
     * enabled. Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedAspectRatioValue suggested aspect ratio value.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedAspectRatioValue(final double suggestedAspectRatioValue) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedAspectRatioValue = suggestedAspectRatioValue;
    }

    /**
     * Indicates whether principal point is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if principal point is suggested, false otherwise.
     */
    public boolean isSuggestPrincipalPointEnabled() {
        return suggestPrincipalPointEnabled;
    }

    /**
     * Specifies whether principal point is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestPrincipalPointEnabled true if principal point is suggested,
     *                                     false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestPrincipalPointEnabled(final boolean suggestPrincipalPointEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestPrincipalPointEnabled = suggestPrincipalPointEnabled;
        if (suggestPrincipalPointEnabled && suggestedPrincipalPointValue == null) {
            suggestedPrincipalPointValue = new InhomogeneousPoint2D();
        }
    }

    /**
     * Gets suggested principal point value to be reached when suggestion is
     * enabled. Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested principal point value to be reached when suggestion is
     * enabled.
     */
    public InhomogeneousPoint2D getSuggestedPrincipalPointValue() {
        return suggestedPrincipalPointValue;
    }

    /**
     * Sets suggested principal point value to be reached when suggestion is
     * enabled. Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedPrincipalPointValue suggested principal point value to be
     *                                     reached when suggestion is enabled.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedPrincipalPointValue(final InhomogeneousPoint2D suggestedPrincipalPointValue)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedPrincipalPointValue = suggestedPrincipalPointValue;
    }

    /**
     * Indicates whether camera rotation is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if camera rotation is suggested, false otherwise.
     */
    public boolean isSuggestRotationEnabled() {
        return suggestRotationEnabled;
    }

    /**
     * Specifies whether camera rotation is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestRotationEnabled true if camera rotation is suggested, false
     *                               otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestRotationEnabled(final boolean suggestRotationEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestRotationEnabled = suggestRotationEnabled;
        if (suggestRotationEnabled && suggestedRotationValue == null) {
            suggestedRotationValue = new Quaternion();
        }
    }

    /**
     * Gets suggested rotation to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested rotation to be reached when suggestion is enabled.
     */
    public Quaternion getSuggestedRotationValue() {
        return suggestedRotationValue;
    }

    /**
     * Sets suggested rotation to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedRotationValue suggested rotation to be reached when
     *                               suggestion is enabled.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedRotationValue(final Quaternion suggestedRotationValue) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedRotationValue = suggestedRotationValue;
    }

    /**
     * Indicates whether camera center is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @return true if camera center is suggested, false otherwise.
     */
    public boolean isSuggestCenterEnabled() {
        return suggestCenterEnabled;
    }

    /**
     * Specifies whether camera center is suggested or not. When enabled, the
     * estimator will attempt to enforce suggested value in an iterative manner
     * starting from an initially estimated camera.
     * Even when suggestion is enabled, the iterative algorithm might not reach
     * suggested value if the initial value largely differs from the suggested
     * value.
     *
     * @param suggestCenterEnabled true if camera is suggested, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestCenterEnabled(final boolean suggestCenterEnabled) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestCenterEnabled = suggestCenterEnabled;
        if (suggestCenterEnabled && suggestedCenterValue == null) {
            suggestedCenterValue = new InhomogeneousPoint3D();
        }
    }

    /**
     * Gets suggested center to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @return suggested center to be reached when suggestion is enabled.
     */
    public InhomogeneousPoint3D getSuggestedCenterValue() {
        return suggestedCenterValue;
    }

    /**
     * Sets suggested center to be reached when suggestion is enabled.
     * Suggested value should be close to the initially estimated value
     * otherwise the iterative refinement might not converge to provided value.
     *
     * @param suggestedCenterValue suggested center to be reached when
     *                             suggestion is enabled.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestedCenterValue(final InhomogeneousPoint3D suggestedCenterValue) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestedCenterValue = suggestedCenterValue;
    }
File Line
com/irurueta/geometry/ProjectiveTransformation2D.java 769
com/irurueta/geometry/ProjectiveTransformation3D.java 802
public void setAffineParameters(final AffineParameters2D parameters) throws AlgebraException {
        normalize();
        final var value = t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1);
        final var decomposer = new RQDecomposer(t.getSubmatrix(0, 0,
                INHOM_COORDS - 1, INHOM_COORDS - 1));
        decomposer.decompose();
        final var params = parameters.asMatrix();
        final var rotation = decomposer.getQ();

        // params is equivalent to A because it
        // has been multiplied by rotation
        params.multiply(rotation);
        // normalize
        params.multiplyByScalar(value);
        t.setSubmatrix(0, 0, INHOM_COORDS - 1, INHOM_COORDS - 1,
                params);
        normalized = false;
    }

    /**
     * Returns the projective parameters associated to this instance.
     * These parameters are the located in the last row of the internal
     * transformation matrix.
     * For affine, metric or Euclidean transformations this last row is always
     * [0, 0, 1] (taking into account that transformation matrix is defined
     * up to scale).
     *
     * @return Projective parameters returned as the array containing the values
     * of the last row of the internal transformation matrix.
     */
    public double[] getProjectiveParameters() {
        // return last row of matrix t
        return t.getSubmatrixAsArray(HOM_COORDS - 1, 0, HOM_COORDS - 1,
                HOM_COORDS - 1, true);
    }

    /**
     * Sets the projective parameters associated to this instance.
     * These parameters will be set in the last row of the internal
     * transformation matrix.
     * For affine, matrix or Euclidean transformations parameters are always
     * [0, 0, 1] (taking into account that transformation matrix is defined up
     * to scale).
     *
     * @param params projective parameters to be set. It must be an array of
     *               length 3.
     * @throws IllegalArgumentException raised if provided array does not have
     *                                  length 3.
     */
    public final void setProjectiveParameters(final double[] params) {
        if (params.length != HOM_COORDS) {
            throw new IllegalArgumentException();
        }

        t.setSubmatrix(HOM_COORDS - 1, 0, HOM_COORDS - 1,
                HOM_COORDS - 1, params);
        normalized = false;
    }

    /**
     * Returns 2D translation assigned to this transformation as an array
     * expressed in inhomogeneous coordinates.
     * Note: Updating the values of the returned array will not update the
     * translation of this instance. To do so, translation needs to be set
     * again.
     *
     * @return 2D translation array.
     */
    public double[] getTranslation() {
        normalize();
        final var translation = t.getSubmatrixAsArray(0, HOM_COORDS - 1,
                INHOM_COORDS - 1, HOM_COORDS - 1);
        final var value = t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1);
        ArrayUtils.multiplyByScalar(translation, 1.0 / value, translation);
        return translation;
    }

    /**
     * Obtains 2D translation assigned to this transformation and stores result
     * into provided array.
     * Note: updating the values of the returned array will not update the
     * translation of this instance. To do so, translation needs to be set.
     *
     * @param out array where translation values will be stored.
     * @throws WrongSizeException if provided array does not have length 2.
     */
    public void getTranslation(final double[] out) throws WrongSizeException {
        t.getSubmatrixAsArray(0, HOM_COORDS - 1,
                INHOM_COORDS - 1, HOM_COORDS - 1, out);
        final var value = t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1);
        ArrayUtils.multiplyByScalar(out, 1.0 / value, out);
    }

    /**
     * Sets 2D translation assigned to this transformation as an array expressed
     * in inhomogeneous coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void setTranslation(final double[] translation) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }

        final var value = t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1);
        final var translation2 = ArrayUtils.multiplyByScalarAndReturnNew(translation, value);
        t.setSubmatrix(0, HOM_COORDS - 1, translation2.length - 1,
                HOM_COORDS - 1, translation2);
        normalized = false;
    }

    /**
     * Adds provided translation to current translation on this transformation.
     * Provided translation must be expressed as an array of inhomogeneous
     * coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void addTranslation(final double[] translation) {
        final var currentTranslation = getTranslation();
        ArrayUtils.sum(currentTranslation, translation, currentTranslation);
        setTranslation(currentTranslation);
    }

    /**
     * Returns current x coordinate translation assigned to this transformation.
     *
     * @return X coordinate translation.
     */
    public double getTranslationX() {
        normalize();
        return t.getElementAt(0, HOM_COORDS - 1)
                / t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1);
    }

    /**
     * Sets x coordinate translation to be made by this transformation.
     *
     * @param translationX X coordinate translation to be set.
     */
    public void setTranslationX(final double translationX) {
        t.setElementAt(0, HOM_COORDS - 1,
                translationX * t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1));
        normalized = false;
    }

    /**
     * Returns current y coordinate translation assigned to this transformation.
     *
     * @return Y coordinate translation.
     */
    public double getTranslationY() {
        normalize();
        return t.getElementAt(1, HOM_COORDS - 1)
                / t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1);
    }

    /**
     * Sets y coordinate translation to be made by this transformation.
     *
     * @param translationY Y coordinate translation to be set.
     */
    public void setTranslationY(final double translationY) {
        t.setElementAt(1, HOM_COORDS - 1,
                translationY * t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1));
        normalized = false;
    }

    /**
     * Sets x, y coordinates of translation to be made by this transformation.
     *
     * @param translationX translation x coordinate to be set.
     * @param translationY translation y coordinate to be set.
     */
    public void setTranslation(final double translationX, final double translationY) {
File Line
com/irurueta/geometry/AffineTransformation3D.java 548
com/irurueta/geometry/EuclideanTransformation3D.java 181
}

    /**
     * Returns 3D translation assigned to this transformation as an array
     * expressed in inhomogeneous coordinates.
     *
     * @return 3D translation array.
     */
    public double[] getTranslation() {
        return translation;
    }

    /**
     * Sets 3D translation assigned to this transformation as an array expressed
     * in inhomogeneous coordinates.
     *
     * @param translation 3D translation array.
     * @throws IllegalArgumentException Raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void setTranslation(final double[] translation) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }

        this.translation = translation;
    }

    /**
     * Adds provided translation to current translation on this transformation.
     * Provided translation must be expressed as an array of inhomogeneous
     * coordinates.
     *
     * @param translation 3D translation array.
     * @throws IllegalArgumentException Raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void addTranslation(final double[] translation) {
        ArrayUtils.sum(this.translation, translation, this.translation);
    }

    /**
     * Returns current x coordinate translation assigned to this transformation.
     *
     * @return X coordinate translation.
     */
    public double getTranslationX() {
        return translation[0];
    }

    /**
     * Sets x coordinate translation to be made by this transformation.
     *
     * @param translationX X coordinate translation to be set.
     */
    public void setTranslationX(final double translationX) {
        translation[0] = translationX;
    }

    /**
     * Returns current y coordinate translation assigned to this transformation.
     *
     * @return Y coordinate translation.
     */
    public double getTranslationY() {
        return translation[1];
    }

    /**
     * Sets y coordinate translation to be made by this transformation.
     *
     * @param translationY Y coordinate translation to be set.
     */
    public void setTranslationY(final double translationY) {
        translation[1] = translationY;
    }

    /**
     * Returns current z coordinate translation assigned to this transformation.
     *
     * @return Z coordinate translation.
     */
    public double getTranslationZ() {
        return translation[2];
    }

    /**
     * Sets z coordinate translation to be made by this transformation.
     *
     * @param translationZ z coordinate translation to be set.
     */
    public void setTranslationZ(final double translationZ) {
        translation[2] = translationZ;
    }

    /**
     * Sets x, y, z coordinates of translation to be made by this
     * transformation.
     *
     * @param translationX translation x coordinate to be set.
     * @param translationY translation y coordinate to be set.
     * @param translationZ translation z coordinate to be set.
     */
    public void setTranslation(final double translationX, final double translationY, final double translationZ) {
        translation[0] = translationX;
        translation[1] = translationY;
        translation[2] = translationZ;
    }

    /**
     * Sets x, y, z coordinates of translation to be made by this
     * transformation.
     *
     * @param translation translation to be set.
     */
    public void setTranslation(final Point3D translation) {
        setTranslation(translation.getInhomX(), translation.getInhomY(), translation.getInhomZ());
    }

    /**
     * Gets x, y, z coordinates of translation to be made by this transformation
     * as a new point.
     *
     * @return a new point containing translation coordinates.
     */
    public Point3D getTranslationPoint() {
        final var out = Point3D.create();
        getTranslationPoint(out);
        return out;
    }

    /**
     * Gets x, y, z coordinates of translation to be made by this transformation
     * and stores them into provided point.
     *
     * @param out point where translation coordinates will be stored.
     */
    public void getTranslationPoint(final Point3D out) {
        out.setInhomogeneousCoordinates(translation[0], translation[1], translation[2]);
    }

    /**
     * Adds provided x coordinate to current translation assigned to this
     * transformation.
     *
     * @param translationX X coordinate to be added to current translation.
     */
    public void addTranslationX(final double translationX) {
        translation[0] += translationX;
    }

    /**
     * Adds provided y coordinate to current translation assigned to this
     * transformation.
     *
     * @param translationY Y coordinate to be added to current translation.
     */
    public void addTranslationY(final double translationY) {
        translation[1] += translationY;
    }

    /**
     * Adds provided z coordinate to current translation assigned to this
     * transformation.
     *
     * @param translationZ Z coordinate to be added to current translation.
     */
    public void addTranslationZ(final double translationZ) {
        translation[2] += translationZ;
    }

    /**
     * Adds provided coordinates to current translation assigned to this
     * transformation.
     *
     * @param translationX x coordinate to be added to current translation.
     * @param translationY y coordinate to be added to current translation.
     * @param translationZ z coordinate to be added to current translation.
     */
    public void addTranslation(final double translationX, final double translationY, final double translationZ) {
        translation[0] += translationX;
        translation[1] += translationY;
        translation[2] += translationZ;
    }

    /**
     * Adds provided coordinates to current translation assigned to this
     * transformation.
     *
     * @param translation x, y, z coordinates to be added to current
     *                    translation.
     */
    public void addTranslation(final Point3D translation) {
        addTranslation(translation.getInhomX(), translation.getInhomY(), translation.getInhomZ());
    }

    /**
     * Represents this transformation as a 4x4 matrix.
     * a point can be transformed as T * p, where T is the transformation matrix
     * and p is a point expressed as an homogeneous vector.
     *
     * @return This transformation in matrix form.
     */
    @Override
    public Matrix asMatrix() {
        Matrix m = null;
        try {
            m = new Matrix(HOM_COORDS, HOM_COORDS);
            asMatrix(m);
        } catch (final WrongSizeException ignore) {
            // never happens
        }
        return m;
    }

    /**
     * Represents this transformation as a 4x4 matrix and stores the result in
     * provided instance.
     *
     * @param m instance where transformation matrix will be stored.
     * @throws IllegalArgumentException raised if provided instance is not a 4x4
     *                                  matrix.
     */
    @Override
    public void asMatrix(final Matrix m) {
        if (m.getRows() != HOM_COORDS || m.getColumns() != HOM_COORDS) {
            throw new IllegalArgumentException();
        }

        // set rotation
        m.setSubmatrix(0, 0, 2, 2, a);
File Line
com/irurueta/geometry/Triangle2D.java 802
com/irurueta/geometry/Triangle3D.java 872
final var closest3 = line3.getClosestPoint(point, threshold);
        // to increase accuracy
        closest3.normalize();

        // check if points lie within sides of triangle
        final var between1 = closest1.isBetween(vertex1, vertex2);
        final var between2 = closest2.isBetween(vertex1, vertex3);
        final var between3 = closest3.isBetween(vertex2, vertex3);

        final var distClosest1 = closest1.distanceTo(point);
        final var distClosest2 = closest2.distanceTo(point);
        final var distClosest3 = closest3.distanceTo(point);

        final var distVertex1 = vertex1.distanceTo(point);
        final var distVertex2 = vertex2.distanceTo(point);
        final var distVertex3 = vertex3.distanceTo(point);

        if (between1 && !between2 && !between3) {
            // choose closest1 or opposite vertex (vertex3)
            if (distClosest1 < distVertex3) {
                result.setCoordinates(closest1);
            } else {
                result.setCoordinates(vertex3);
            }
        } else if (!between1 && between2 && !between3) {
            // choose closest2 or opposite vertex (vertex2)
            if (distClosest2 < distVertex2) {
                result.setCoordinates(closest2);
            } else {
                result.setCoordinates(vertex2);
            }
        } else if (!between1 && !between2 && between3) {
            // choose closest3 or opposite vertex (vertex1)
            if (distClosest3 < distVertex1) {
                result.setCoordinates(closest3);
            } else {
                result.setCoordinates(vertex1);
            }
        } else if (between1 && between2 && !between3) {
            // determine if closest1 or closest2
            if (distClosest1 < distClosest2) {
                result.setCoordinates(closest1);
            } else {
                result.setCoordinates(closest2);
            }
        } else if (!between1 && between2) {
            // and between3

            // determine if closest2 or closest3
            if (distClosest2 < distClosest3) {
                result.setCoordinates(closest2);
            } else {
                result.setCoordinates(closest3);
            }
        } else if (between1 && !between2) {
            // and between3

            //determine if closest1 or closest3
            if (distClosest1 < distClosest3) {
                result.setCoordinates(closest1);
            } else {
                result.setCoordinates(closest3);
            }
        } else if (between1) {
            // and between2 and between3

            //determine if closest1, closest2 or closest3
            if (distClosest1 < distClosest2 && distClosest1 < distClosest3) {
                // pick closest1
                result.setCoordinates(closest1);
            } else if (distClosest2 < distClosest1 &&
                    distClosest2 < distClosest3) {
                // pick closest2
                result.setCoordinates(closest2);
            } else {
                // pick closest3
                result.setCoordinates(closest3);
            }
        } else {
            // all closest points are outside vertex limits, so we pick the
            // closest vertex

            if (distVertex1 < distVertex2 && distVertex1 < distVertex3) {
                // pick vertex1
                result.setCoordinates(vertex1);
            } else if (distVertex2 < distVertex1 && distVertex2 < distVertex3) {
                // pick vertex2
                result.setCoordinates(vertex2);
            } else {
                // pick vertex3
                result.setCoordinates(vertex3);
            }
        }
    }

    /**
     * Returns boolean indicating if provided point is locus of this triangle
     * (i.e. lies within this triangle boundaries) up to a certain threshold.
     *
     * @param point     Point to be checked.
     * @param threshold Threshold to determine if point is locus or not. This
     *                  should usually be a small value.
     * @return True if provided point is locus, false otherwise.
     * @throws IllegalArgumentException Raised if provided threshold is negative.
     */
    public boolean isLocus(final Point2D point, final double threshold) {
File Line
com/irurueta/geometry/AffineTransformation2D.java 518
com/irurueta/geometry/EuclideanTransformation2D.java 177
}

    /**
     * Returns 2D translation assigned to this transformation as an array
     * expressed in inhomogeneous coordinates.
     *
     * @return 2D translation array.
     */
    public double[] getTranslation() {
        return translation;
    }

    /**
     * Sets 2D translation assigned to this transformation as an array expressed
     * in inhomogeneous coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void setTranslation(final double[] translation) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }

        this.translation = translation;
    }

    /**
     * Adds provided translation to current translation on this transformation.
     * Provided translation must be expressed as an array of inhomogeneous
     * coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void addTranslation(final double[] translation) {
        ArrayUtils.sum(this.translation, translation, this.translation);
    }

    /**
     * Returns current x coordinate translation assigned to this transformation.
     *
     * @return X coordinate translation.
     */
    public double getTranslationX() {
        return translation[0];
    }

    /**
     * Sets x coordinate translation to be made by this transformation.
     *
     * @param translationX X coordinate translation to be set.
     */
    public void setTranslationX(final double translationX) {
        translation[0] = translationX;
    }

    /**
     * Returns current y coordinate translation assigned to this transformation.
     *
     * @return Y coordinate translation.
     */
    public double getTranslationY() {
        return translation[1];
    }

    /**
     * Sets y coordinate translation to be made by this transformation.
     *
     * @param translationY Y coordinate translation to be set.
     */
    public void setTranslationY(final double translationY) {
        translation[1] = translationY;
    }

    /**
     * Sets x, y coordinates of translation to be made by this transformation.
     *
     * @param translationX translation x coordinate to be set.
     * @param translationY translation y coordinate to be set.
     */
    public void setTranslation(final double translationX, final double translationY) {
        translation[0] = translationX;
        translation[1] = translationY;
    }

    /**
     * Sets x, y, coordinates of translation to be made by this transformation.
     *
     * @param translation translation to be set.
     */
    public void setTranslation(final Point2D translation) {
        setTranslation(translation.getInhomX(), translation.getInhomY());
    }

    /**
     * Gets x, y coordinates of translation to be made by this transformation
     * as a new point.
     *
     * @return a new point containing translation coordinates.
     */
    public Point2D getTranslationPoint() {
        final var out = Point2D.create();
        getTranslationPoint(out);
        return out;
    }

    /**
     * Gets x, y coordinates of translation to be made by this transformation
     * and stores them into provided point.
     *
     * @param out point where translation coordinates will be stored.
     */
    public void getTranslationPoint(final Point2D out) {
        out.setInhomogeneousCoordinates(translation[0], translation[1]);
    }

    /**
     * Adds provided x coordinate to current translation assigned to this
     * transformation.
     *
     * @param translationX X coordinate to be added to current translation.
     */
    public void addTranslationX(final double translationX) {
        translation[0] += translationX;
    }

    /**
     * Adds provided y coordinate to current translation assigned to this
     * transformation.
     *
     * @param translationY Y coordinate to be added to current translation.
     */
    public void addTranslationY(final double translationY) {
        translation[1] += translationY;
    }

    /**
     * Adds provided coordinates to current translation assigned to this
     * transformation.
     *
     * @param translationX x coordinate to be added to current translation.
     * @param translationY y coordinate to be added to current translation.
     */
    public void addTranslation(final double translationX, final double translationY) {
        translation[0] += translationX;
        translation[1] += translationY;
    }

    /**
     * Adds provided coordinates to current translation assigned to this
     * transformation.
     *
     * @param translation x, y, coordinates to be added to current translation.
     */
    public void addTranslation(final Point2D translation) {
        addTranslation(translation.getInhomX(), translation.getInhomY());
    }

    /**
     * Represents this transformation as a 3x3 matrix.
     * a point can be transformed as T * p, where T is the transformation matrix
     * and p is a point expressed as an homogeneous vector.
     *
     * @return This transformation in matrix form.
     */
    @Override
    public Matrix asMatrix() {
        Matrix m = null;
        try {
            m = new Matrix(HOM_COORDS, HOM_COORDS);
            asMatrix(m);
        } catch (final WrongSizeException ignore) {
            // never happens
        }
        return m;
    }

    /**
     * Represents this transformation as a 3x3 matrix and stores the result in
     * provided instance.
     *
     * @param m instance where transformation matrix will be stored.
     * @throws IllegalArgumentException raised if provided instance is not a 3x3
     *                                  matrix.
     */
    @Override
    public void asMatrix(final Matrix m) {
        if (m.getRows() != HOM_COORDS || m.getColumns() != HOM_COORDS) {
            throw new IllegalArgumentException();
        }

        // set rotation
        m.setSubmatrix(0, 0, INHOM_COORDS - 1, INHOM_COORDS - 1,
File Line
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 202
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 425
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 609
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 431
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 278
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<PinholeCamera>() {

            // point to be reused when computing residuals
            private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

            // 3D points for a subset of samples
            private final List<Point3D> subset3D = new ArrayList<>();

            // 2D points for a subset of samples
            private final List<Point2D> subset2D = new ArrayList<>();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraRobustEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                // pick i-th points
                final var point3D = points3D.get(i);
                final var point2D = points2D.get(i);

                // project point3D into test point
                currentEstimation.project(point3D, testPoint);

                // compare test point and 2D point
                return testPoint.distanceTo(point2D);
            }

            @Override
            public boolean isReady() {
                return MSACDLTPointCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 276
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 283
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<PinholeCamera>() {

            // point to be reused when computing residuals
            private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

            // 3D points for a subset of samples
            private final List<Point3D> subset3D = new ArrayList<>();

            // 2D points for a subset of samples
            private final List<Point2D> subset2D = new ArrayList<>();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                // pick i-th points
                final var point3D = points3D.get(i);
                final var point2D = points2D.get(i);

                // project point3D into test point
                currentEstimation.project(point3D, testPoint);

                // compare test point and 2D point
                return testPoint.distanceTo(point2D);
            }

            @Override
            public boolean isReady() {
                return MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 206
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 283
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<PinholeCamera>() {

            // point to be reused when computing residuals
            private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

            // 3D points for a subset of samples
            private final List<Point3D> subset3D = new ArrayList<>();

            // 2D points for a subset of samples
            private final List<Point2D> subset2D = new ArrayList<>();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                // pick i-th points
                final var point3D = points3D.get(i);
                final var point2D = points2D.get(i);

                // project point3D into test point
                currentEstimation.project(point3D, testPoint);

                // compare test point and 2D point
                return testPoint.distanceTo(point2D);
            }

            @Override
            public boolean isReady() {
                return MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 439
com/irurueta/geometry/estimators/EuclideanTransformation3DRobustEstimator.java 438
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 436
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 436
public void setListener(final EuclideanTransformation2DRobustEstimatorListener listener) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.listener = listener;
    }

    /**
     * Indicates whether listener has been provided and is available for
     * retrieval.
     *
     * @return true if available, false otherwise.
     */
    public boolean isListenerAvailable() {
        return listener != null;
    }

    /**
     * Indicates whether estimation can start with only 2 points or not.
     *
     * @return true allows 2 points, false requires 3.
     */
    public boolean isWeakMinimumSizeAllowed() {
        return weakMinimumSizeAllowed;
    }

    /**
     * Specifies whether estimation can start with only 2 points or not.
     *
     * @param weakMinimumSizeAllowed true allows 2 points, false requires 3.
     * @throws LockedException if estimator is locked.
     */
    public void setWeakMinimumSizeAllowed(final boolean weakMinimumSizeAllowed) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.weakMinimumSizeAllowed = weakMinimumSizeAllowed;
    }

    /**
     * Required minimum number of point correspondences to start the estimation.
     * Can be either 2 or 3.
     *
     * @return minimum number of point correspondences.
     */
    public int getMinimumPoints() {
        return weakMinimumSizeAllowed ? WEAK_MINIMUM_SIZE : MINIMUM_SIZE;
    }

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
        return keepCovariance;
    }

    /**
     * Specifies whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @param keepCovariance true if covariance must be kept after refining
     *                       result, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.keepCovariance = keepCovariance;
    }

    /**
     * Gets estimated covariance of estimated 3D point if available.
     * This is only available when result has been refined and covariance is
     * kept.
     *
     * @return estimated covariance or null.
     */
    public Matrix getCovariance() {
        return covariance;
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and the
     * best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    public abstract EuclideanTransformation2D estimate() throws LockedException, NotReadyException,
File Line
com/irurueta/geometry/refiners/DecomposedLinePlaneCorrespondencePinholeCameraRefiner.java 167
com/irurueta/geometry/refiners/DecomposedPointCorrespondencePinholeCameraRefiner.java 168
final List<Plane> samples1, final List<Line2D> samples2, final double refinementStandardDeviation) {
        super(initialEstimation, keepCovariance, inliersData, samples1, samples2, refinementStandardDeviation);
    }

    /**
     * Gets minimum suggestion weight. This weight is used to slowly draw
     * original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @return minimum suggestion weight.
     */
    public double getMinSuggestionWeight() {
        return minSuggestionWeight;
    }

    /**
     * Sets minimum suggestion weight. This weight is used to slowly draw
     * original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @param minSuggestionWeight minimum suggestion weight.
     * @throws LockedException if estimator is locked.
     */
    public void setMinSuggestionWeight(final double minSuggestionWeight) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.minSuggestionWeight = minSuggestionWeight;
    }

    /**
     * Gets maximum suggestion weight. This weight is used to slowly draw
     * original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @return maximum suggestion weight.
     */
    public double getMaxSuggestionWeight() {
        return maxSuggestionWeight;
    }

    /**
     * Sets maximum suggestion weight. This weight is used to slowly draw
     * original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @param maxSuggestionWeight maximum suggestion weight.
     * @throws LockedException if estimator is locked.
     */
    public void setMaxSuggestionWeight(final double maxSuggestionWeight) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.maxSuggestionWeight = maxSuggestionWeight;
    }

    /**
     * Sets minimum and maximum suggestion weights. Suggestion weight is used to
     * slowly draw original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @param minSuggestionWeight minimum suggestion weight.
     * @param maxSuggestionWeight maximum suggestion weight.
     * @throws LockedException          if estimator is locked.
     * @throws IllegalArgumentException if minimum suggestion weight is greater
     *                                  or equal than maximum value.
     */
    public void setMinMaxSuggestionWeight(final double minSuggestionWeight, final double maxSuggestionWeight)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (minSuggestionWeight >= maxSuggestionWeight) {
            throw new IllegalArgumentException();
        }

        this.minSuggestionWeight = minSuggestionWeight;
        this.maxSuggestionWeight = maxSuggestionWeight;
    }

    /**
     * Gets step to increase suggestion weight. This weight is used to slowly
     * draw original camera parameters into desired suggested values. Suggestion
     * weight slowly increases each time Levenberg-Marquardt is used to find a
     * solution so that the algorithm can converge into desired value. The
     * faster the weights are increased the less likely that suggested values
     * can be converged if they differ too much from the original ones.
     *
     * @return step to increase suggestion weight.
     */
    public double getSuggestionWeightStep() {
        return suggestionWeightStep;
    }

    /**
     * Sets step to increase suggestion weight. This weight is used to slowly
     * draw original camera parameters into desired suggested values. Suggestion
     * weight slowly increases each time Levenberg-Marquardt is used to find a
     * solution so that the algorithm can converge into desired value. The
     * faster the weights are increased the less likely that suggested values
     * can be converged if they differ too much from the original ones.
     *
     * @param suggestionWeightStep step to increase suggestion weight.
     * @throws LockedException          if estimator is locked.
     * @throws IllegalArgumentException if provided step is negative or zero.
     */
    public void setSuggestionWeightStep(final double suggestionWeightStep) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (suggestionWeightStep <= 0.0) {
            throw new IllegalArgumentException();
        }

        this.suggestionWeightStep = suggestionWeightStep;
    }

    /**
     * Refines provided initial estimation.
     * This method always sets a value into provided result instance regardless
     * of the fact that error has actually improved in LMSE terms or not.
     *
     * @param result instance where refined estimation will be stored.
     * @return true if result improves (decreases) in LMSE terms respect to
     * initial estimation, false if no improvement has been achieved.
     * @throws NotReadyException if not enough input data has been provided.
     * @throws LockedException   if estimator is locked because refinement is
     *                           already in progress.
     */
    @Override
    public boolean refine(final PinholeCamera result) throws NotReadyException, LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        locked = true;

        if (listener != null) {
            listener.onRefineStart(this, initialEstimation);
        }

        final var improved = refinePowell(result);

        if (keepCovariance) {
            covariance = estimateCovarianceLevenbergMarquardt(improved ? result : initialEstimation, currentWeight);
        }

        if (listener != null) {
            listener.onRefineEnd(this, initialEstimation, result, improved);
        }

        locked = false;

        return improved;
    }

    /**
     * Estimates covariance matrix for provided estimated and refined camera
     *
     * @param pinholeCamera pinhole camera to estimate covariance for.
     * @param weight        weight for suggestion residual.
     * @return estimated covariance or null if anything fails.
     */
    private Matrix estimateCovarianceLevenbergMarquardt(final PinholeCamera pinholeCamera, final double weight) {
        try {
            pinholeCamera.normalize();

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2D line and 3D plane to compute
            // residuals
            final var nDims = Plane.PLANE_NUMBER_PARAMS + Line2D.LINE_NUMBER_PARAMS;
File Line
com/irurueta/geometry/refiners/DecomposedLinePlaneCorrespondencePinholeCameraRefiner.java 415
com/irurueta/geometry/refiners/DecomposedPointCorrespondencePinholeCameraRefiner.java 417
final var y = residualLevenbergMarquardt(pinholeCamera, line, plane, params, weight);
                    gradientEstimator.gradient(params, derivatives);

                    return y;
                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain covariance
            return fitter.getCovar();

        } catch (final Exception e) {
            // estimation failed, so we return null
            return null;
        }
    }

    /**
     * Refines camera using Powell optimization to minimize a cost function
     * consisting on the sum of squared projection residuals plus the
     * suggestion residual for any suggested terms.
     *
     * @param result instance where refined estimation will be stored.
     * @return true if result improves (decreases) in LMSE terms respect to
     * initial estimation, false if no improvement has been achieved.
     */
    private boolean refinePowell(final PinholeCamera result) {
        var improvedAtLeastOnce = false;
        currentWeight = minSuggestionWeight;

        if (hasSuggestions()) {
            try {
                // copy camera into a new instance
                refineCamera = new PinholeCamera(new Matrix(initialEstimation.getInternalMatrix()));
                refineCamera.normalize();

                final var startPoint = new double[REFINE_DIMS];
                final var listener = new RefinementMultiDimensionFunctionEvaluatorListener();
                final var optimizer = new PowellMultiOptimizer(listener, PowellMultiOptimizer.DEFAULT_TOLERANCE);

                boolean improved;
                do {
                    improved = refinementStepPowell(optimizer, listener, startPoint, currentWeight);

                    if (improved) {
                        // update result
                        result.setInternalMatrix(new Matrix(refineCamera.getInternalMatrix()));
                        improvedAtLeastOnce = true;
                    }

                    currentWeight += suggestionWeightStep;
                } while (currentWeight < maxSuggestionWeight && improved);

                return improvedAtLeastOnce;
            } catch (final GeometryException | NumericalException | AlgebraException e) {
                // refinement failed, so we return input value
                return improvedAtLeastOnce;
            }
        }
        return false;
    }

    /**
     * Computes one refinement step using Powell optimizer for a given weight
     * on suggestion terms.
     *
     * @param optimizer  Powell optimizer to be reused.
     * @param listener   Powell optimizer listener to be reused.
     * @param startPoint starting point for powell optimization. This array is
     *                   passed only for reuse purposes.
     * @param weight     suggestion terms weight.
     * @return true if this refinement step decreased projection error in LMSE
     * terms, false otherwise.
     * @throws GeometryException  if something failed.
     * @throws NumericalException if something failed.
     */
    private boolean refinementStepPowell(
            final PowellMultiOptimizer optimizer, final RefinementMultiDimensionFunctionEvaluatorListener listener,
            final double[] startPoint, final double weight) throws GeometryException, NumericalException {

        listener.weight = weight;
        cameraToParameters(refineCamera, startPoint);
        final var initResidual = residualPowell(refineCamera, startPoint, weight);

        optimizer.setStartPoint(startPoint);
        optimizer.minimize();

        final var resultParams = optimizer.getResult();
        parametersToCamera(resultParams, refineCamera);

        final var finalResidual = residualPowell(refineCamera, resultParams, weight);

        return finalResidual < initResidual;
    }

    /**
     * Listener for powell optimizer to minimize cost function during
     * refinement.
     * A weight can be provided so that required parameters are slowly drawn
     * to suggested values.
     */
    private class RefinementMultiDimensionFunctionEvaluatorListener implements MultiDimensionFunctionEvaluatorListener {
        /**
         * Weight to slowly draw parameters to suggested values.
         */
        double weight;

        /**
         * Evaluates cost function
         *
         * @param point parameters to evaluate cost function.
         * @return cost value.
         */
        @Override
        public double evaluate(final double[] point) {
            parametersToCamera(point, refineCamera);
            return residualPowell(refineCamera, point, weight);
        }
    }
}
File Line
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 276
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 357
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<PinholeCamera>() {

            // point to be reused when computing residuals
            private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

            // 3D points for a subset of samples
            private final List<Point3D> subset3D = new ArrayList<>();

            // 2D points for a subset of samples
            private final List<Point2D> subset2D = new ArrayList<>();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 206
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 357
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<PinholeCamera>() {

            // point to be reused when computing residuals
            private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

            // 3D points for a subset of samples
            private final List<Point3D> subset3D = new ArrayList<>();

            // 2D points for a subset of samples
            private final List<Point2D> subset2D = new ArrayList<>();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 206
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 430
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 281
new MSACRobustEstimatorListener<ProjectiveTransformation3D>() {

                    // plane to be reused when computing residuals
                    private final Plane testPlane = new Plane();

                    @Override
                    public double getThreshold() {
                        return threshold;
                    }

                    @Override
                    public int getTotalSamples() {
                        return inputPlanes.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation3DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation3D> solutions) {
                        final var inputPlane1 = inputPlanes.get(samplesIndices[0]);
                        final var inputPlane2 = inputPlanes.get(samplesIndices[1]);
                        final var inputPlane3 = inputPlanes.get(samplesIndices[2]);
                        final var inputPlane4 = inputPlanes.get(samplesIndices[3]);
                        final var inputPlane5 = inputPlanes.get(samplesIndices[4]);

                        final var outputPlane1 = outputPlanes.get(samplesIndices[0]);
                        final var outputPlane2 = outputPlanes.get(samplesIndices[1]);
                        final var outputPlane3 = outputPlanes.get(samplesIndices[2]);
                        final var outputPlane4 = outputPlanes.get(samplesIndices[3]);
                        final var outputPlane5 = outputPlanes.get(samplesIndices[4]);

                        try {
                            final var transformation = new ProjectiveTransformation3D(inputPlane1, inputPlane2,
                                    inputPlane3, inputPlane4, inputPlane5, outputPlane1, outputPlane2, outputPlane3,
                                    outputPlane4, outputPlane5);
                            solutions.add(transformation);
                        } catch (final CoincidentPlanesException e) {
                            // if lines are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation3D currentEstimation, final int i) {
                        final var inputPlane = inputPlanes.get(i);
                        final var outputPlane = outputPlanes.get(i);

                        // transform input plane and store result in mTestPlane
                        try {
                            currentEstimation.transform(inputPlane, testPlane);

                            return getResidual(outputPlane, testPlane);
                        } catch (final AlgebraException e) {
                            // this happens when internal matrix of affine transformation
                            // cannot be reverse (i.e. transformation is not well-defined,
                            // numerical instabilities, etc.)
                            return Double.MAX_VALUE;
                        }
                    }

                    @Override
                    public boolean isReady() {
                        return MSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 216
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 396
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 566
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 400
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 439
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 623
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 445
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 292
}

            @Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraRobustEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                // pick i-th points
                final var point3D = points3D.get(i);
                final var point2D = points2D.get(i);

                // project point3D into test point
                currentEstimation.project(point3D, testPoint);

                // compare test point and 2D point
                return testPoint.distanceTo(point2D);
            }

            @Override
            public boolean isReady() {
                return MSACDLTPointCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 253
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 218
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 398
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 568
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 402
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 441
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 625
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 447
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 294
@Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraRobustEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                // pick i-th points
                final var point3D = points3D.get(i);
                final var point2D = points2D.get(i);

                // project point3D into test point
                currentEstimation.project(point3D, testPoint);

                // compare test point and 2D point
                return testPoint.distanceTo(point2D);
            }

            @Override
            public boolean isReady() {
                return LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 326
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 292
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 222
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 299
@Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                // pick i-th points
                final var point3D = points3D.get(i);
                final var point2D = points2D.get(i);

                // project point3D into test point
                currentEstimation.project(point3D, testPoint);

                // compare test point and 2D point
                return testPoint.distanceTo(point2D);
            }

            @Override
            public boolean isReady() {
                return LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 258
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 292
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 222
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 299
@Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                // pick i-th points
                final var point3D = points3D.get(i);
                final var point2D = points2D.get(i);

                // project point3D into test point
                currentEstimation.project(point3D, testPoint);

                // compare test point and 2D point
                return testPoint.distanceTo(point2D);
            }

            @Override
            public boolean isReady() {
                return LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/ProjectiveTransformation2D.java 509
com/irurueta/geometry/ProjectiveTransformation3D.java 539
outputLine3, outputLine4);
    }

    /**
     * Returns internal matrix containing this transformation data.
     * Point transformation is computed as t * x, where x is a 2D point
     * expressed using homogeneous coordinates.
     * Usually the internal transformation matrix will be invertible.
     * When this is not the case, the transformation is considered degenerate
     * and its inverse will not be available.
     *
     * @return internal transformation matrix.
     */
    public Matrix getT() {
        return t;
    }

    /**
     * Sets internal matrix containing this transformation data.
     * Point transformation is computed as t * x, where x is a 2D point
     * expressed using homogeneous coordinates.
     * Usually provided matrix will be invertible, when this is not the case
     * this transformation will become degenerate and its inverse will not be
     * available.
     * This method does not check whether provided matrix is invertible or not.
     *
     * @param t transformation matrix.
     * @throws NullPointerException     raised if provided matrix is null.
     * @throws IllegalArgumentException raised if provided matrix is not 3x3
     */
    public final void setT(final Matrix t) {
        if (t.getRows() != HOM_COORDS || t.getColumns() != HOM_COORDS) {
            throw new IllegalArgumentException();
        }

        this.t = t;
        normalized = false;
    }

    /**
     * Returns boolean indicating whether provided matrix will produce a
     * degenerate projective transformation or not.
     *
     * @param t a 3x3 matrix to be used as the internal matrix of a projective
     *          transformation.
     * @return true if matrix will produce a degenerate transformation, false
     * otherwise.
     * @throws IllegalArgumentException raised if provided matrix is not 3x3.
     */
    public static boolean isDegenerate(final Matrix t) {
        if (t.getRows() != HOM_COORDS || t.getColumns() != HOM_COORDS) {
            throw new IllegalArgumentException();
        }

        try {
            final var decomposer = new LUDecomposer(t);
            decomposer.decompose();
            return decomposer.isSingular();
        } catch (final AlgebraException e) {
            // if decomposition fails, assume that matrix is degenerate because
            // of numerical instabilities
            return true;
        }
    }

    /**
     * Indicates whether this transformation is degenerate.
     * When a transformation is degenerate, its inverse cannot be computed.
     *
     * @return true if transformation is degenerate, false otherwise.
     */
    public boolean isDegenerate() {
        return isDegenerate(t);
    }

    /**
     * Returns affine linear mapping matrix.
     *
     * @return linear mapping matrix.
     * @see AffineTransformation2D
     */
    public Matrix getA() {
        final var a = t.getSubmatrix(0, 0,
                INHOM_COORDS - 1, INHOM_COORDS - 1);
        a.multiplyByScalar(1.0 / t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1));
        return a;
    }

    /**
     * Sets affine linear mapping matrix.
     *
     * @param a linear mapping matrix.
     * @throws NullPointerException     raised if provided matrix is null.
     * @throws IllegalArgumentException raised if provided matrix does not have
     *                                  size 2x2.
     * @see AffineTransformation2D
     */
    public final void setA(final Matrix a) {
        if (a == null) {
            throw new NullPointerException();
        }
        if (a.getRows() != INHOM_COORDS || a.getColumns() != INHOM_COORDS) {
            throw new IllegalArgumentException();
        }

        t.setSubmatrix(0, 0, INHOM_COORDS - 1, INHOM_COORDS - 1,
                a.multiplyByScalarAndReturnNew(t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1)));
        normalized = false;
    }

    /**
     * Normalizes current matrix instance.
     */
    public final void normalize() {
        if (!normalized) {
            final var norm = Utils.normF(t);
            if (norm > EPS) {
                t.multiplyByScalar(1.0 / norm);
            }
            normalized = true;
        }
    }

    /**
     * Returns the 2D rotation component associated to this transformation.
     * Note: if this rotation instance is modified, its changes won't be
     * reflected on this transformation until rotation is set again.
     *
     * @return 2D rotation.
     * @throws AlgebraException if for some reason rotation cannot be estimated
     *                          (usually because of numerical instability).
     */
    public Rotation2D getRotation() throws AlgebraException {
File Line
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 239
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 239
public PROSACDLTPointCorrespondencePinholeCameraRobustEstimator(
            final PinholeCameraRobustEstimatorListener listener, final List<Point3D> points3D,
            final List<Point2D> points2D, final double[] qualityScores) {
        super(listener, points3D, points2D);

        if (qualityScores.length != points3D.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or
     *                  not.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points3D.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 181
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 405
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 259
new MSACRobustEstimatorListener<ProjectiveTransformation3D>() {

                    // point to be reused when computing residuals
                    private final Point3D testPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                    @Override
                    public double getThreshold() {
                        return threshold;
                    }

                    @Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation3DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation3D> solutions) {
                        final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                        final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                        final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                        final var inputPoint4 = inputPoints.get(samplesIndices[3]);
                        final var inputPoint5 = inputPoints.get(samplesIndices[4]);

                        final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                        final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                        final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                        final var outputPoint4 = outputPoints.get(samplesIndices[3]);
                        final var outputPoint5 = outputPoints.get(samplesIndices[4]);

                        try {
                            final var transformation = new ProjectiveTransformation3D(inputPoint1, inputPoint2,
                                    inputPoint3, inputPoint4, inputPoint5, outputPoint1, outputPoint2, outputPoint3,
                                    outputPoint4, outputPoint5);
                            solutions.add(transformation);
                        } catch (final CoincidentPointsException e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation3D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return MSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/AffineTransformation3DRobustEstimator.java 199
com/irurueta/geometry/estimators/ProjectiveTransformation2DRobustEstimator.java 199
com/irurueta/geometry/estimators/ProjectiveTransformation3DRobustEstimator.java 199
final AffineTransformation3DRobustEstimatorListener listener) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.listener = listener;
    }

    /**
     * Indicates whether listener has been provided and is available for
     * retrieval.
     *
     * @return true if available, false otherwise.
     */
    public boolean isListenerAvailable() {
        return listener != null;
    }

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
        return keepCovariance;
    }

    /**
     * Specifies whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @param keepCovariance true if covariance must be kept after refining
     *                       result, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.keepCovariance = keepCovariance;
    }

    /**
     * Gets estimated covariance of estimated 3D point if available.
     * This is only available when result has been refined and covariance is
     * kept.
     *
     * @return estimated covariance or null.
     */
    public Matrix getCovariance() {
        return covariance;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    public abstract AffineTransformation3D estimate() throws LockedException, NotReadyException,
File Line
com/irurueta/geometry/estimators/MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 228
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 452
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 304
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<PinholeCamera>() {

            // 3D planes for a subset of samples
            private final List<Plane> subsetPlanes = new ArrayList<>();

            // 2D lines for a subset of samples
            private final List<Line2D> subsetLines = new ArrayList<>();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return LinePlaneCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subsetPlanes.clear();
                subsetPlanes.add(planes.get(samplesIndices[0]));
                subsetPlanes.add(planes.get(samplesIndices[1]));
                subsetPlanes.add(planes.get(samplesIndices[2]));
                subsetPlanes.add(planes.get(samplesIndices[3]));

                subsetLines.clear();
                subsetLines.add(lines.get(samplesIndices[0]));
                subsetLines.add(lines.get(samplesIndices[1]));
                subsetLines.add(lines.get(samplesIndices[2]));
                subsetLines.add(lines.get(samplesIndices[3]));

                try {
                    nonRobustEstimator.setLists(subsetPlanes, subsetLines);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if lines/planes configuration is degenerate, no solution
                    // is added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                final var inputLine = lines.get(i);
                final var inputPlane = planes.get(i);

                return singleBackprojectionResidual(currentEstimation, inputLine, inputPlane);
            }

            @Override
            public boolean isReady() {
                return MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/DLTPointCorrespondencePinholeCameraEstimator.java 276
com/irurueta/geometry/estimators/WeightedPointCorrespondencePinholeCameraEstimator.java 483
}

            final var decomposer = new SingularValueDecomposer(a);
            decomposer.decompose();

            if (decomposer.getNullity() > 1) {
                // point configuration is degenerate and exists a linear
                // combination of possible pinhole cameras (i.e. solution is not
                // unique up to scale)
                throw new PinholeCameraEstimatorException();
            }

            final var v = decomposer.getV();

            // use last column of V as pinhole camera vector

            // the last column of V contains pinhole camera matrix ordered by
            // rows as: P11, P12, P13, P14, P21, P22, P23, P24, P31, P32, P33,
            // P34, hence we reorder p
            final var pinholeCameraMatrix = new Matrix(
                    PinholeCamera.PINHOLE_CAMERA_MATRIX_ROWS, PinholeCamera.PINHOLE_CAMERA_MATRIX_COLS);

            pinholeCameraMatrix.setElementAt(0, 0, v.getElementAt(0, 11));
            pinholeCameraMatrix.setElementAt(0, 1, v.getElementAt(1, 11));
            pinholeCameraMatrix.setElementAt(0, 2, v.getElementAt(2, 11));
            pinholeCameraMatrix.setElementAt(0, 3, v.getElementAt(3, 11));

            pinholeCameraMatrix.setElementAt(1, 0, v.getElementAt(4, 11));
            pinholeCameraMatrix.setElementAt(1, 1, v.getElementAt(5, 11));
            pinholeCameraMatrix.setElementAt(1, 2, v.getElementAt(6, 11));
            pinholeCameraMatrix.setElementAt(1, 3, v.getElementAt(7, 11));

            pinholeCameraMatrix.setElementAt(2, 0, v.getElementAt(8, 11));
            pinholeCameraMatrix.setElementAt(2, 1, v.getElementAt(9, 11));
            pinholeCameraMatrix.setElementAt(2, 2, v.getElementAt(10, 11));
            pinholeCameraMatrix.setElementAt(2, 3, v.getElementAt(11, 11));

            // because pinholeCameraMatrix has been obtained as the last column
            // of V, then its Frobenius norm will be 1 because SVD already
            // returns normalized singular vector

            return pinholeCameraMatrix;

        } catch (final PinholeCameraEstimatorException e) {
            throw e;
        } catch (final Exception e) {
            throw new PinholeCameraEstimatorException(e);
        }
    }

    /**
     * Returns type of pinhole camera estimator.
     *
     * @return type of pinhole camera estimator.
     */
    @Override
    public PinholeCameraEstimatorType getType() {
        return PinholeCameraEstimatorType.DLT_POINT_PINHOLE_CAMERA_ESTIMATOR;
File Line
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 214
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 369
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 438
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 289
}

                    @Override
                    public int getTotalSamples() {
                        return inputPlanes.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation3DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation3D> solutions) {
                        final var inputPlane1 = inputPlanes.get(samplesIndices[0]);
                        final var inputPlane2 = inputPlanes.get(samplesIndices[1]);
                        final var inputPlane3 = inputPlanes.get(samplesIndices[2]);
                        final var inputPlane4 = inputPlanes.get(samplesIndices[3]);
                        final var inputPlane5 = inputPlanes.get(samplesIndices[4]);

                        final var outputPlane1 = outputPlanes.get(samplesIndices[0]);
                        final var outputPlane2 = outputPlanes.get(samplesIndices[1]);
                        final var outputPlane3 = outputPlanes.get(samplesIndices[2]);
                        final var outputPlane4 = outputPlanes.get(samplesIndices[3]);
                        final var outputPlane5 = outputPlanes.get(samplesIndices[4]);

                        try {
                            final var transformation = new ProjectiveTransformation3D(inputPlane1, inputPlane2,
                                    inputPlane3, inputPlane4, inputPlane5, outputPlane1, outputPlane2, outputPlane3,
                                    outputPlane4, outputPlane5);
                            solutions.add(transformation);
                        } catch (final CoincidentPlanesException e) {
                            // if lines are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation3D currentEstimation, final int i) {
                        final var inputPlane = inputPlanes.get(i);
                        final var outputPlane = outputPlanes.get(i);

                        // transform input plane and store result in mTestPlane
                        try {
                            currentEstimation.transform(inputPlane, testPlane);

                            return getResidual(outputPlane, testPlane);
                        } catch (final AlgebraException e) {
                            // this happens when internal matrix of affine transformation
                            // cannot be reverse (i.e. transformation is not well-defined,
                            // numerical instabilities, etc.)
                            return Double.MAX_VALUE;
                        }
                    }

                    @Override
                    public boolean isReady() {
                        return MSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1657
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 1649
dz = point.getInhomZ() - centroid.getInhomZ();

            c11 += dx * dx;
            c12 += dx * dy;
            c13 += dx * dz;

            c22 += dy * dy;
            c23 += dy * dz;

            c33 += dz * dz;
        }
        c11 /= n;
        c12 /= n;
        c13 /= n;
        c22 /= n;
        c23 /= n;
        c33 /= n;

        final var covar = new Matrix(3, 3);
        covar.setElementAt(0, 0, c11);
        covar.setElementAt(1, 0, c12);
        covar.setElementAt(2, 0, c13);

        covar.setElementAt(0, 1, c12);
        covar.setElementAt(1, 1, c22);
        covar.setElementAt(2, 1, c23);

        covar.setElementAt(0, 2, c13);
        covar.setElementAt(1, 2, c23);
        covar.setElementAt(2, 2, c33);

        final var decomposer = new SingularValueDecomposer(covar);
        decomposer.decompose();

        final var singularValues = decomposer.getSingularValues();
        final var v = decomposer.getV();

        // planar check
        int numControl;
        if (!planarConfigurationAllowed
                || Math.abs(singularValues[0]) < Math.abs(singularValues[2]) * planarThreshold) {
            // general configuration
            numControl = GENERAL_NUM_CONTROL_POINTS;
            isPlanar = false;
        } else {
            // planar configuration (only if allowed)
            numControl = PLANAR_NUM_CONTROL_POINTS;
            isPlanar = true;
        }

        controlWorldPoints = new ArrayList<>();

        final var centroidX = centroid.getInhomX();
        final var centroidY = centroid.getInhomY();
        final var centroidZ = centroid.getInhomZ();

        final var numDimensions = numControl - 1;
        final var k = Math.sqrt(singularValues[0] / n);
File Line
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 227
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 216
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 371
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 440
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 291
@Override
                    public int getTotalSamples() {
                        return inputPlanes.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation3DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation3D> solutions) {
                        final var inputPlane1 = inputPlanes.get(samplesIndices[0]);
                        final var inputPlane2 = inputPlanes.get(samplesIndices[1]);
                        final var inputPlane3 = inputPlanes.get(samplesIndices[2]);
                        final var inputPlane4 = inputPlanes.get(samplesIndices[3]);
                        final var inputPlane5 = inputPlanes.get(samplesIndices[4]);

                        final var outputPlane1 = outputPlanes.get(samplesIndices[0]);
                        final var outputPlane2 = outputPlanes.get(samplesIndices[1]);
                        final var outputPlane3 = outputPlanes.get(samplesIndices[2]);
                        final var outputPlane4 = outputPlanes.get(samplesIndices[3]);
                        final var outputPlane5 = outputPlanes.get(samplesIndices[4]);

                        try {
                            final var transformation = new ProjectiveTransformation3D(inputPlane1, inputPlane2,
                                    inputPlane3, inputPlane4, inputPlane5, outputPlane1, outputPlane2, outputPlane3,
                                    outputPlane4, outputPlane5);
                            solutions.add(transformation);
                        } catch (final CoincidentPlanesException e) {
                            // if lines are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation3D currentEstimation, final int i) {
                        final var inputPlane = inputPlanes.get(i);
                        final var outputPlane = outputPlanes.get(i);

                        // transform input line and store result in mTestLine
                        try {
                            currentEstimation.transform(inputPlane, testPlane);

                            return getResidual(outputPlane, testPlane);
                        } catch (final AlgebraException e) {
                            // this happens when internal matrix of affine transformation
                            // cannot be reverse (i.e. transformation is not well-defined,
                            // numerical instabilities, etc.)
                            return Double.MAX_VALUE;
                        }
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/DLTLinePlaneCorrespondencePinholeCameraEstimator.java 306
com/irurueta/geometry/estimators/WeightedLinePlaneCorrespondencePinholeCameraEstimator.java 510
}

            final var decomposer = new SingularValueDecomposer(a);
            decomposer.decompose();

            if (decomposer.getNullity() > 1) {
                // line/plane configuration is degenerate and exists a linear
                // combination of possible pinhole cameras (i.e. solution is not
                // unique up to scale)
                throw new PinholeCameraEstimatorException();
            }

            final var v = decomposer.getV();

            // use last column of V as pinhole camera vector

            // the last column of V contains pinhole camera matrix ordered by
            // columns as: P11, P21, P31, P12, P22, P32, P13, P23, P33, P14, P24,
            // P34, hence we reorder p
            final var pinholeCameraMatrix = new Matrix(
                    PinholeCamera.PINHOLE_CAMERA_MATRIX_ROWS, PinholeCamera.PINHOLE_CAMERA_MATRIX_COLS);

            pinholeCameraMatrix.setElementAt(0, 0, v.getElementAt(0, 11));
            pinholeCameraMatrix.setElementAt(1, 0, v.getElementAt(1, 11));
            pinholeCameraMatrix.setElementAt(2, 0, v.getElementAt(2, 11));

            pinholeCameraMatrix.setElementAt(0, 1, v.getElementAt(3, 11));
            pinholeCameraMatrix.setElementAt(1, 1, v.getElementAt(4, 11));
            pinholeCameraMatrix.setElementAt(2, 1, v.getElementAt(5, 11));

            pinholeCameraMatrix.setElementAt(0, 2, v.getElementAt(6, 11));
            pinholeCameraMatrix.setElementAt(1, 2, v.getElementAt(7, 11));
            pinholeCameraMatrix.setElementAt(2, 2, v.getElementAt(8, 11));

            pinholeCameraMatrix.setElementAt(0, 3, v.getElementAt(9, 11));
            pinholeCameraMatrix.setElementAt(1, 3, v.getElementAt(10, 11));
            pinholeCameraMatrix.setElementAt(2, 3, v.getElementAt(11, 11));

            // because pinholeCameraMatrix has been obtained as the last column
            // of V, then its Frobenius norm will be 1 because SVD already
            // returns normalized singular vector

            final var camera = new PinholeCamera(pinholeCameraMatrix);

            if (listener != null) {
                listener.onEstimateEnd(this);
            }

            return attemptRefine(camera);

        } catch (final PinholeCameraEstimatorException e) {
File Line
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 260
com/irurueta/geometry/estimators/LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 333
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 265
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 225
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 299
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 405
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 575
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 409
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 448
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 632
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 454
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 301
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 306
return PointCorrespondencePinholeCameraRobustEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                // pick i-th points
                final var point3D = points3D.get(i);
                final var point2D = points2D.get(i);

                // project point3D into test point
                currentEstimation.project(point3D, testPoint);

                // compare test point and 2D point
                return testPoint.distanceTo(point2D);
            }

            @Override
            public boolean isReady() {
                return LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 206
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 430
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 281
new MSACRobustEstimatorListener<ProjectiveTransformation2D>() {

                    // line to be reused when computing residuals
                    private final Line2D testLine = new Line2D();

                    @Override
                    public double getThreshold() {
                        return threshold;
                    }

                    @Override
                    public int getTotalSamples() {
                        return inputLines.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation2DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation2D> solutions) {
                        final var inputLine1 = inputLines.get(samplesIndices[0]);
                        final var inputLine2 = inputLines.get(samplesIndices[1]);
                        final var inputLine3 = inputLines.get(samplesIndices[2]);
                        final var inputLine4 = inputLines.get(samplesIndices[3]);

                        final var outputLine1 = outputLines.get(samplesIndices[0]);
                        final var outputLine2 = outputLines.get(samplesIndices[1]);
                        final var outputLine3 = outputLines.get(samplesIndices[2]);
                        final var outputLine4 = outputLines.get(samplesIndices[3]);

                        try {
                            final var transformation = new ProjectiveTransformation2D(inputLine1, inputLine2,
                                    inputLine3, inputLine4, outputLine1, outputLine2, outputLine3, outputLine4);
                            solutions.add(transformation);
                        } catch (final CoincidentLinesException e) {
                            // if lines are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation2D currentEstimation, final int i) {
                        final var inputLine = inputLines.get(i);
                        final var outputLine = outputLines.get(i);

                        // transform input line and store result in mTestLine
                        try {
                            currentEstimation.transform(inputLine, testLine);

                            return getResidual(outputLine, testLine);
                        } catch (final AlgebraException e) {
                            // this happens when internal matrix of affine transformation
                            // cannot be reverse (i.e. transformation is not well-defined,
                            // numerical instabilities, etc.)
                            return Double.MAX_VALUE;
                        }
                    }

                    @Override
                    public boolean isReady() {
                        return MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 205
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 281
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<AffineTransformation3D>() {

            // plane to be reused when computing residuals
            private final Plane testPlane = new Plane();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return inputPlanes.size();
            }

            @Override
            public int getSubsetSize() {
                return AffineTransformation3DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<AffineTransformation3D> solutions) {
                final var inputPlane1 = inputPlanes.get(samplesIndices[0]);
                final var inputPlane2 = inputPlanes.get(samplesIndices[1]);
                final var inputPlane3 = inputPlanes.get(samplesIndices[2]);
                final var inputPlane4 = inputPlanes.get(samplesIndices[3]);

                final var outputPlane1 = outputPlanes.get(samplesIndices[0]);
                final var outputPlane2 = outputPlanes.get(samplesIndices[1]);
                final var outputPlane3 = outputPlanes.get(samplesIndices[2]);
                final var outputPlane4 = outputPlanes.get(samplesIndices[3]);

                try {
                    final var transformation = new AffineTransformation3D(inputPlane1, inputPlane2, inputPlane3,
                            inputPlane4, outputPlane1, outputPlane2, outputPlane3, outputPlane4);
                    solutions.add(transformation);
                } catch (final CoincidentPlanesException e) {
                    // if lines are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final AffineTransformation3D currentEstimation, final int i) {
                final var inputPlane = inputPlanes.get(i);
                final var outputPlane = outputPlanes.get(i);

                // transform input line and store result in mTestLine
                try {
                    currentEstimation.transform(inputPlane, testPlane);

                    return getResidual(outputPlane, testPlane);
                } catch (final AlgebraException e) {
                    // this happens when internal matrix of affine transformation
                    // cannot be reverse (i.e. transformation is not well-defined,
                    // numerical instabilities, etc.)
                    return Double.MAX_VALUE;
                }
            }

            @Override
            public boolean isReady() {
                return MSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 242
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 424
super(listener, points3D, points2D);

        if (qualityScores.length != points3D.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or
     *                  not.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points3D.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 424
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 242
super(listener, intrinsic, points3D, points2D);

        if (qualityScores.length != points3D.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or
     *                  not.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points3D.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new EPnPPointCorrespondencePinholeCameraEstimator(intrinsic);
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 371
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 413
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 267
}

                    @Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation3DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation3D> solutions) {
                        final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                        final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                        final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                        final var inputPoint4 = inputPoints.get(samplesIndices[3]);
                        final var inputPoint5 = inputPoints.get(samplesIndices[4]);

                        final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                        final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                        final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                        final var outputPoint4 = outputPoints.get(samplesIndices[3]);
                        final var outputPoint5 = outputPoints.get(samplesIndices[4]);

                        try {
                            final var transformation = new ProjectiveTransformation3D(inputPoint1, inputPoint2,
                                    inputPoint3, inputPoint4, inputPoint5, outputPoint1, outputPoint2, outputPoint3,
                                    outputPoint4, outputPoint5);
                            solutions.add(transformation);
                        } catch (final CoincidentPointsException e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation3D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return MSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 226
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 191
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 373
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 415
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 269
@Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation3DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation3D> solutions) {
                        final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                        final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                        final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                        final var inputPoint4 = inputPoints.get(samplesIndices[3]);
                        final var inputPoint5 = inputPoints.get(samplesIndices[4]);

                        final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                        final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                        final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                        final var outputPoint4 = outputPoints.get(samplesIndices[3]);
                        final var outputPoint5 = outputPoints.get(samplesIndices[4]);

                        try {
                            final var transformation = new ProjectiveTransformation3D(inputPoint1, inputPoint2,
                                    inputPoint3, inputPoint4, inputPoint5, outputPoint1, outputPoint2, outputPoint3,
                                    outputPoint4, outputPoint5);
                            solutions.add(transformation);
                        } catch (final CoincidentPointsException e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation3D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 181
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 407
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 259
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<AffineTransformation3D>() {

            // point to be reused when computing residuals
            private final Point3D testPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return inputPoints.size();
            }

            @Override
            public int getSubsetSize() {
                return AffineTransformation3DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<AffineTransformation3D> solutions) {
                final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                final var inputPoint4 = inputPoints.get(samplesIndices[3]);

                final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                final var outputPoint4 = outputPoints.get(samplesIndices[3]);

                try {
                    final var transformation = new AffineTransformation3D(inputPoint1, inputPoint2, inputPoint3,
                            inputPoint4, outputPoint1, outputPoint2, outputPoint3, outputPoint4);
                    solutions.add(transformation);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final AffineTransformation3D currentEstimation, final int i) {
                final var inputPoint = inputPoints.get(i);
                final var outputPoint = outputPoints.get(i);

                // transform input point and store result in mTestPoint
                currentEstimation.transform(inputPoint, testPoint);

                return outputPoint.distanceTo(testPoint);
            }

            @Override
            public boolean isReady() {
                return MSACPointCorrespondenceAffineTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 181
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 405
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 257
new MSACRobustEstimatorListener<ProjectiveTransformation2D>() {

                    // point to be reused when computing residuals
                    private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                    @Override
                    public double getThreshold() {
                        return threshold;
                    }

                    @Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation2DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation2D> solutions) {
                        final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                        final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                        final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                        final var inputPoint4 = inputPoints.get(samplesIndices[3]);

                        final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                        final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                        final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                        final var outputPoint4 = outputPoints.get(samplesIndices[3]);

                        try {
                            final var transformation = new ProjectiveTransformation2D(inputPoint1, inputPoint2,
                                    inputPoint3, inputPoint4, outputPoint1, outputPoint2, outputPoint3, outputPoint4);
                            solutions.add(transformation);
                        } catch (final CoincidentPointsException e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return MSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 424
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 422
final EuclideanTransformation3DRobustEstimatorListener listener, final List<Point3D> inputPoints,
            final List<Point3D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an Euclidean 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 422
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 422
final EuclideanTransformation2DRobustEstimatorListener listener, final List<Point2D> inputPoints,
            final List<Point2D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
File Line
com/irurueta/geometry/estimators/AffineTransformation2DRobustEstimator.java 212
com/irurueta/geometry/estimators/AffineTransformation3DRobustEstimator.java 213
com/irurueta/geometry/estimators/ProjectiveTransformation2DRobustEstimator.java 213
com/irurueta/geometry/estimators/ProjectiveTransformation3DRobustEstimator.java 213
return mListener != null;
    }

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
        return keepCovariance;
    }

    /**
     * Specifies whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @param keepCovariance true if covariance must be kept after refining
     *                       result, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.keepCovariance = keepCovariance;
    }

    /**
     * Gets estimated covariance of estimated 3D point if available.
     * This is only available when result has been refined and covariance is
     * kept.
     *
     * @return estimated covariance or null.
     */
    public Matrix getCovariance() {
        return covariance;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point or line correspondences found using the
     * robust estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    public abstract AffineTransformation2D estimate() throws LockedException, NotReadyException,
File Line
com/irurueta/geometry/estimators/AffineTransformation2DRobustEstimator.java 213
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 486
com/irurueta/geometry/estimators/EuclideanTransformation3DRobustEstimator.java 485
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 483
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 483
com/irurueta/geometry/estimators/ProjectiveTransformation2DRobustEstimator.java 214
com/irurueta/geometry/estimators/ProjectiveTransformation3DRobustEstimator.java 214
}

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
        return keepCovariance;
    }

    /**
     * Specifies whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @param keepCovariance true if covariance must be kept after refining
     *                       result, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.keepCovariance = keepCovariance;
    }

    /**
     * Gets estimated covariance of estimated 3D point if available.
     * This is only available when result has been refined and covariance is
     * kept.
     *
     * @return estimated covariance or null.
     */
    public Matrix getCovariance() {
        return covariance;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point or line correspondences found using the
     * robust estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    public abstract AffineTransformation2D estimate() throws LockedException, NotReadyException,
File Line
com/irurueta/geometry/estimators/AffineTransformation3DRobustEstimator.java 214
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 486
com/irurueta/geometry/estimators/EuclideanTransformation3DRobustEstimator.java 485
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 483
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 483
}

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
        return keepCovariance;
    }

    /**
     * Specifies whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @param keepCovariance true if covariance must be kept after refining
     *                       result, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.keepCovariance = keepCovariance;
    }

    /**
     * Gets estimated covariance of estimated 3D point if available.
     * This is only available when result has been refined and covariance is
     * kept.
     *
     * @return estimated covariance or null.
     */
    public Matrix getCovariance() {
        return covariance;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    public abstract AffineTransformation3D estimate() throws LockedException, NotReadyException,
File Line
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 251
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 251
final AffineTransformation2DRobustEstimatorListener listener,
            final List<Line2D> inputLines, final List<Line2D> outputLines, final double[] qualityScores) {
        super(listener, inputLines, outputLines);

        if (qualityScores.length != inputLines.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether lines are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, lines are considered equal, since sign changes are not taken
     * into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched lines are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether lines are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, lines are considered equal, since sign changes are not taken
     * into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched lines are inliers
     *                  or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched lines.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched lines.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched lines.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      lines.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched lines and quality
     * scores) are provided and a minimum of MINIMUM_SIZE lines are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputLines.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 251
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 251
final AffineTransformation3DRobustEstimatorListener listener,
            final List<Plane> inputPlanes, final List<Plane> outputPlanes, final double[] qualityScores) {
        super(listener, inputPlanes, outputPlanes);

        if (qualityScores.length != inputPlanes.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched planes.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched planes.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched planes.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      planes.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched planes and quality
     * scores) are provided and a minimum of MINIMUM_SIZE planes are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPlanes.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D planes correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 242
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 242
final AffineTransformation2DRobustEstimatorListener listener,
            final List<Point2D> inputPoints, final List<Point2D> outputPoints, final double[] qualityScores) {
        super(listener, inputPoints, outputPoints);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 326
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 373
@Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 258
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 373
@Override
            public int getTotalSamples() {
                return points3D.size();
            }

            @Override
            public int getSubsetSize() {
                return PointCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is
                    // added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 513
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 261
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new EPnPPointCorrespondencePinholeCameraEstimator(intrinsic);

        nonRobustEstimator.setPlanarConfigurationAllowed(planarConfigurationAllowed);
        nonRobustEstimator.setNullspaceDimension2Allowed(nullspaceDimension2Allowed);
        nonRobustEstimator.setNullspaceDimension3Allowed(nullspaceDimension3Allowed);
        nonRobustEstimator.setPlanarThreshold(planarThreshold);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new PROSACRobustEstimator<>(new PROSACRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 672
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 814
try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = -initialBeta1;
        beta2 = -initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = initialBeta1;
        beta2 = -initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = -initialBeta1;
        beta2 = initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        // 2nd triplet: [beta11, beta12, betaff12] = [alpha1, alpha2, alpha5]
        // ------------------------------------------------------------------
        initialBeta1 = beta1 = Math.sqrt(Math.abs(a[0]));
        initialBeta2 = beta2 = a[1] / beta1;
File Line
com/irurueta/geometry/estimators/MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 214
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 369
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 438
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 289
}

                    @Override
                    public int getTotalSamples() {
                        return inputLines.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation2DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation2D> solutions) {
                        final var inputLine1 = inputLines.get(samplesIndices[0]);
                        final var inputLine2 = inputLines.get(samplesIndices[1]);
                        final var inputLine3 = inputLines.get(samplesIndices[2]);
                        final var inputLine4 = inputLines.get(samplesIndices[3]);

                        final var outputLine1 = outputLines.get(samplesIndices[0]);
                        final var outputLine2 = outputLines.get(samplesIndices[1]);
                        final var outputLine3 = outputLines.get(samplesIndices[2]);
                        final var outputLine4 = outputLines.get(samplesIndices[3]);

                        try {
                            final var transformation = new ProjectiveTransformation2D(inputLine1, inputLine2,
                                    inputLine3, inputLine4, outputLine1, outputLine2, outputLine3, outputLine4);
                            solutions.add(transformation);
                        } catch (final CoincidentLinesException e) {
                            // if lines are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation2D currentEstimation, final int i) {
                        final var inputLine = inputLines.get(i);
                        final var outputLine = outputLines.get(i);

                        // transform input line and store result in mTestLine
                        try {
                            currentEstimation.transform(inputLine, testLine);

                            return getResidual(outputLine, testLine);
                        } catch (final AlgebraException e) {
                            // this happens when internal matrix of affine transformation
                            // cannot be reverse (i.e. transformation is not well-defined,
                            // numerical instabilities, etc.)
                            return Double.MAX_VALUE;
                        }
                    }

                    @Override
                    public boolean isReady() {
                        return MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 213
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 369
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 289
}

            @Override
            public int getTotalSamples() {
                return inputPlanes.size();
            }

            @Override
            public int getSubsetSize() {
                return AffineTransformation3DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<AffineTransformation3D> solutions) {
                final var inputPlane1 = inputPlanes.get(samplesIndices[0]);
                final var inputPlane2 = inputPlanes.get(samplesIndices[1]);
                final var inputPlane3 = inputPlanes.get(samplesIndices[2]);
                final var inputPlane4 = inputPlanes.get(samplesIndices[3]);

                final var outputPlane1 = outputPlanes.get(samplesIndices[0]);
                final var outputPlane2 = outputPlanes.get(samplesIndices[1]);
                final var outputPlane3 = outputPlanes.get(samplesIndices[2]);
                final var outputPlane4 = outputPlanes.get(samplesIndices[3]);

                try {
                    final var transformation = new AffineTransformation3D(inputPlane1, inputPlane2, inputPlane3,
                            inputPlane4, outputPlane1, outputPlane2, outputPlane3, outputPlane4);
                    solutions.add(transformation);
                } catch (final CoincidentPlanesException e) {
                    // if lines are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final AffineTransformation3D currentEstimation, final int i) {
                final var inputPlane = inputPlanes.get(i);
                final var outputPlane = outputPlanes.get(i);

                // transform input line and store result in mTestLine
                try {
                    currentEstimation.transform(inputPlane, testPlane);

                    return getResidual(outputPlane, testPlane);
                } catch (final AlgebraException e) {
                    // this happens when internal matrix of affine transformation
                    // cannot be reverse (i.e. transformation is not well-defined,
                    // numerical instabilities, etc.)
                    return Double.MAX_VALUE;
                }
            }

            @Override
            public boolean isReady() {
                return MSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 227
com/irurueta/geometry/estimators/MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 216
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 371
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 440
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 291
@Override
                    public int getTotalSamples() {
                        return inputLines.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation2DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation2D> solutions) {
                        final var inputLine1 = inputLines.get(samplesIndices[0]);
                        final var inputLine2 = inputLines.get(samplesIndices[1]);
                        final var inputLine3 = inputLines.get(samplesIndices[2]);
                        final var inputLine4 = inputLines.get(samplesIndices[3]);

                        final var outputLine1 = outputLines.get(samplesIndices[0]);
                        final var outputLine2 = outputLines.get(samplesIndices[1]);
                        final var outputLine3 = outputLines.get(samplesIndices[2]);
                        final var outputLine4 = outputLines.get(samplesIndices[3]);

                        try {
                            final var transformation = new ProjectiveTransformation2D(inputLine1, inputLine2,
                                    inputLine3, inputLine4, outputLine1, outputLine2, outputLine3, outputLine4);
                            solutions.add(transformation);
                        } catch (final CoincidentLinesException e) {
                            // if lines are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation2D currentEstimation, final int i) {
                        final var inputLine = inputLines.get(i);
                        final var outputLine = outputLines.get(i);

                        // transform input line and store result in mTestLine
                        try {
                            currentEstimation.transform(inputLine, testLine);

                            return getResidual(outputLine, testLine);
                        } catch (final AlgebraException e) {
                            // this happens when internal matrix of affine transformation
                            // cannot be reverse (i.e. transformation is not well-defined,
                            // numerical instabilities, etc.)
                            return Double.MAX_VALUE;
                        }
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 425
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 423
final List<Point3D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an Euclidean 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 423
final List<Point2D> inputPoints, final List<Point2D> outputPoints,
            final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the metric 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a metric 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public MetricTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/MSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 205
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 430
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 281
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<AffineTransformation2D>() {

            // line to be reused when computing residuals
            private final Line2D testLine = new Line2D();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return inputLines.size();
            }

            @Override
            public int getSubsetSize() {
                return AffineTransformation2DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<AffineTransformation2D> solutions) {
                final var inputLine1 = inputLines.get(samplesIndices[0]);
                final var inputLine2 = inputLines.get(samplesIndices[1]);
                final var inputLine3 = inputLines.get(samplesIndices[2]);

                final var outputLine1 = outputLines.get(samplesIndices[0]);
                final var outputLine2 = outputLines.get(samplesIndices[1]);
                final var outputLine3 = outputLines.get(samplesIndices[2]);

                try {
                    final var transformation = new AffineTransformation2D(inputLine1, inputLine2, inputLine3,
                            outputLine1, outputLine2, outputLine3);
                    solutions.add(transformation);
                } catch (final CoincidentLinesException e) {
                    // if lines are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final AffineTransformation2D currentEstimation, final int i) {
                final var inputLine = inputLines.get(i);
                final var outputLine = outputLines.get(i);

                // transform input line and store result in mTestLine
                try {
                    currentEstimation.transform(inputLine, testLine);

                    return getResidual(outputLine, testLine);
                } catch (final AlgebraException e) {
                    // this happens when internal matrix of affine transformation
                    // cannot be reverse (i.e. transformation is not well-defined,
                    // numerical instabilities, etc.)
                    return Double.MAX_VALUE;
                }
            }

            @Override
            public boolean isReady() {
                return MSACLineCorrespondenceAffineTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 425
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 423
final List<Point2D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
File Line
com/irurueta/geometry/estimators/AffineTransformation2DRobustEstimator.java 213
com/irurueta/geometry/estimators/PinholeCameraRobustEstimator.java 833
com/irurueta/geometry/estimators/ProjectiveTransformation2DRobustEstimator.java 214
com/irurueta/geometry/estimators/ProjectiveTransformation3DRobustEstimator.java 214
}

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
        return keepCovariance;
    }

    /**
     * Specifies whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @param keepCovariance true if covariance must be kept after refining
     *                       result, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.keepCovariance = keepCovariance;
    }

    /**
     * Gets estimated covariance of estimated 3D point if available.
     * This is only available when result has been refined and covariance is
     * kept.
     *
     * @return estimated covariance or null.
     */
    public Matrix getCovariance() {
File Line
com/irurueta/geometry/estimators/AffineTransformation3DRobustEstimator.java 214
com/irurueta/geometry/estimators/PinholeCameraRobustEstimator.java 833
}

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
        return keepCovariance;
    }

    /**
     * Specifies whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @param keepCovariance true if covariance must be kept after refining
     *                       result, false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.keepCovariance = keepCovariance;
    }

    /**
     * Gets estimated covariance of estimated 3D point if available.
     * This is only available when result has been refined and covariance is
     * kept.
     *
     * @return estimated covariance or null.
     */
    public Matrix getCovariance() {
File Line
com/irurueta/geometry/estimators/MSACDualQuadricRobustEstimator.java 165
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 284
com/irurueta/geometry/estimators/RANSACDualQuadricRobustEstimator.java 165
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<DualQuadric>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return DualQuadricRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<DualQuadric> solutions) {
                final var plane1 = planes.get(samplesIndices[0]);
                final var plane2 = planes.get(samplesIndices[1]);
                final var plane3 = planes.get(samplesIndices[2]);
                final var plane4 = planes.get(samplesIndices[3]);
                final var plane5 = planes.get(samplesIndices[4]);
                final var plane6 = planes.get(samplesIndices[5]);
                final var plane7 = planes.get(samplesIndices[6]);
                final var plane8 = planes.get(samplesIndices[7]);
                final var plane9 = planes.get(samplesIndices[8]);

                try {
                    final var dualQuadric = new DualQuadric(plane1, plane2, plane3, plane4, plane5, plane6, plane7,
                            plane8, plane9);
                    solutions.add(dualQuadric);
                } catch (final CoincidentPlanesException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final DualQuadric currentEstimation, final int i) {
                return residual(currentEstimation, planes.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACDualQuadricRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACQuadricRobustEstimator.java 164
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 282
com/irurueta/geometry/estimators/RANSACQuadricRobustEstimator.java 164
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Quadric>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return QuadricRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Quadric> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);
                final var point4 = points.get(samplesIndices[3]);
                final var point5 = points.get(samplesIndices[4]);
                final var point6 = points.get(samplesIndices[5]);
                final var point7 = points.get(samplesIndices[6]);
                final var point8 = points.get(samplesIndices[7]);
                final var point9 = points.get(samplesIndices[8]);

                try {
                    final var quadric = new Quadric(point1, point2, point3, point4, point5, point6, point7, point8,
                            point9);
                    solutions.add(quadric);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Quadric currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACQuadricRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 243
final List<Point3D> inputPoints, final List<Point3D> outputPoints, final double[] qualityScores) {
        super(listener, inputPoints, outputPoints);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not when
     *                  testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/refiners/EuclideanTransformation3DRefiner.java 218
com/irurueta/geometry/refiners/MetricTransformation3DRefiner.java 216
System.arraycopy(initialEstimation.getTranslation(), 0, initParams, Quaternion.N_PARAMS,
                    EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point3D.POINT3D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomZ());
                    x.setElementAt(pos, 3, inputPoint.getHomW());
                    x.setElementAt(pos, 4, outputPoint.getHomX());
                    x.setElementAt(pos, 5, outputPoint.getHomY());
                    x.setElementAt(pos, 6, outputPoint.getHomZ());
                    x.setElementAt(pos, 7, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point3D inputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point3D outputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final EuclideanTransformation3D transformation = new EuclideanTransformation3D();
File Line
com/irurueta/geometry/refiners/EuclideanTransformation3DRefiner.java 219
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation3DRefiner.java 137
EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point3D.POINT3D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomZ());
                    x.setElementAt(pos, 3, inputPoint.getHomW());
                    x.setElementAt(pos, 4, outputPoint.getHomX());
                    x.setElementAt(pos, 5, outputPoint.getHomY());
                    x.setElementAt(pos, 6, outputPoint.getHomZ());
                    x.setElementAt(pos, 7, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point3D inputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point3D outputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final EuclideanTransformation3D transformation = new EuclideanTransformation3D();
File Line
com/irurueta/geometry/refiners/MetricTransformation3DRefiner.java 217
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation3DRefiner.java 137
EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point3D.POINT3D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomZ());
                    x.setElementAt(pos, 3, inputPoint.getHomW());
                    x.setElementAt(pos, 4, outputPoint.getHomX());
                    x.setElementAt(pos, 5, outputPoint.getHomY());
                    x.setElementAt(pos, 6, outputPoint.getHomZ());
                    x.setElementAt(pos, 7, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point3D inputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point3D outputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final MetricTransformation3D transformation = new MetricTransformation3D();
File Line
com/irurueta/geometry/estimators/LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 248
com/irurueta/geometry/estimators/MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 241
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 317
@Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return LinePlaneCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subsetPlanes.clear();
                subsetPlanes.add(planes.get(samplesIndices[0]));
                subsetPlanes.add(planes.get(samplesIndices[1]));
                subsetPlanes.add(planes.get(samplesIndices[2]));
                subsetPlanes.add(planes.get(samplesIndices[3]));

                subsetLines.clear();
                subsetLines.add(lines.get(samplesIndices[0]));
                subsetLines.add(lines.get(samplesIndices[1]));
                subsetLines.add(lines.get(samplesIndices[2]));
                subsetLines.add(lines.get(samplesIndices[3]));

                try {
                    nonRobustEstimator.setLists(subsetPlanes, subsetLines);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if lines/planes configuration is degenerate, no solution
                    // is added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
                final var inputLine = lines.get(i);
                final var inputPlane = planes.get(i);

                return singleBackprojectionResidual(currentEstimation, inputLine, inputPlane);
            }

            @Override
            public boolean isReady() {
                return LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 243
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 243
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 243
final List<Point2D> inputPoints, final List<Point2D> outputPoints, final double[] qualityScores) {
        super(listener, inputPoints, outputPoints);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/refiners/EuclideanTransformation3DRefiner.java 219
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 137
EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point3D.POINT3D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomZ());
                    x.setElementAt(pos, 3, inputPoint.getHomW());
                    x.setElementAt(pos, 4, outputPoint.getHomX());
                    x.setElementAt(pos, 5, outputPoint.getHomY());
                    x.setElementAt(pos, 6, outputPoint.getHomZ());
                    x.setElementAt(pos, 7, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point3D inputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point3D outputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final EuclideanTransformation3D transformation = new EuclideanTransformation3D();
File Line
com/irurueta/geometry/refiners/MetricTransformation3DRefiner.java 217
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 137
EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point3D.POINT3D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomZ());
                    x.setElementAt(pos, 3, inputPoint.getHomW());
                    x.setElementAt(pos, 4, outputPoint.getHomX());
                    x.setElementAt(pos, 5, outputPoint.getHomY());
                    x.setElementAt(pos, 6, outputPoint.getHomZ());
                    x.setElementAt(pos, 7, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point3D inputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point3D outputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final MetricTransformation3D transformation = new MetricTransformation3D();
File Line
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation3DRefiner.java 137
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 137
AffineTransformation3D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point3D.POINT3D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomZ());
                    x.setElementAt(pos, 3, inputPoint.getHomW());
                    x.setElementAt(pos, 4, outputPoint.getHomX());
                    x.setElementAt(pos, 5, outputPoint.getHomY());
                    x.setElementAt(pos, 6, outputPoint.getHomZ());
                    x.setElementAt(pos, 7, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point3D inputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point3D outputPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final AffineTransformation3D transformation = new AffineTransformation3D();
File Line
com/irurueta/geometry/estimators/AffineTransformation3DRobustEstimator.java 199
com/irurueta/geometry/estimators/Point2DRobustEstimator.java 256
com/irurueta/geometry/estimators/Point3DRobustEstimator.java 256
final AffineTransformation3DRobustEstimatorListener listener) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.listener = listener;
    }

    /**
     * Indicates whether listener has been provided and is available for
     * retrieval.
     *
     * @return true if available, false otherwise.
     */
    public boolean isListenerAvailable() {
        return listener != null;
    }

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
File Line
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 331
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 184
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setLMSESolutionAllowed(false);
        nonRobustEstimator.setPointCorrespondencesNormalized(normalizeSubsetPointCorrespondences);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new PROSACRobustEstimator<>(new PROSACRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 255
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraRobustEstimator.java 133
internalSetListsUPnP(points3D, points2D);
    }

    /**
     * Indicates whether planar configuration is checked to determine whether
     * point correspondences are in such configuration and find a specific
     * solution for such case.
     *
     * @return true to allow specific solutions for planar configurations,
     * false to always find a solution assuming the general case.
     */
    public boolean isPlanarConfigurationAllowed() {
        return planarConfigurationAllowed;
    }

    /**
     * Specifies whether planar configuration is checked to determine whether
     * point correspondences are in such configuration and find a specific
     * solution for such case.
     *
     * @param planarConfigurationAllowed true to allow specific solutions for
     *                                   planar configurations, false to always find a solution assuming the
     *                                   general case.
     * @throws LockedException if estimator is locked.
     */
    public void setPlanarConfigurationAllowed(final boolean planarConfigurationAllowed) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.planarConfigurationAllowed = planarConfigurationAllowed;
    }

    /**
     * Indicates whether the case where a dimension 2 null-space is allowed.
     * When allowed, additional constraints are taken into account to ensure
     * equality of scales so that less point correspondences are required.
     * Enabling this parameter is usually ok.
     *
     * @return true to allow 2-dimensional null-space, false otherwise.
     */
    public boolean isNullspaceDimension2Allowed() {
        return nullspaceDimension2Allowed;
    }

    /**
     * Specifies whether the case where a dimension 2 null-space is allowed.
     * When allowed, additional constraints are taken into account to ensure
     * equality of scales so that less point correspondences are required.
     * Enabling this parameter is usually ok.
     *
     * @param nullspaceDimension2Allowed true to allow 2-dimensional null-space,
     *                                   false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setNullspaceDimension2Allowed(final boolean nullspaceDimension2Allowed) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.nullspaceDimension2Allowed = nullspaceDimension2Allowed;
    }

    /**
     * Gets threshold to determine whether 3D matched points are in a planar
     * configuration.
     * Points are considered to be laying in a plane when the smallest singular
     * value of their covariance matrix has a value much smaller than the
     * largest one as many times as this value.
     *
     * @return threshold to determine whether 3D matched points are in a planar
     * configuration.
     */
    public double getPlanarThreshold() {
        return planarThreshold;
    }

    /**
     * Sets threshold to determine whether 3D matched points are in a planar
     * configuration.
     * Points are considered to be laying in a plane when the smallest singular
     * value of their covariance matrix has a value much smaller than the
     * largest one as many times as this value.
     *
     * @param planarThreshold threshold to determine whether 3D matched points
     *                        are in a planar configuration.
     * @throws IllegalArgumentException if provided threshold is negative.
     * @throws LockedException          if estimator is locked.
     */
    public void setPlanarThreshold(final double planarThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (planarThreshold < 0.0) {
            throw new IllegalArgumentException();
        }
        this.planarThreshold = planarThreshold;
    }

    /**
     * Gets skewness value of intrinsic parameters to be used on estimated
     * camera.
     *
     * @return skewness value of intrinsic parameters to be used on estimated
     * camera.
     */
    public double getSkewness() {
        return skewness;
    }

    /**
     * Sets skewness value of intrinsic parameters to be used on estimated
     * camera.
     *
     * @param skewness skewness value of intrinsic parameters to be used on
     *                 estimated camera.
     * @throws LockedException if estimator is locked.
     */
    public void setSkewness(final double skewness) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }

        this.skewness = skewness;
    }

    /**
     * Returns horizontal coordinate of principal point on intrinsic parameters
     * to be used on estimated camera.
     *
     * @return horizontal coordinate of principal point on intrinsic parameters
     * to be used on estimated camera.
     */
    public double getHorizontalPrincipalPoint() {
        return horizontalPrincipalPoint;
    }

    /**
     * Sets horizontal coordinate of principal point on intrinsic parameters to
     * be used on estimated camera.
     *
     * @param horizontalPrincipalPoint horizontal coordinate of principal point
     *                                 on intrinsic parameters to be used on estimated camera.
     * @throws LockedException if estimator is locked.
     */
    public void setHorizontalPrincipalPoint(final double horizontalPrincipalPoint) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }

        this.horizontalPrincipalPoint = horizontalPrincipalPoint;
    }

    /**
     * Returns vertical coordinate of principal point on intrinsic parameters
     * to be used on estimated camera.
     *
     * @return vertical coordinate of principal point on intrinsic parameters to
     * be used on estimated camera.
     */
    public double getVerticalPrincipalPoint() {
        return verticalPrincipalPoint;
    }

    /**
     * Sets vertical coordinate of principal point on intrinsic parameters
     * to be used on estimated camera.
     *
     * @param verticalPrincipalPoint vertical coordinate of principal point on
     *                               intrinsic parameters to be used on estimated camera.
     * @throws LockedException if estimator is locked.
     */
    public void setVerticalPrincipalPoint(final double verticalPrincipalPoint) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }

        this.verticalPrincipalPoint = verticalPrincipalPoint;
    }

    /**
     * Indicates if this estimator is ready to start the estimation.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 372
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 415
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 267
}

            @Override
            public int getTotalSamples() {
                return inputPoints.size();
            }

            @Override
            public int getSubsetSize() {
                return AffineTransformation3DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<AffineTransformation3D> solutions) {
                final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                final var inputPoint4 = inputPoints.get(samplesIndices[3]);

                final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                final var outputPoint4 = outputPoints.get(samplesIndices[3]);

                try {
                    final var transformation = new AffineTransformation3D(inputPoint1, inputPoint2, inputPoint3,
                            inputPoint4, outputPoint1, outputPoint2, outputPoint3, outputPoint4);
                    solutions.add(transformation);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final AffineTransformation3D currentEstimation, final int i) {
                final var inputPoint = inputPoints.get(i);
                final var outputPoint = outputPoints.get(i);

                // transform input point and store result in mTestPoint
                currentEstimation.transform(inputPoint, testPoint);

                return outputPoint.distanceTo(testPoint);
            }

            @Override
            public boolean isReady() {
                return MSACPointCorrespondenceAffineTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 371
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 413
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 265
}

                    @Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation2DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation2D> solutions) {
                        final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                        final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                        final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                        final var inputPoint4 = inputPoints.get(samplesIndices[3]);

                        final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                        final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                        final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                        final var outputPoint4 = outputPoints.get(samplesIndices[3]);

                        try {
                            final var transformation = new ProjectiveTransformation2D(inputPoint1, inputPoint2,
                                    inputPoint3, inputPoint4, outputPoint1, outputPoint2, outputPoint3, outputPoint4);
                            solutions.add(transformation);
                        } catch (final CoincidentPointsException e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return MSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 734
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 805
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 876
focalLength = Math.sqrt(Math.abs(a[4] / a[1]));

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = -initialBeta1;
        beta2 = -initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = initialBeta1;
        beta2 = -initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = -initialBeta1;
        beta2 = initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, tmp1);
File Line
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 226
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 191
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 374
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 417
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 269
@Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return AffineTransformation3DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<AffineTransformation3D> solutions) {
                        final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                        final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                        final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                        final var inputPoint4 = inputPoints.get(samplesIndices[3]);

                        final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                        final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                        final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                        final var outputPoint4 = outputPoints.get(samplesIndices[3]);

                        try {
                            final var transformation = new AffineTransformation3D(inputPoint1, inputPoint2, inputPoint3,
                                    inputPoint4, outputPoint1, outputPoint2, outputPoint3, outputPoint4);
                            solutions.add(transformation);
                        } catch (final CoincidentPointsException e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final AffineTransformation3D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSPointCorrespondenceAffineTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 226
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 191
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 373
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 415
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 267
@Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return ProjectiveTransformation2DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<ProjectiveTransformation2D> solutions) {
                        final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                        final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                        final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                        final var inputPoint4 = inputPoints.get(samplesIndices[3]);

                        final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                        final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                        final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                        final var outputPoint4 = outputPoints.get(samplesIndices[3]);

                        try {
                            final var transformation = new ProjectiveTransformation2D(inputPoint1, inputPoint2,
                                    inputPoint3, inputPoint4, outputPoint1, outputPoint2, outputPoint3, outputPoint4);
                            solutions.add(transformation);
                        } catch (final CoincidentPointsException e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final ProjectiveTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 181
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 406
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 257
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<AffineTransformation2D>() {

            // point to be reused when computing residuals
            private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return inputPoints.size();
            }

            @Override
            public int getSubsetSize() {
                return AffineTransformation2DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<AffineTransformation2D> solutions) {
                final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                final var inputPoint3 = inputPoints.get(samplesIndices[2]);

                final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                final var outputPoint3 = outputPoints.get(samplesIndices[2]);

                try {
                    final var transformation = new AffineTransformation2D(inputPoint1, inputPoint2, inputPoint3,
                            outputPoint1, outputPoint2, outputPoint3);
                    solutions.add(transformation);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final AffineTransformation2D currentEstimation, final int i) {
                final var inputPoint = inputPoints.get(i);
                final var outputPoint = outputPoints.get(i);

                // transform input point and store result in mTestPoint
                currentEstimation.transform(inputPoint, testPoint);

                return outputPoint.distanceTo(testPoint);
            }

            @Override
            public boolean isReady() {
                return MSACPointCorrespondenceAffineTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACEuclideanTransformation2DRobustEstimator.java 249
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 333
new MSACRobustEstimatorListener<EuclideanTransformation2D>() {

                    // point to be reused when computing residuals
                    private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                    private final EuclideanTransformation2DEstimator nonRobustEstimator =
                            new EuclideanTransformation2DEstimator(isWeakMinimumSizeAllowed());

                    private final List<Point2D> subsetInputPoints = new ArrayList<>();
                    private final List<Point2D> subsetOutputPoints = new ArrayList<>();

                    @Override
                    public double getThreshold() {
                        return threshold;
                    }

                    @Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return nonRobustEstimator.getMinimumPoints();
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<EuclideanTransformation2D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final EuclideanTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return MSACEuclideanTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACEuclideanTransformation3DRobustEstimator.java 249
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 588
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 332
new MSACRobustEstimatorListener<EuclideanTransformation3D>() {

                    // point to be reused when computing residuals
                    private final Point3D testPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                    private final EuclideanTransformation3DEstimator nonRobustEstimator =
                            new EuclideanTransformation3DEstimator(isWeakMinimumSizeAllowed());

                    private final List<Point3D> subsetInputPoints = new ArrayList<>();
                    private final List<Point3D> subsetOutputPoints = new ArrayList<>();

                    @Override
                    public double getThreshold() {
                        return threshold;
                    }

                    @Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return nonRobustEstimator.getMinimumPoints();
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<EuclideanTransformation3D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final EuclideanTransformation3D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return MSACEuclideanTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACMetricTransformation2DRobustEstimator.java 247
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 587
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 331
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<MetricTransformation2D>() {

            // point to be reused when computing residuals
            private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

            private final MetricTransformation2DEstimator nonRobustEstimator = new MetricTransformation2DEstimator(
                    isWeakMinimumSizeAllowed());

            private final List<Point2D> subsetInputPoints = new ArrayList<>();
            private final List<Point2D> subsetOutputPoints = new ArrayList<>();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return inputPoints.size();
            }

            @Override
            public int getSubsetSize() {
                return nonRobustEstimator.getMinimumPoints();
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<MetricTransformation2D> solutions) {
                subsetInputPoints.clear();
                subsetOutputPoints.clear();
                for (final var samplesIndex : samplesIndices) {
                    subsetInputPoints.add(inputPoints.get(samplesIndex));
                    subsetOutputPoints.add(outputPoints.get(samplesIndex));
                }

                try {
                    nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                    solutions.add(nonRobustEstimator.estimate());
                } catch (final Exception e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final MetricTransformation2D currentEstimation, final int i) {
                final var inputPoint = inputPoints.get(i);
                final var outputPoint = outputPoints.get(i);

                // transform input point and store result in mTestPoint
                currentEstimation.transform(inputPoint, testPoint);

                return outputPoint.distanceTo(testPoint);
            }

            @Override
            public boolean isReady() {
                return MSACMetricTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACMetricTransformation3DRobustEstimator.java 247
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 586
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 332
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<MetricTransformation3D>() {

            // point to be reused when computing residuals
            private final Point3D testPoint = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

            private final MetricTransformation3DEstimator nonRobustEstimator = new MetricTransformation3DEstimator(
                    isWeakMinimumSizeAllowed());

            private final List<Point3D> subsetInputPoints = new ArrayList<>();
            private final List<Point3D> subsetOutputPoints = new ArrayList<>();

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return inputPoints.size();
            }

            @Override
            public int getSubsetSize() {
                return nonRobustEstimator.getMinimumPoints();
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<MetricTransformation3D> solutions) {
                subsetInputPoints.clear();
                subsetOutputPoints.clear();
                for (final var samplesIndex : samplesIndices) {
                    subsetInputPoints.add(inputPoints.get(samplesIndex));
                    subsetOutputPoints.add(outputPoints.get(samplesIndex));
                }

                try {
                    nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                    solutions.add(nonRobustEstimator.estimate());
                } catch (final Exception e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final MetricTransformation3D currentEstimation, final int i) {
                final var inputPoint = inputPoints.get(i);
                final var outputPoint = outputPoints.get(i);

                // transform input point and store result in mTestPoint
                currentEstimation.transform(inputPoint, testPoint);

                return outputPoint.distanceTo(testPoint);
            }

            @Override
            public boolean isReady() {
                return MSACMetricTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 359
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 211
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTLinePlaneCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setLMSESolutionAllowed(false);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new PROSACRobustEstimator<>(new PROSACRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/refiners/PlaneCorrespondenceAffineTransformation3DRefiner.java 137
com/irurueta/geometry/refiners/PlaneCorrespondenceProjectiveTransformation3DRefiner.java 134
AffineTransformation3D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Plane.PLANE_NUMBER_PARAMS;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPlane = samples1.get(i);
                    final var outputPlane = samples2.get(i);
                    inputPlane.normalize();
                    outputPlane.normalize();
                    x.setElementAt(pos, 0, inputPlane.getA());
                    x.setElementAt(pos, 1, inputPlane.getB());
                    x.setElementAt(pos, 2, inputPlane.getC());
                    x.setElementAt(pos, 3, inputPlane.getD());
                    x.setElementAt(pos, 4, outputPlane.getA());
                    x.setElementAt(pos, 5, outputPlane.getB());
                    x.setElementAt(pos, 6, outputPlane.getC());
                    x.setElementAt(pos, 7, outputPlane.getD());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Plane inputPlane = new Plane();

                private final Plane outputPlane = new Plane();

                private final AffineTransformation3D transformation = new AffineTransformation3D();
File Line
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 672
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 885
try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = -initialBeta1;
        beta2 = -initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = initialBeta1;
        beta2 = -initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = -initialBeta1;
        beta2 = initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }
File Line
com/irurueta/geometry/refiners/DecomposedPointCorrespondencePinholeCameraRefiner.java 366
com/irurueta/geometry/refiners/NonDecomposedPointCorrespondencePinholeCameraRefiner.java 179
final var suggestionResidual = hasSuggestions() ? suggestionResidual(initParams, weight) : 0.0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var point2D = samples2.get(i);
                    final var point3D = samples1.get(i);
                    point2D.normalize();
                    point3D.normalize();
                    x.setElementAt(pos, 0, point2D.getHomX());
                    x.setElementAt(pos, 1, point2D.getHomY());
                    x.setElementAt(pos, 2, point2D.getHomW());
                    x.setElementAt(pos, 3, point3D.getHomX());
                    x.setElementAt(pos, 4, point3D.getHomY());
                    x.setElementAt(pos, 5, point3D.getHomZ());
                    x.setElementAt(pos, 6, point3D.getHomW());

                    y[pos] = Math.pow(residuals[i], 2.0) + suggestionResidual;
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point2D point2D = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point3D point3D = Point3D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final PinholeCamera pinholeCamera = new PinholeCamera();

                private final GradientEstimator gradientEstimator = new GradientEstimator(params -> {
                    parametersToCamera(params, pinholeCamera);
                    return residualLevenbergMarquardt(pinholeCamera, point3D, point2D, params, weight);
File Line
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 260
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 380
return PointCorrespondencePinholeCameraRobustEstimator.MIN_NUMBER_OF_POINT_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subset3D.clear();
                subset3D.add(points3D.get(samplesIndices[0]));
                subset3D.add(points3D.get(samplesIndices[1]));
                subset3D.add(points3D.get(samplesIndices[2]));
                subset3D.add(points3D.get(samplesIndices[3]));
                subset3D.add(points3D.get(samplesIndices[4]));
                subset3D.add(points3D.get(samplesIndices[5]));

                subset2D.clear();
                subset2D.add(points2D.get(samplesIndices[0]));
                subset2D.add(points2D.get(samplesIndices[1]));
                subset2D.add(points2D.get(samplesIndices[2]));
                subset2D.add(points2D.get(samplesIndices[3]));
                subset2D.add(points2D.get(samplesIndices[4]));
                subset2D.add(points2D.get(samplesIndices[5]));

                try {
                    nonRobustEstimator.setLists(subset3D, subset2D);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if points configuration is degenerate, no solution is added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/MSACDualQuadricRobustEstimator.java 170
com/irurueta/geometry/estimators/PROMedSDualQuadricRobustEstimator.java 328
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 289
com/irurueta/geometry/estimators/RANSACDualQuadricRobustEstimator.java 170
}

            @Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return DualQuadricRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<DualQuadric> solutions) {
                final var plane1 = planes.get(samplesIndices[0]);
                final var plane2 = planes.get(samplesIndices[1]);
                final var plane3 = planes.get(samplesIndices[2]);
                final var plane4 = planes.get(samplesIndices[3]);
                final var plane5 = planes.get(samplesIndices[4]);
                final var plane6 = planes.get(samplesIndices[5]);
                final var plane7 = planes.get(samplesIndices[6]);
                final var plane8 = planes.get(samplesIndices[7]);
                final var plane9 = planes.get(samplesIndices[8]);

                try {
                    final var dualQuadric = new DualQuadric(plane1, plane2, plane3, plane4, plane5, plane6, plane7,
                            plane8, plane9);
                    solutions.add(dualQuadric);
                } catch (final CoincidentPlanesException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final DualQuadric currentEstimation, final int i) {
                return residual(currentEstimation, planes.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACDualQuadricRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACQuadricRobustEstimator.java 169
com/irurueta/geometry/estimators/PROMedSQuadricRobustEstimator.java 327
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 287
com/irurueta/geometry/estimators/RANSACQuadricRobustEstimator.java 169
}

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return QuadricRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Quadric> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);
                final var point4 = points.get(samplesIndices[3]);
                final var point5 = points.get(samplesIndices[4]);
                final var point6 = points.get(samplesIndices[5]);
                final var point7 = points.get(samplesIndices[6]);
                final var point8 = points.get(samplesIndices[7]);
                final var point9 = points.get(samplesIndices[8]);

                try {
                    final var quadric = new Quadric(point1, point2, point3, point4, point5, point6, point7, point8,
                            point9);
                    solutions.add(quadric);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Quadric currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACQuadricRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSQuadricRobustEstimator.java 202
com/irurueta/geometry/estimators/MSACQuadricRobustEstimator.java 171
com/irurueta/geometry/estimators/PROMedSQuadricRobustEstimator.java 329
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 289
com/irurueta/geometry/estimators/RANSACQuadricRobustEstimator.java 171
@Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return QuadricRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Quadric> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);
                final var point4 = points.get(samplesIndices[3]);
                final var point5 = points.get(samplesIndices[4]);
                final var point6 = points.get(samplesIndices[5]);
                final var point7 = points.get(samplesIndices[6]);
                final var point8 = points.get(samplesIndices[7]);
                final var point9 = points.get(samplesIndices[8]);

                try {
                    final var quadric = new Quadric(point1, point2, point3, point4, point5, point6, point7, point8,
                            point9);
                    solutions.add(quadric);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Quadric currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return LMedSQuadricRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 426
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 245
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 244
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an Euclidean 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 425
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 245
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 244
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the metric 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a metric 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public MetricTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 424
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 245
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 244
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the metric 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a metric 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public MetricTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/refiners/HomogeneousPoint3DRefiner.java 119
com/irurueta/geometry/refiners/InhomogeneousPoint3DRefiner.java 119
public boolean refine(final HomogeneousPoint3D result) throws NotReadyException, LockedException, RefinerException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        locked = true;

        if (listener != null) {
            listener.onRefineStart(this, initialEstimation);
        }

        final var initialTotalResidual = totalResidual(initialEstimation);

        try {
            final var initParams = initialEstimation.asArray();

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain planes to compute residuals
            final var nDims = Plane.PLANE_NUMBER_PARAMS;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var plane = samples.get(i);
                    plane.normalize();
                    x.setElementAt(pos, 0, plane.getA());
                    x.setElementAt(pos, 1, plane.getB());
                    x.setElementAt(pos, 2, plane.getC());
                    x.setElementAt(pos, 3, plane.getD());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Plane plane = new Plane();

                private final HomogeneousPoint3D point = new HomogeneousPoint3D();
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 424
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 245
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 244
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
File Line
com/irurueta/geometry/estimators/LMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 227
com/irurueta/geometry/estimators/MSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 215
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 440
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 291
@Override
                    public int getTotalSamples() {
                        return inputLines.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return AffineTransformation2DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<AffineTransformation2D> solutions) {
                        final var inputLine1 = inputLines.get(samplesIndices[0]);
                        final var inputLine2 = inputLines.get(samplesIndices[1]);
                        final var inputLine3 = inputLines.get(samplesIndices[2]);

                        final var outputLine1 = outputLines.get(samplesIndices[0]);
                        final var outputLine2 = outputLines.get(samplesIndices[1]);
                        final var outputLine3 = outputLines.get(samplesIndices[2]);

                        try {
                            final var transformation = new AffineTransformation2D(inputLine1, inputLine2, inputLine3,
                                    outputLine1, outputLine2, outputLine3);
                            solutions.add(transformation);
                        } catch (final CoincidentLinesException e) {
                            // if lines are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final AffineTransformation2D currentEstimation, final int i) {
                        final var inputLine = inputLines.get(i);
                        final var outputLine = outputLines.get(i);

                        // transform input line and store result in mTestLine
                        try {
                            currentEstimation.transform(inputLine, testLine);

                            return getResidual(outputLine, testLine);
                        } catch (final AlgebraException e) {
                            // this happens when internal matrix of affine transformation
                            // cannot be reverse (i.e. transformation is not well-defined,
                            // numerical instabilities, etc.)
                            return Double.MAX_VALUE;
                        }
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSLineCorrespondenceAffineTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/refiners/HomogeneousPoint2DRefiner.java 163
com/irurueta/geometry/refiners/InhomogeneousPoint2DRefiner.java 164
private final HomogeneousPoint2D point = new HomogeneousPoint2D();

                private final GradientEstimator gradientEstimator = new GradientEstimator(p -> {
                    this.point.setCoordinates(p);
                    return residual(this.point, line);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    // point contains a,b,c values for line
                    line.setParameters(point);

                    // params contains coordinates of point
                    this.point.setCoordinates(params);

                    final var y = residual(this.point, line);
                    gradientEstimator.gradient(params, derivatives);

                    return y;
                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain estimated params
            final var params = fitter.getA();

            // update point
            result.setCoordinates(params);

            if (keepCovariance) {
                // keep covariance
                covariance = fitter.getCovar();
            }

            final var finalTotalResidual = totalResidual(result);
            final var errorDecreased = finalTotalResidual < initialTotalResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;
        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }
}
File Line
com/irurueta/geometry/refiners/HomogeneousPoint3DRefiner.java 164
com/irurueta/geometry/refiners/InhomogeneousPoint3DRefiner.java 165
private final HomogeneousPoint3D point = new HomogeneousPoint3D();

                private final GradientEstimator gradientEstimator = new GradientEstimator(p -> {
                    this.point.setCoordinates(p);
                    return residual(this.point, plane);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    // point contains a,b,c,d values for plane
                    plane.setParameters(point);

                    // params contains coordinates of point
                    this.point.setCoordinates(params);

                    final var y = residual(this.point, plane);
                    gradientEstimator.gradient(params, derivatives);

                    return y;
                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain estimated params
            final var params = fitter.getA();

            // update point
            result.setCoordinates(params);

            if (keepCovariance) {
                // keep covariance
                covariance = fitter.getCovar();
            }

            final var finalTotalResidual = totalResidual(result);
            final var errorDecreased = finalTotalResidual < initialTotalResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;
        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }
}
File Line
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 224
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 224
public PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator(
            final PinholeCameraRobustEstimatorListener listener,
            final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores) {
        super(listener, points3D, points2D);

        if (qualityScores.length != points3D.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points3D.size();
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/refiners/EuclideanTransformation2DRefiner.java 200
com/irurueta/geometry/refiners/MetricTransformation2DRefiner.java 201
1, EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point2D.POINT2D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomW());
                    x.setElementAt(pos, 3, outputPoint.getHomX());
                    x.setElementAt(pos, 4, outputPoint.getHomY());
                    x.setElementAt(pos, 5, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point2D inputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point2D outputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final EuclideanTransformation2D transformation = new EuclideanTransformation2D();
File Line
com/irurueta/geometry/refiners/EuclideanTransformation2DRefiner.java 200
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation2DRefiner.java 137
1, EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point2D.POINT2D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomW());
                    x.setElementAt(pos, 3, outputPoint.getHomX());
                    x.setElementAt(pos, 4, outputPoint.getHomY());
                    x.setElementAt(pos, 5, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point2D inputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point2D outputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final EuclideanTransformation2D transformation = new EuclideanTransformation2D();
File Line
com/irurueta/geometry/refiners/MetricTransformation2DRefiner.java 202
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation2DRefiner.java 137
EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point2D.POINT2D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomW());
                    x.setElementAt(pos, 3, outputPoint.getHomX());
                    x.setElementAt(pos, 4, outputPoint.getHomY());
                    x.setElementAt(pos, 5, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point2D inputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point2D outputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final MetricTransformation2D transformation = new MetricTransformation2D();
File Line
com/irurueta/geometry/refiners/EuclideanTransformation2DRefiner.java 200
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 136
1, EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point2D.POINT2D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomW());
                    x.setElementAt(pos, 3, outputPoint.getHomX());
                    x.setElementAt(pos, 4, outputPoint.getHomY());
                    x.setElementAt(pos, 5, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point2D inputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point2D outputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final EuclideanTransformation2D transformation = new EuclideanTransformation2D();
File Line
com/irurueta/geometry/refiners/MetricTransformation2DRefiner.java 202
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 136
EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point2D.POINT2D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomW());
                    x.setElementAt(pos, 3, outputPoint.getHomX());
                    x.setElementAt(pos, 4, outputPoint.getHomY());
                    x.setElementAt(pos, 5, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point2D inputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point2D outputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final MetricTransformation2D transformation = new MetricTransformation2D();
File Line
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation2DRefiner.java 137
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 136
AffineTransformation2D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Point2D.POINT2D_HOMOGENEOUS_COORDINATES_LENGTH;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomW());
                    x.setElementAt(pos, 3, outputPoint.getHomX());
                    x.setElementAt(pos, 4, outputPoint.getHomY());
                    x.setElementAt(pos, 5, outputPoint.getHomW());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Point2D inputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final Point2D outputPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                private final AffineTransformation2D transformation = new AffineTransformation2D();
File Line
com/irurueta/geometry/refiners/HomogeneousPoint2DRefiner.java 119
com/irurueta/geometry/refiners/InhomogeneousPoint2DRefiner.java 119
public boolean refine(final HomogeneousPoint2D result) throws NotReadyException, LockedException, RefinerException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        locked = true;

        if (listener != null) {
            listener.onRefineStart(this, initialEstimation);
        }

        final var initialTotalResidual = totalResidual(initialEstimation);

        try {
            final var initParams = initialEstimation.asArray();

            // output value to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain planes to compute residuals
            final var nDims = Line2D.LINE_NUMBER_PARAMS;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var line = samples.get(i);
                    line.normalize();
                    x.setElementAt(pos, 0, line.getA());
                    x.setElementAt(pos, 1, line.getB());
                    x.setElementAt(pos, 2, line.getC());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Line2D line = new Line2D();

                private final HomogeneousPoint2D point = new HomogeneousPoint2D();
File Line
com/irurueta/geometry/estimators/AffineTransformation2DRobustEstimator.java 212
com/irurueta/geometry/estimators/Point2DRobustEstimator.java 270
com/irurueta/geometry/estimators/Point3DRobustEstimator.java 270
return mListener != null;
    }

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 371
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 414
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 265
}

            @Override
            public int getTotalSamples() {
                return inputPoints.size();
            }

            @Override
            public int getSubsetSize() {
                return AffineTransformation2DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<AffineTransformation2D> solutions) {
                final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                final var inputPoint3 = inputPoints.get(samplesIndices[2]);

                final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                final var outputPoint3 = outputPoints.get(samplesIndices[2]);

                try {
                    final var transformation = new AffineTransformation2D(inputPoint1, inputPoint2, inputPoint3,
                            outputPoint1, outputPoint2, outputPoint3);
                    solutions.add(transformation);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final AffineTransformation2D currentEstimation, final int i) {
                final var inputPoint = inputPoints.get(i);
                final var outputPoint = outputPoints.get(i);

                // transform input point and store result in mTestPoint
                currentEstimation.transform(inputPoint, testPoint);

                return outputPoint.distanceTo(testPoint);
            }

            @Override
            public boolean isReady() {
                return MSACPointCorrespondenceAffineTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 486
com/irurueta/geometry/estimators/Point2DRobustEstimator.java 271
com/irurueta/geometry/estimators/Point3DRobustEstimator.java 271
}

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
        return inliersData;
    }

    /**
     * Indicates whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     * If ture, inliers will be computed and kept in any implementation
     * regardless of the settings.
     *
     * @return true to refine result, false to simply use result found by
     * robust estimator without further refining.
     */
    public boolean isResultRefined() {
        return refineResult;
    }

    /**
     * Specifies whether result must be refined using Levenberg-Marquardt
     * fitting algorithm over found inliers.
     *
     * @param refineResult true to refine result, false to simply use result
     *                     found by robust estimator without further refining.
     * @throws LockedException if estimator is locked.
     */
    public void setResultRefined(final boolean refineResult) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.refineResult = refineResult;
    }

    /**
     * Indicates whether covariance must be kept after refining result.
     * This setting is only taken into account if result is refined.
     *
     * @return true if covariance must be kept after refining result, false
     * otherwise.
     */
    public boolean isCovarianceKept() {
File Line
com/irurueta/geometry/estimators/EuclideanTransformation3DEstimator.java 430
com/irurueta/geometry/estimators/MetricTransformation3DEstimator.java 454
result.setTranslation(t.getBuffer());

            if (listener != null) {
                listener.onEstimateEnd(this);
            }

        } catch (final AlgebraException | InvalidRotationMatrixException e) {
            throw new CoincidentPointsException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Computes centroid of provided list of points using inhomogeneous
     * coordinates.
     *
     * @param points list of points to compute centroid.
     * @return centroid.
     * @throws AlgebraException never thrown.
     */
    private static Matrix computeCentroid(final List<Point3D> points) throws AlgebraException {
        var x = 0.0;
        var y = 0.0;
        var z = 0.0;
        final var n = points.size();
        for (final var p : points) {
            x += p.getInhomX() / n;
            y += p.getInhomY() / n;
            z += p.getInhomZ() / n;
        }

        final var result = new Matrix(Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH, 1);
        result.setElementAtIndex(0, x);
        result.setElementAtIndex(1, y);
        result.setElementAtIndex(2, z);
        return result;
    }

    /**
     * Internal method to set lists of points to be used to estimate an
     * Euclidean 3D transformation.
     * This method does not check whether estimator is locked or not.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     Euclidean 3D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     Euclidean 3D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than #getMinimumPoints.
     */
    private void internalSetPoints(final List<Point3D> inputPoints, final List<Point3D> outputPoints) {
        if (inputPoints.size() < getMinimumPoints()) {
            throw new IllegalArgumentException();
        }
        if (inputPoints.size() != outputPoints.size()) {
            throw new IllegalArgumentException();
        }
        this.inputPoints = inputPoints;
        this.outputPoints = outputPoints;
    }
}
File Line
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 226
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 191
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 373
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 416
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 267
@Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return AffineTransformation2DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<AffineTransformation2D> solutions) {
                        final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                        final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                        final var inputPoint3 = inputPoints.get(samplesIndices[2]);

                        final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                        final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                        final var outputPoint3 = outputPoints.get(samplesIndices[2]);

                        try {
                            final var transformation = new AffineTransformation2D(inputPoint1, inputPoint2, inputPoint3,
                                    outputPoint1, outputPoint2, outputPoint3);
                            solutions.add(transformation);
                        } catch (final CoincidentPointsException e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final AffineTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSPointCorrespondenceAffineTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/AffineTransformation2D.java 764
com/irurueta/geometry/EuclideanTransformation2D.java 411
throws NonSymmetricMatrixException, AlgebraException {
        // point' * conic * point = 0
        // point' * T' * transformedConic * T * point = 0
        // where:
        // - transformedPoint = T * point

        // Hence:
        // transformedConic = T^-1' * conic * T^-1

        inputConic.normalize();

        final var c = inputConic.asMatrix();
        final var invT = inverseAndReturnNew().asMatrix();
        // normalize transformation matrix invT to increase accuracy
        var norm = Utils.normF(invT);
        invT.multiplyByScalar(1.0 / norm);

        final var m = invT.transposeAndReturnNew();
        try {
            m.multiply(c);
            m.multiply(invT);
        } catch (final WrongSizeException ignore) {
            // never happens
        }

        // normalize resulting m matrix to increase accuracy so that it can be
        // considered symmetric
        norm = Utils.normF(m);
        m.multiplyByScalar(1.0 / norm);

        outputConic.setParameters(m);
    }

    /**
     * Transforms a dual conic using this transformation and stores the result
     * into provided output dual conic.
     *
     * @param inputDualConic  dual conic to be transformed.
     * @param outputDualConic instance where data of transformed dual conic will
     *                        be stored.
     * @throws NonSymmetricMatrixException raised if due to numerical precision
     *                                     the resulting output dual conic matrix is not considered to be symmetric.
     */
    @Override
    public void transform(final DualConic inputDualConic, final DualConic outputDualConic)
            throws NonSymmetricMatrixException {
        // line' * dualConic * line = 0
        // line' * T^-1 * T * dualConic * T' * T^-1'* line

        // Hence:
        // transformed plane: T^-1'* line
        // transformed dual quadric: T * dualQuadric * T'

        inputDualConic.normalize();

        final var dualC = inputDualConic.asMatrix();
        final var t = asMatrix();
        // normalize transformation matrix T to increase accuracy
        var norm = Utils.normF(t);
        t.multiplyByScalar(1.0 / norm);

        final var transT = t.transposeAndReturnNew();
        try {
            t.multiply(dualC);
            t.multiply(transT);
        } catch (final WrongSizeException ignore) {
            //never happens
        }

        // normalize resulting m matrix to increase accuracy so that it can be
        // considered symmetric
        norm = Utils.normF(t);
        t.multiplyByScalar(1.0 / norm);

        outputDualConic.setParameters(t);
    }

    /**
     * Transforms provided input line using this transformation and stores the
     * result into provided output line instance.
     *
     * @param inputLine  line to be transformed.
     * @param outputLine instance where data of transformed line will be stored.
     * @throws AlgebraException raised if transform cannot be computed because
     *                          of numerical instabilities.
     */
    @Override
    public void transform(final Line2D inputLine, final Line2D outputLine) throws AlgebraException {
File Line
com/irurueta/geometry/AffineTransformation3D.java 828
com/irurueta/geometry/EuclideanTransformation3D.java 452
AlgebraException {
        // point' * quadric * point = 0
        // point' * T' * transformedQuadric * T * point = 0
        // where:
        // - transformedPoint = T * point

        // Hence:
        // transformedQuadric = T^-1' * quadric * T^-1

        inputQuadric.normalize();

        final var q = inputQuadric.asMatrix();
        final var invT = inverseAndReturnNew().asMatrix();
        // normalize transformation matrix invT to increase accuracy
        var norm = Utils.normF(invT);
        invT.multiplyByScalar(1.0 / norm);

        final var m = invT.transposeAndReturnNew();
        try {
            m.multiply(q);
            m.multiply(invT);
        } catch (final WrongSizeException ignore) {
            // never happens
        }

        // normalize resulting m matrix to increase accuracy so that it can be
        // considered symmetric
        norm = Utils.normF(m);
        m.multiplyByScalar(1.0 / norm);

        outputQuadric.setParameters(m);
    }

    /**
     * Transforms a dual quadric using this transformation and stores the result
     * into provided output dual quadric.
     *
     * @param inputDualQuadric  dual quadric to be transformed.
     * @param outputDualQuadric instance where data of transformed dual quadric
     *                          will be stored.
     * @throws NonSymmetricMatrixException raised if due to numerical precision
     *                                     the resulting output dual conic matrix is not considered to be symmetric.
     */
    @Override
    public void transform(final DualQuadric inputDualQuadric, final DualQuadric outputDualQuadric)
            throws NonSymmetricMatrixException {
        // plane' * dualQuadric * plane = 0
        // plane' * T^-1 * T * dualQuadric * T' * T^-1'*plane

        // Hence:
        // transformed plane: T^-1'*plane
        // transformed dual quadric: T * dualQuadric * T'

        inputDualQuadric.normalize();

        final var dualQ = inputDualQuadric.asMatrix();
        final var t = asMatrix();
        // normalize transformation matrix T to increase accuracy
        var norm = Utils.normF(t);
        t.multiplyByScalar(1.0 / norm);

        final var transT = t.transposeAndReturnNew();
        try {
            t.multiply(dualQ);
            t.multiply(transT);
        } catch (final WrongSizeException ignore) {
            // never happens
        }

        // normalize resulting m matrix to increase accuracy so that it can be
        // considered symmetric
        norm = Utils.normF(t);
        t.multiplyByScalar(1.0 / norm);

        outputDualQuadric.setParameters(t);
    }

    /**
     * Transforms provided input plane using this transformation and stores the
     * result into provided output plane instance.
     *
     * @param inputPlane  plane to be transformed.
     * @param outputPlane instance where data of transformed plane will be
     *                    stored.
     * @throws AlgebraException raised if transformAndReturnNew cannot be
     *                          computed because of numerical instabilities.
     */
    @Override
    public void transform(final Plane inputPlane, final Plane outputPlane) throws AlgebraException {
File Line
com/irurueta/geometry/refiners/LineCorrespondenceAffineTransformation2DRefiner.java 139
com/irurueta/geometry/refiners/LineCorrespondenceProjectiveTransformation2DRefiner.java 138
AffineTransformation2D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Line2D.LINE_NUMBER_PARAMS;
            final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputLine = samples1.get(i);
                    final var outputLine = samples2.get(i);
                    inputLine.normalize();
                    outputLine.normalize();
                    x.setElementAt(pos, 0, inputLine.getA());
                    x.setElementAt(pos, 1, inputLine.getB());
                    x.setElementAt(pos, 2, inputLine.getC());
                    x.setElementAt(pos, 3, outputLine.getA());
                    x.setElementAt(pos, 4, outputLine.getB());
                    x.setElementAt(pos, 5, outputLine.getC());

                    y[pos] = residuals[i];
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Line2D inputLine = new Line2D();

                private final Line2D outputLine = new Line2D();

                private final AffineTransformation2D transformation = new AffineTransformation2D();
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1498
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 1496
m.setElementAt(row + 1, col + 1, alpha * verticalFocalLength);
                m.setElementAt(row + 1, col + 2, alpha * (verticalPrincipalPoint - pY));
            }
        }
    }

    /**
     * Computes the coordinates of each provided world point in terms of
     * estimated control points in world coordinates.
     * Such coordinates (i.e. barycentric coordinates) are stored in alphas
     * matrix, where each row contains the coordinates of each world point in
     * terms of control points.
     * For general configuration, each row contains 4 coordinates and alphas
     * has size nx4, where n is the number of provided 3D world points.
     * For planar configuration, each row contains 3 coordinates and alphas
     * has size nx3, where n is the number of provided 3D world points.
     * Because world and camera coordinates are related by a rotation (since
     * both reference frames are centered in the centroid), alphas can be used
     * in both world and camera coordinates.
     *
     * @throws AlgebraException if there are numerical instabilities.
     */
    private void computeBarycentricCoordinates() throws AlgebraException {
        // we need to express world points in terms of control points in world
        // coordinates

        // In the general configuration case:
        // For a point p1 in world inhomogeneous coordinates
        // p1 =  alpha1 + c1 + alpha2 * c2 + alpha3 * c3 + alpha4 * c4
        // where alpha1, alpha2, alpha3, alpha4 are scalars and
        // c1, c2, c3 are the control points in the principal axes and
        // centroid is the last control point c4, all 4 expressed in world
        // inhomogeneous coordinates as 3-column vectors.

        // Assuming a matrix form:
        // [p1] = [c1 c2 c3 c4]*[alpha1]
        //                      [alpha2]
        //                      [alpha3]
        //                      [alpha4]

        // or in simpler for p = C * alpha, where p is a 3-column vector, C is a
        // 3x4 matrix and alpha is a 4-1 vector.
        // This can be repeated for each i-th point so that:
        // pi = C * alphai --> alphai = inv(C)*pi
        // However, in this form C is not invertible because it is rank deficient
        // To avoid this deficiency we add the constraint that the sum of alphas
        // for a point must be 1, so we can use the reduced form:
        // [p1 - c4] = [(c1 - c4) (c2 - c4) (c3 - c4)]*[alpha1]
        //                                             [alpha2]
        //                                             [alpha3]
        // and set alpha4 = 1 - alpha1 - alpha2 - alpha3

        // This way the equation still holds:
        // p1 - c4 = (c1 - c4) * alpha1 + (c2 - c4) * alpha2 + (c3 - c4) * alpha3 =
        //         = c1 * alpha1 + c2 * alpha2 + c3 * alpha3 - c4 * (alpha1 + alpha2 + alpha3)
        // p1 = c1 * alpha1 + c2 * alpha2 * c3 * alpha3 + c4 * (1 - alpha1 - alpha2 - alpha3)

        // This way, we create reduced matrix C as having 3 rows (one for each
        // inhomogeneous coordinate) and 3 columns in the general case.

        // In the planar case we have only 3 control points, and the last one
        // (c3) is the centroid.

        final var numControl = controlWorldPoints.size();
        final var numDimensions = numControl - 1;
        final var numControlMinusTwo = numControl - 2;
        final var c = new Matrix(Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH, numDimensions);

        // the last control point is the centroid (or mean point)
        final var mean = controlWorldPoints.get(numDimensions);
        final var meanX = mean.getInhomX();
        final var meanY = mean.getInhomY();
        final var meanZ = mean.getInhomZ();

        for (var i = 0; i < numDimensions; i++) {
            final var controlPoint = controlWorldPoints.get(i);
            c.setElementAt(0, i, controlPoint.getInhomX() - meanX);
            c.setElementAt(1, i, controlPoint.getInhomY() - meanY);
            c.setElementAt(2, i, controlPoint.getInhomZ() - meanZ);
        }

        // to find  reduced alphas, we need to inverse the reduced C matrix and
        // multiply it by [p - centroid], where centroid can be c4 or c3 in
        // planar case.

        final var invC = Utils.inverse(c);

        // x is p - centroid, where p is each 3D world point
        final var n = points3D.size();
        final var reducedPoint = new Matrix(Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH, 1);
        final var reducedAlpha = new Matrix(numDimensions, 1);
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 293
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraRobustEstimator.java 201
}

    /**
     * Indicates whether planar configuration is checked to determine whether
     * point correspondences are in such configuration and find a specific
     * solution for such case.
     *
     * @return true to allow specific solutions for planar configurations,
     * false to always find a solution assuming the general case.
     */
    public boolean isPlanarConfigurationAllowed() {
        return planarConfigurationAllowed;
    }

    /**
     * Specifies whether planar configuration is checked to determine whether
     * point correspondences are in such configuration and find a specific
     * solution for such case.
     *
     * @param planarConfigurationAllowed true to allow specific solutions for
     *                                   planar configurations, false to always find a solution assuming the
     *                                   general case.
     * @throws LockedException if estimator is locked.
     */
    public void setPlanarConfigurationAllowed(final boolean planarConfigurationAllowed) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.planarConfigurationAllowed = planarConfigurationAllowed;
    }

    /**
     * Indicates whether the case where a dimension 2 null-space is allowed.
     * When allowed, additional constraints are taken into account to ensure
     * equality of scales so that less point correspondences are required.
     * Enabling this parameter is usually ok.
     *
     * @return true to allow 2-dimensional null-space, false otherwise.
     */
    public boolean isNullspaceDimension2Allowed() {
        return nullspaceDimension2Allowed;
    }

    /**
     * Specifies whether the case where a dimension 2 null-space is allowed.
     * When allowed, additional constraints are taken into account to ensure
     * equality of scales so that less point correspondences are required.
     * Enabling this parameter is usually ok.
     *
     * @param nullspaceDimension2Allowed true to allow 2-dimensional null-space,
     *                                   false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setNullspaceDimension2Allowed(final boolean nullspaceDimension2Allowed) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.nullspaceDimension2Allowed = nullspaceDimension2Allowed;
    }

    /**
     * Indicates whether the case where a dimension 3 null-space is allowed.
     * When allowed, additional constraints are taken into account to ensure
     * equality of scales so that less point correspondences are required.
     * Enabling this parameter is usually ok although less precise than
     * when a null-space of dimension 2 is used.
     *
     * @return true to allow 3-dimensional null-space, false otherwise.
     */
    public boolean isNullspaceDimension3Allowed() {
        return nullspaceDimension3Allowed;
    }

    /**
     * Specifies whether the case where a dimension 3 null-space is allowed.
     * When allowed, additional constraints are taken into account to ensure
     * equality of scales so that less point correspondences are required.
     * Enabling this parameter is usually ok although less precise than
     * when a null-space of dimension 2 is used.
     *
     * @param nullspaceDimension3Allowed true to allow 3-dimensional null-space,
     *                                   false otherwise.
     * @throws LockedException if estimator is locked.
     */
    public void setNullspaceDimension3Allowed(final boolean nullspaceDimension3Allowed) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.nullspaceDimension3Allowed = nullspaceDimension3Allowed;
    }

    /**
     * Gets threshold to determine whether 3D matched points are in a planar
     * configuration.
     * Points are considered to be laying in a plane when the smallest singular
     * value of their covariance matrix has a value much smaller than the
     * largest one as many times as this value.
     *
     * @return threshold to determine whether 3D matched points are in a planar
     * configuration.
     */
    public double getPlanarThreshold() {
        return planarThreshold;
    }

    /**
     * Sets threshold to determine whether 3D matched points are in a planar
     * configuration.
     * Points are considered to be laying in a plane when the smallest singular
     * value of their covariance matrix has a value much smaller than the
     * largest one as many times as this value.
     *
     * @param planarThreshold threshold to determine whether 3D matched points
     *                        are in a planar configuration.
     * @throws IllegalArgumentException if provided threshold is negative.
     * @throws LockedException          if estimator is locked.
     */
    public void setPlanarThreshold(final double planarThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (planarThreshold < 0.0) {
            throw new IllegalArgumentException();
        }
        this.planarThreshold = planarThreshold;
    }

    /**
     * Gets intrinsic parameters of camera to be estimated.
     *
     * @return intrinsic parameters of camera to be estimated.
     */
    public PinholeCameraIntrinsicParameters getIntrinsic() {
        return intrinsic;
    }

    /**
     * Sets intrinsic parameters of camera to be estimated.
     *
     * @param intrinsic intrinsic parameters of camera to be estimated.
     * @throws LockedException if estimator is locked.
     */
    public void setIntrinsic(final PinholeCameraIntrinsicParameters intrinsic) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.intrinsic = intrinsic;
    }

    /**
     * Indicates if this estimator is ready to start the estimation.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return areListsAvailable() && areValidLists(points3D, points2D) && intrinsic != null;
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1350
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 1360
point2D = points2D.get(i);
            camera.project(point3D, projected);
            error += projected.distanceTo(point2D);
        }
        return error;
    }

    /**
     * Computes list of control points from provided array containing one column
     * of the null-space of M or a linear combination of columns of the
     * null-space.
     *
     * @param v one column of the null-space of M or a linear combination of
     *          columns of the null-space.
     * @return control points.
     */
    private List<Point3D> controlPointsFromV(final double[] v) {
        final var numControl = controlWorldPoints.size();
        final var points = new ArrayList<Point3D>();

        for (var j = 0; j < numControl; j++) {
            final var k = j * 3;
            final var p = new InhomogeneousPoint3D(v[k], v[k + 1], v[k + 2]);
            points.add(p);
        }

        return points;
    }

    /**
     * Solves null-space of matrix M containing possible solutions of camera
     * coordinates of control points.
     *
     * @throws AlgebraException if something fails due to numerical
     *                          instabilities.
     */
    private void solveNullspace() throws AlgebraException {
        final var rows = m.getRows();
        final var cols = m.getColumns();
        final var numControl = cols / Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH;

        // normalize rows of m to increase numerical accuracy
        for (var i = 0; i < rows; i++) {
            normalizeRow(m, i);
        }

        final var decomposer = new SingularValueDecomposer(m);
        decomposer.decompose();

        // Singular values are always in descending order, hence null space is in
        // the last columns of v.
        // V is 12x12 (general configuration) or 9x9 (planar configuration).
        // Each column of v contains coordinates of control points in camera
        // coordinates.
        // A solution for the linear system M*x = 0 is obtained as a linear
        // combination of the columns of v forming the null-space.
        final var v = decomposer.getV();

        // although nullity of M could be determined after SVD, it is assumed
        // instead that null-space could be located in any of the latter columns
        // of v up to the number of control points.
        // Hence, for general configuration we pick the last 4 columns of v and
        // for planar configuration we pick the last 3.

        // extract null points from the null space
        nullspace = new ArrayList<>();
        final var colsMinusOne = cols - 1;
        for (var i = 0; i < numControl; i++) {
File Line
com/irurueta/geometry/estimators/MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 239
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 389
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 463
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 315
}

            @Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return LinePlaneCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subsetPlanes.clear();
                subsetPlanes.add(planes.get(samplesIndices[0]));
                subsetPlanes.add(planes.get(samplesIndices[1]));
                subsetPlanes.add(planes.get(samplesIndices[2]));
                subsetPlanes.add(planes.get(samplesIndices[3]));

                subsetLines.clear();
                subsetLines.add(lines.get(samplesIndices[0]));
                subsetLines.add(lines.get(samplesIndices[1]));
                subsetLines.add(lines.get(samplesIndices[2]));
                subsetLines.add(lines.get(samplesIndices[3]));

                try {
                    nonRobustEstimator.setLists(subsetPlanes, subsetLines);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if lines/planes configuration is degenerate, no solution
                    // is added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
File Line
com/irurueta/geometry/Plane.java 254
com/irurueta/geometry/Plane.java 321
throws ColinearPointsException {

        // normalize points to increase accuracy
        pointA.normalize();
        pointB.normalize();
        pointC.normalize();

        // we use 3 points to find one plane
        try {
            // set homogeneous coordinates of each point on each row of the matrix
            final var m = new Matrix(3, PLANE_NUMBER_PARAMS);

            m.setElementAt(0, 0, pointA.getHomX());
            m.setElementAt(0, 1, pointA.getHomY());
            m.setElementAt(0, 2, pointA.getHomZ());
            m.setElementAt(0, 3, pointA.getHomW());

            m.setElementAt(1, 0, pointB.getHomX());
            m.setElementAt(1, 1, pointB.getHomY());
            m.setElementAt(1, 2, pointB.getHomZ());
            m.setElementAt(1, 3, pointB.getHomW());

            m.setElementAt(2, 0, pointC.getHomX());
            m.setElementAt(2, 1, pointC.getHomY());
            m.setElementAt(2, 2, pointC.getHomZ());
            m.setElementAt(2, 3, pointC.getHomW());

            final var decomposer = new SingularValueDecomposer(m);
            decomposer.decompose();
File Line
com/irurueta/geometry/estimators/LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 248
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 391
@Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return LinePlaneCorrespondencePinholeCameraEstimator.MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<PinholeCamera> solutions) {
                subsetPlanes.clear();
                subsetPlanes.add(planes.get(samplesIndices[0]));
                subsetPlanes.add(planes.get(samplesIndices[1]));
                subsetPlanes.add(planes.get(samplesIndices[2]));
                subsetPlanes.add(planes.get(samplesIndices[3]));

                subsetLines.clear();
                subsetLines.add(lines.get(samplesIndices[0]));
                subsetLines.add(lines.get(samplesIndices[1]));
                subsetLines.add(lines.get(samplesIndices[2]));
                subsetLines.add(lines.get(samplesIndices[3]));

                try {
                    nonRobustEstimator.setLists(subsetPlanes, subsetLines);

                    final var cam = nonRobustEstimator.estimate();
                    solutions.add(cam);
                } catch (final Exception e) {
                    // if lines/planes configuration is degenerate, no solution
                    // is added
                }
            }

            @Override
            public double computeResidual(final PinholeCamera currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 227
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 440
@Override
                    public int getTotalSamples() {
                        return inputPlanes.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return AffineTransformation3DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<AffineTransformation3D> solutions) {
                        final var inputLine1 = inputPlanes.get(samplesIndices[0]);
                        final var inputLine2 = inputPlanes.get(samplesIndices[1]);
                        final var inputLine3 = inputPlanes.get(samplesIndices[2]);
                        final var inputLine4 = inputPlanes.get(samplesIndices[3]);

                        final var outputLine1 = outputPlanes.get(samplesIndices[0]);
                        final var outputLine2 = outputPlanes.get(samplesIndices[1]);
                        final var outputLine3 = outputPlanes.get(samplesIndices[2]);
                        final var outputLine4 = outputPlanes.get(samplesIndices[3]);

                        try {
                            final var transformation = new AffineTransformation3D(inputLine1, inputLine2, inputLine3,
                                    inputLine4, outputLine1, outputLine2, outputLine3, outputLine4);
                            solutions.add(transformation);
                        } catch (final CoincidentPlanesException e) {
                            // if lines are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final AffineTransformation3D currentEstimation, final int i) {
                        final var inputLine = inputPlanes.get(i);
File Line
com/irurueta/geometry/estimators/AffineTransformation3DRobustEstimator.java 199
com/irurueta/geometry/estimators/CircleRobustEstimator.java 196
com/irurueta/geometry/estimators/ConicRobustEstimator.java 212
com/irurueta/geometry/estimators/DualConicRobustEstimator.java 210
com/irurueta/geometry/estimators/DualQuadricRobustEstimator.java 209
com/irurueta/geometry/estimators/Line2DRobustEstimator.java 196
com/irurueta/geometry/estimators/PlaneRobustEstimator.java 196
com/irurueta/geometry/estimators/Point2DRobustEstimator.java 256
com/irurueta/geometry/estimators/Point3DRobustEstimator.java 256
com/irurueta/geometry/estimators/ProjectiveTransformation2DRobustEstimator.java 199
com/irurueta/geometry/estimators/ProjectiveTransformation3DRobustEstimator.java 199
com/irurueta/geometry/estimators/QuadricRobustEstimator.java 211
com/irurueta/geometry/estimators/SphereRobustEstimator.java 196
final AffineTransformation3DRobustEstimatorListener listener) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.listener = listener;
    }

    /**
     * Indicates whether listener has been provided and is available for
     * retrieval.
     *
     * @return true if available, false otherwise.
     */
    public boolean isListenerAvailable() {
        return listener != null;
    }

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 261
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 216
}

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES (i.e. 4 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 672
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 743
try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = -initialBeta1;
        beta2 = -initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = initialBeta1;
        beta2 = -initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
        denormalizeV(finalV, focalLength);

        controlCameraPoints = controlPointsFromV(finalV);

        try {
            solution = computePossibleSolutionWithPoseAndReprojectionError(controlCameraPoints, focalLength);
            solutions.add(solution);
        } catch (final GeometryException ignore) {
            // if it fails, solution is not added
        }

        beta1 = -initialBeta1;
        beta2 = initialBeta2;

        ArrayUtils.multiplyByScalar(va, beta1, tmp1);
        ArrayUtils.multiplyByScalar(vb, beta2, tmp2);
        ArrayUtils.sum(tmp1, tmp2, finalV);
File Line
com/irurueta/geometry/estimators/MSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 213
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 368
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 438
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 289
}

            @Override
            public int getTotalSamples() {
                return inputLines.size();
            }

            @Override
            public int getSubsetSize() {
                return AffineTransformation2DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<AffineTransformation2D> solutions) {
                final var inputLine1 = inputLines.get(samplesIndices[0]);
                final var inputLine2 = inputLines.get(samplesIndices[1]);
                final var inputLine3 = inputLines.get(samplesIndices[2]);

                final var outputLine1 = outputLines.get(samplesIndices[0]);
                final var outputLine2 = outputLines.get(samplesIndices[1]);
                final var outputLine3 = outputLines.get(samplesIndices[2]);

                try {
                    final var transformation = new AffineTransformation2D(inputLine1, inputLine2, inputLine3,
                            outputLine1, outputLine2, outputLine3);
                    solutions.add(transformation);
                } catch (final CoincidentLinesException e) {
                    // if lines are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final AffineTransformation2D currentEstimation, final int i) {
                final var inputLine = inputLines.get(i);
                final var outputLine = outputLines.get(i);

                // transform input line and store result in mTestLine
                try {
                    currentEstimation.transform(inputLine, testLine);
File Line
com/irurueta/geometry/estimators/LMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 227
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 370
@Override
                    public int getTotalSamples() {
                        return inputLines.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return AffineTransformation2DRobustEstimator.MINIMUM_SIZE;
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<AffineTransformation2D> solutions) {
                        final var inputLine1 = inputLines.get(samplesIndices[0]);
                        final var inputLine2 = inputLines.get(samplesIndices[1]);
                        final var inputLine3 = inputLines.get(samplesIndices[2]);

                        final var outputLine1 = outputLines.get(samplesIndices[0]);
                        final var outputLine2 = outputLines.get(samplesIndices[1]);
                        final var outputLine3 = outputLines.get(samplesIndices[2]);

                        try {
                            final var transformation = new AffineTransformation2D(inputLine1, inputLine2, inputLine3,
                                    outputLine1, outputLine2, outputLine3);
                            solutions.add(transformation);
                        } catch (final CoincidentLinesException e) {
                            // if lines are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final AffineTransformation2D currentEstimation, final int i) {
                        final var inputLine = inputLines.get(i);
                        final var outputLine = outputLines.get(i);

                        // transform input line and store result in mTestLine
                        try {
                            currentEstimation.transform(inputLine, testLine);
File Line
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 227
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 395
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 227
super(listener, points3D, points2D);

        if (qualityScores.length != points3D.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points3D.size();
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 196
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 156
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 336
}

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences or 2D line/3D plane
     * correspondences found using the robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using UPnP (Uncalibrated Perspective-n-Point)
        // algorithm
        final var nonRobustEstimator = new UPnPPointCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setPlanarConfigurationAllowed(planarConfigurationAllowed);
        nonRobustEstimator.setNullspaceDimension2Allowed(nullspaceDimension2Allowed);
        nonRobustEstimator.setPlanarThreshold(planarThreshold);
        nonRobustEstimator.setSkewness(skewness);
        nonRobustEstimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
        nonRobustEstimator.setVerticalPrincipalPoint(verticalPrincipalPoint);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new LMedSRobustEstimator<>(new LMedSRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 211
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 247
@Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using UPnP (Uncalibrated Perspective-n-Point)
        // algorithm
        final var nonRobustEstimator = new UPnPPointCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setPlanarConfigurationAllowed(planarConfigurationAllowed);
        nonRobustEstimator.setNullspaceDimension2Allowed(nullspaceDimension2Allowed);
        nonRobustEstimator.setPlanarThreshold(planarThreshold);
        nonRobustEstimator.setSkewness(skewness);
        nonRobustEstimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
        nonRobustEstimator.setVerticalPrincipalPoint(verticalPrincipalPoint);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new LMedSRobustEstimator<>(new LMedSRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/MSACConicRobustEstimator.java 162
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 281
com/irurueta/geometry/estimators/RANSACConicRobustEstimator.java 165
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Conic>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return ConicRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Conic> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);
                final var point4 = points.get(samplesIndices[3]);
                final var point5 = points.get(samplesIndices[4]);

                try {
                    final var conic = new Conic(point1, point2, point3, point4, point5);
                    solutions.add(conic);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Conic currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACConicRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACDualConicRobustEstimator.java 166
com/irurueta/geometry/estimators/RANSACDualConicRobustEstimator.java 165
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<DualConic>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return lines.size();
            }

            @Override
            public int getSubsetSize() {
                return DualConicRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<DualConic> solutions) {
                final var line1 = lines.get(samplesIndices[0]);
                final var line2 = lines.get(samplesIndices[1]);
                final var line3 = lines.get(samplesIndices[2]);
                final var line4 = lines.get(samplesIndices[3]);
                final var line5 = lines.get(samplesIndices[4]);

                try {
                    final var dualConic = new DualConic(line1, line2, line3, line4, line5);
                    solutions.add(dualConic);
                } catch (final CoincidentLinesException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final DualConic currentEstimation, final int i) {
                return residual(currentEstimation, lines.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACDualConicRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 171
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 247
@Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using UPnP (Uncalibrated Perspective-n-Point) algorithm
        final var nonRobustEstimator = new UPnPPointCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setPlanarConfigurationAllowed(planarConfigurationAllowed);
        nonRobustEstimator.setNullspaceDimension2Allowed(nullspaceDimension2Allowed);
        nonRobustEstimator.setPlanarThreshold(planarThreshold);
        nonRobustEstimator.setSkewness(skewness);
        nonRobustEstimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
        nonRobustEstimator.setVerticalPrincipalPoint(verticalPrincipalPoint);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 247
@Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using UPnP (Uncalibrated Perspective-n-Point) algorithm
        final var nonRobustEstimator = new UPnPPointCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setPlanarConfigurationAllowed(planarConfigurationAllowed);
        nonRobustEstimator.setNullspaceDimension2Allowed(nullspaceDimension2Allowed);
        nonRobustEstimator.setPlanarThreshold(planarThreshold);
        nonRobustEstimator.setSkewness(skewness);
        nonRobustEstimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
        nonRobustEstimator.setVerticalPrincipalPoint(verticalPrincipalPoint);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/LinePlaneCorrespondencePinholeCameraRobustEstimator.java 578
com/irurueta/geometry/estimators/PointCorrespondencePinholeCameraRobustEstimator.java 1406
keepCovariance, inliersData, planes, lines, getRefinementStandardDeviation());
            try {
                if (refineResult) {
                    refiner.setMinSuggestionWeight(weight);
                    refiner.setMaxSuggestionWeight(weight);

                    refiner.setSuggestSkewnessValueEnabled(suggestSkewnessValueEnabled);
                    refiner.setSuggestedSkewnessValue(suggestedSkewnessValue);
                    refiner.setSuggestHorizontalFocalLengthEnabled(suggestHorizontalFocalLengthEnabled);
                    refiner.setSuggestedHorizontalFocalLengthValue(suggestedHorizontalFocalLengthValue);
                    refiner.setSuggestVerticalFocalLengthEnabled(suggestVerticalFocalLengthEnabled);
                    refiner.setSuggestedVerticalFocalLengthValue(suggestedVerticalFocalLengthValue);
                    refiner.setSuggestAspectRatioEnabled(suggestAspectRatioEnabled);
                    refiner.setSuggestedAspectRatioValue(suggestedAspectRatioValue);
                    refiner.setSuggestPrincipalPointEnabled(suggestPrincipalPointEnabled);
                    refiner.setSuggestedPrincipalPointValue(suggestedPrincipalPointValue);
                    refiner.setSuggestRotationEnabled(suggestRotationEnabled);
                    refiner.setSuggestedRotationValue(suggestedRotationValue);
                    refiner.setSuggestCenterEnabled(suggestCenterEnabled);
                    refiner.setSuggestedCenterValue(suggestedCenterValue);
                }

                final var result = new PinholeCamera();
                final var improved = refiner.refine(result);

                if (keepCovariance) {
                    // keep covariance
                    covariance = refiner.getCovariance();
                }

                return improved ? result : pinholeCamera;

            } catch (final Exception e) {
                return pinholeCamera;
            }
        } else {
            covariance = null;
            return pinholeCamera;
        }
    }

    /**
     * Attempts to refine provided camera using a fast algorithm based on
     * Levenberg/Marquardt.
     *
     * @param pinholeCamera camera to be refined.
     * @param weight        weight for suggestion residual.
     * @return refined camera or provided camera if anything fails.
     */
    private PinholeCamera attemptFastRefine(final PinholeCamera pinholeCamera, final double weight) {
        final var inliersData = getInliersData();
        if (refineResult && inliersData != null) {
            final var refiner = new NonDecomposedLinePlaneCorrespondencePinholeCameraRefiner(pinholeCamera,
File Line
com/irurueta/geometry/Ellipse.java 1154
com/irurueta/geometry/Ellipse.java 1214
center.normalize();
        // use inhomogeneous center coordinates
        final var xc = center.getInhomX();
        final var yc = center.getInhomY();

        final var sint = Math.sin(rotationAngle);
        final var cost = Math.cos(rotationAngle);

        final var a = semiMajorAxis;
        final var b = semiMinorAxis;

        final var xc2 = xc * xc;
        final var yc2 = yc * yc;

        final var sint2 = sint * sint;
        final var cost2 = cost * cost;

        final var a2 = a * a;
        final var b2 = b * b;

        final var aParam = a2 * sint2 + b2 * cost2;
        final var bParam = 2.0 * (b2 - a2) * sint * cost;
        final var cParam = a2 * cost2 + b2 * sint2;
        final var dParam = -2.0 * aParam * xc - bParam * yc;
        final var eParam = -bParam * xc - 2.0 * cParam * yc;
        final var fParam = aParam * xc2 + bParam * xc * yc + cParam * yc2 - a2 * b2;

        final var x = point.getInhomX();
        final var y = point.getInhomY();

        return aParam * x * x + bParam * x * y + cParam * y * y + dParam * x + eParam * y + fParam <= threshold;
File Line
com/irurueta/geometry/estimators/DLTLinePlaneCorrespondencePinholeCameraEstimator.java 297
com/irurueta/geometry/estimators/DLTPointCorrespondencePinholeCameraEstimator.java 268
+ Math.pow(a.getElementAt(counter, 11), 2.0));

                a.setElementAt(counter, 6, a.getElementAt(counter, 6) / rowNorm);
                a.setElementAt(counter, 7, a.getElementAt(counter, 7) / rowNorm);
                a.setElementAt(counter, 8, a.getElementAt(counter, 8) / rowNorm);
                a.setElementAt(counter, 9, a.getElementAt(counter, 9) / rowNorm);
                a.setElementAt(counter, 10, a.getElementAt(counter, 10) / rowNorm);
                a.setElementAt(counter, 11, a.getElementAt(counter, 11) / rowNorm);
                counter++;
            }

            final var decomposer = new SingularValueDecomposer(a);
            decomposer.decompose();

            if (decomposer.getNullity() > 1) {
                // line/plane configuration is degenerate and exists a linear
                // combination of possible pinhole cameras (i.e. solution is not
                // unique up to scale)
                throw new PinholeCameraEstimatorException();
            }

            final var v = decomposer.getV();

            // use last column of V as pinhole camera vector

            // the last column of V contains pinhole camera matrix ordered by
            // columns as: P11, P21, P31, P12, P22, P32, P13, P23, P33, P14, P24,
            // P34, hence we reorder p
            final var pinholeCameraMatrix = new Matrix(
                    PinholeCamera.PINHOLE_CAMERA_MATRIX_ROWS, PinholeCamera.PINHOLE_CAMERA_MATRIX_COLS);

            pinholeCameraMatrix.setElementAt(0, 0, v.getElementAt(0, 11));
            pinholeCameraMatrix.setElementAt(1, 0, v.getElementAt(1, 11));
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 392
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 391
final EuclideanTransformation3DRobustEstimatorListener listener, final List<Point3D> inputPoints,
            final List<Point3D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an Euclidean 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 267
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 227
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 504
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 561
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 309
}

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences or 2D line/3D plane
     * correspondences found using the robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using EPnP (Efficient Perspective-n-Point) algorithm
        final var nonRobustEstimator = new EPnPPointCorrespondencePinholeCameraEstimator(intrinsic);

        nonRobustEstimator.setPlanarConfigurationAllowed(planarConfigurationAllowed);
        nonRobustEstimator.setNullspaceDimension2Allowed(nullspaceDimension2Allowed);
        nonRobustEstimator.setNullspaceDimension3Allowed(nullspaceDimension3Allowed);
        nonRobustEstimator.setPlanarThreshold(planarThreshold);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new LMedSRobustEstimator<>(new LMedSRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 392
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 390
final EuclideanTransformation2DRobustEstimatorListener listener, final List<Point2D> inputPoints,
            final List<Point2D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 616
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 616
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 616
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 616
PROMedSEuclideanTransformation2DRobustEstimator.this, progress);
                        }
                    }

                    @Override
                    public double[] getQualityScores() {
                        return qualityScores;
                    }
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of such
     * threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();
        return inliersData.getEstimatedThreshold();
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < getMinimumPoints()) {
            throw new IllegalArgumentException();
        }

        this.qualityScores = qualityScores;
    }
}
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 676
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 676
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 675
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 674
PROSACEuclideanTransformation2DRobustEstimator.this, progress);
                        }
                    }

                    @Override
                    public double[] getQualityScores() {
                        return qualityScores;
                    }
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < getMinimumPoints()) {
            throw new IllegalArgumentException();
        }

        this.qualityScores = qualityScores;
    }
}
File Line
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 145
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 223
super(listener, points3D, points2D);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 384
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 386
listener.onEstimateProgressChange(PROMedSPoint2DRobustEstimator.this, progress);
                }
            }

            @Override
            public double[] getQualityScores() {
                return qualityScores;
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();
        return inliersData.getEstimatedThreshold();
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }

        this.qualityScores = qualityScores;
    }
}
File Line
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 427
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 428
listener.onEstimateProgressChange(PROSACPoint2DRobustEstimator.this, progress);
                }
            }

            @Override
            public double[] getQualityScores() {
                return qualityScores;
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }

    /**
     * Sets quality scores corresponding to each provided line.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }

        this.qualityScores = qualityScores;
    }
}
File Line
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 226
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 227
final AffineTransformation2DRobustEstimatorListener listener,
            final List<Line2D> inputLines, final List<Line2D> outputLines, final double[] qualityScores) {
        super(listener, inputLines, outputLines);

        if (qualityScores.length != inputLines.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched lines.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched lines.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched lines.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      lines.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched lines and quality
     * scores) are provided and a minimum of MINIMUM_SIZE lines are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputLines.size();
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 227
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 227
final AffineTransformation3DRobustEstimatorListener listener,
            final List<Plane> inputPlanes, final List<Plane> outputPlanes, final double[] qualityScores) {
        super(listener, inputPlanes, outputPlanes);

        if (qualityScores.length != inputPlanes.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched planes.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched planes.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched planes.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      planes.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched planes and quality
     * scores) are provided and a minimum of MINIMUM_SIZE lines are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPlanes.size();
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched planes correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 227
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 227
final AffineTransformation2DRobustEstimatorListener listener,
            final List<Point2D> inputPoints, final List<Point2D> outputPoints, final double[] qualityScores) {
        super(listener, inputPoints, outputPoints);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/LMedSEuclideanTransformation2DRobustEstimator.java 298
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 603
@Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return nonRobustEstimator.getMinimumPoints();
                    }

                    @SuppressWarnings("DuplicatedCode")
                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<EuclideanTransformation2D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final EuclideanTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSEuclideanTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACSphereRobustEstimator.java 161
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 279
com/irurueta/geometry/estimators/RANSACSphereRobustEstimator.java 161
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Sphere>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return SphereRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Sphere> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);
                final var point4 = points.get(samplesIndices[3]);

                try {
                    final var sphere = new Sphere(point1, point2, point3, point4);
                    solutions.add(sphere);
                } catch (final CoplanarPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Sphere currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACSphereRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 152
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 145
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 223
super(listener, planes, lines);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTLinePlaneCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/MSACConicRobustEstimator.java 167
com/irurueta/geometry/estimators/PROMedSConicRobustEstimator.java 326
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 286
com/irurueta/geometry/estimators/RANSACConicRobustEstimator.java 170
}

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return ConicRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Conic> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);
                final var point4 = points.get(samplesIndices[3]);
                final var point5 = points.get(samplesIndices[4]);

                try {
                    final var conic = new Conic(point1, point2, point3, point4, point5);
                    solutions.add(conic);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Conic currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACConicRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACDualConicRobustEstimator.java 171
com/irurueta/geometry/estimators/PROMedSDualConicRobustEstimator.java 327
com/irurueta/geometry/estimators/RANSACDualConicRobustEstimator.java 170
}

            @Override
            public int getTotalSamples() {
                return lines.size();
            }

            @Override
            public int getSubsetSize() {
                return DualConicRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<DualConic> solutions) {
                final var line1 = lines.get(samplesIndices[0]);
                final var line2 = lines.get(samplesIndices[1]);
                final var line3 = lines.get(samplesIndices[2]);
                final var line4 = lines.get(samplesIndices[3]);
                final var line5 = lines.get(samplesIndices[4]);

                try {
                    final var dualConic = new DualConic(line1, line2, line3, line4, line5);
                    solutions.add(dualConic);
                } catch (final CoincidentLinesException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final DualConic currentEstimation, final int i) {
                return residual(currentEstimation, lines.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACDualConicRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 227
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 227
final AffineTransformation3DRobustEstimatorListener listener, final List<Point3D> inputPoints,
            final List<Point3D> outputPoints, final double[] qualityScores) {
        super(listener, inputPoints, outputPoints);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
File Line
com/irurueta/geometry/Ellipse.java 1057
com/irurueta/geometry/Ellipse.java 1153
public Conic toConic() {
        center.normalize();
        // use inhomogeneous center coordinates
        final var xc = center.getInhomX();
        final var yc = center.getInhomY();

        final var sint = Math.sin(rotationAngle);
        final var cost = Math.cos(rotationAngle);

        final var a = semiMajorAxis;
        final var b = semiMinorAxis;

        final var xc2 = xc * xc;
        final var yc2 = yc * yc;

        final var sint2 = sint * sint;
        final var cost2 = cost * cost;

        final var a2 = a * a;
        final var b2 = b * b;

        final var aParam = a2 * sint2 + b2 * cost2;
        final var bParam = 2.0 * (b2 - a2) * sint * cost;
        final var cParam = a2 * cost2 + b2 * sint2;
        final var dParam = -2.0 * aParam * xc - bParam * yc;
        final var eParam = -bParam * xc - 2.0 * cParam * yc;
        final var fParam = aParam * xc2 + bParam * xc * yc + cParam * yc2 - a2 * b2;

        final var bConic = bParam / 2.0;
File Line
com/irurueta/geometry/estimators/LMedSConicRobustEstimator.java 202
com/irurueta/geometry/estimators/MSACConicRobustEstimator.java 169
com/irurueta/geometry/estimators/PROMedSConicRobustEstimator.java 328
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 288
com/irurueta/geometry/estimators/RANSACConicRobustEstimator.java 172
@Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return ConicRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Conic> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);
                final var point4 = points.get(samplesIndices[3]);
                final var point5 = points.get(samplesIndices[4]);

                try {
                    final var conic = new Conic(point1, point2, point3, point4, point5);
                    solutions.add(conic);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Conic currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return LMedSConicRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSDualConicRobustEstimator.java 202
com/irurueta/geometry/estimators/MSACDualConicRobustEstimator.java 173
com/irurueta/geometry/estimators/PROMedSDualConicRobustEstimator.java 329
com/irurueta/geometry/estimators/RANSACDualConicRobustEstimator.java 172
@Override
            public int getTotalSamples() {
                return lines.size();
            }

            @Override
            public int getSubsetSize() {
                return DualConicRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<DualConic> solutions) {
                final var line1 = lines.get(samplesIndices[0]);
                final var line2 = lines.get(samplesIndices[1]);
                final var line3 = lines.get(samplesIndices[2]);
                final var line4 = lines.get(samplesIndices[3]);
                final var line5 = lines.get(samplesIndices[4]);

                try {
                    final var dualConic = new DualConic(line1, line2, line3, line4, line5);
                    solutions.add(dualConic);
                } catch (final CoincidentLinesException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final DualConic currentEstimation, final int i) {
                return residual(currentEstimation, lines.get(i));
            }

            @Override
            public boolean isReady() {
                return LMedSDualConicRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/ProjectiveTransformation2D.java 340
com/irurueta/geometry/ProjectiveTransformation3D.java 339
public ProjectiveTransformation2D(final double scale, final Rotation2D rotation, final double[] translation,
                                      final double[] projectiveParameters) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }
        if (projectiveParameters.length != HOM_COORDS) {
            throw new IllegalArgumentException();
        }

        try {
            final var value = projectiveParameters[HOM_COORDS - 1];
            final var diag = new double[INHOM_COORDS];
            Arrays.fill(diag, scale);
            final var a = Matrix.diagonal(diag);
            a.multiply(rotation.asInhomogeneousMatrix());

            t = Matrix.identity(HOM_COORDS, HOM_COORDS);
            // set A
            t.setSubmatrix(0, 0, INHOM_COORDS - 1,
                    INHOM_COORDS - 1, a);
            // set translation
            t.setSubmatrix(0, HOM_COORDS - 1, translation.length - 1,
                    HOM_COORDS - 1, translation);
            t.multiplyByScalar(value);

            t.setSubmatrix(HOM_COORDS - 1, 0, HOM_COORDS - 1,
                    HOM_COORDS - 1, projectiveParameters);
        } catch (final WrongSizeException ignore) {
            // never happens
        }
        normalize();
    }

    /**
     * Creates transformation with provided parameters, rotation and
     * translation.
     *
     * @param params      Affine parameters including horizontal scaling, vertical
     *                    scaling and skewness.
     * @param rotation    a 2D rotation.
     * @param translation array indicating 2D translation using inhomogeneous
     *                    coordinates.
     * @throws NullPointerException     raised if provided parameters, rotation or
     *                                  translation is null.
     * @throws IllegalArgumentException raised if provided translation does not
     *                                  have length 2.
     */
    public ProjectiveTransformation2D(final AffineParameters2D params, final Rotation2D rotation,
File Line
com/irurueta/geometry/refiners/LineCorrespondenceAffineTransformation2DRefiner.java 93
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation2DRefiner.java 92
final List<Line2D> samples2, final double refinementStandardDeviation) {
        super(initialEstimation, keepCovariance, inliersData, samples1, samples2, refinementStandardDeviation);
    }

    /**
     * Refines provided initial estimation.
     * This method always sets a value into provided result instance regardless
     * of the fact that error has actually improved in LMSE terms or not.
     *
     * @param result instance where refined estimation will be stored.
     * @return true if result improves (error decreases) in LMSE terms respect
     * to initial estimation, false if no improvement has been achieved.
     * @throws NotReadyException if not enough input data has been provided.
     * @throws LockedException   if estimator is locked because refinement is
     *                           already in progress.
     * @throws RefinerException  if refinement fails for some reason (e.g. unable
     *                           to converge to a result).
     */
    @Override
    public boolean refine(final AffineTransformation2D result) throws NotReadyException, LockedException,
            RefinerException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        locked = true;

        if (listener != null) {
            listener.onRefineStart(this, initialEstimation);
        }

        final var initialTotalResidual = totalResidual(initialEstimation);

        try {
            final var initParams = new double[AffineTransformation2D.INHOM_COORDS * AffineTransformation2D.INHOM_COORDS
                    + AffineTransformation2D.NUM_TRANSLATION_COORDS];
            // copy values for A matrix
            System.arraycopy(initialEstimation.getA().getBuffer(), 0,
                    initParams, 0,
                    AffineTransformation2D.INHOM_COORDS * AffineTransformation2D.INHOM_COORDS);
            // copy values for translation
            System.arraycopy(initialEstimation.getTranslation(), 0,
                    initParams, AffineTransformation2D.INHOM_COORDS * AffineTransformation2D.INHOM_COORDS,
                    AffineTransformation2D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Line2D.LINE_NUMBER_PARAMS;
File Line
com/irurueta/geometry/refiners/PlaneCorrespondenceAffineTransformation3DRefiner.java 92
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation3DRefiner.java 92
final List<Plane> samples1, final List<Plane> samples2, final double refinementStandardDeviation) {
        super(initialEstimation, keepCovariance, inliersData, samples1, samples2, refinementStandardDeviation);
    }

    /**
     * Refines provided initial estimation.
     * This method always sets a value into provided result instance regardless
     * of the fact that error has actually improved in LMSE terms or not.
     *
     * @param result instance where refined estimation will be stored.
     * @return true if result improves (error decreases) in LMSE terms respect
     * to initial estimation, false if no improvement has been achieved.
     * @throws NotReadyException if not enough input data has been provided.
     * @throws LockedException   if estimator is locked because refinement is
     *                           already in progress.
     * @throws RefinerException  if refinement fails for some reason (e.g. unable
     *                           to converge to a result).
     */
    @Override
    public boolean refine(final AffineTransformation3D result) throws NotReadyException, LockedException,
            RefinerException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        locked = true;

        if (listener != null) {
            listener.onRefineStart(this, initialEstimation);
        }

        final var initialTotalResidual = totalResidual(initialEstimation);

        try {
            final var initParams = new double[AffineTransformation3D.INHOM_COORDS * AffineTransformation3D.INHOM_COORDS
                    + AffineTransformation3D.NUM_TRANSLATION_COORDS];
            // copy values for A matrix
            System.arraycopy(initialEstimation.getA().getBuffer(), 0, initParams, 0,
                    AffineTransformation3D.INHOM_COORDS * AffineTransformation3D.INHOM_COORDS);
            // copy values for translation
            System.arraycopy(initialEstimation.getTranslation(), 0, initParams,
                    AffineTransformation3D.INHOM_COORDS * AffineTransformation3D.INHOM_COORDS,
                    AffineTransformation3D.NUM_TRANSLATION_COORDS);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D points to compute residuals
            final var nDims = 2 * Plane.PLANE_NUMBER_PARAMS;
File Line
com/irurueta/geometry/Ellipse.java 1058
com/irurueta/geometry/Ellipse.java 1214
center.normalize();
        // use inhomogeneous center coordinates
        final var xc = center.getInhomX();
        final var yc = center.getInhomY();

        final var sint = Math.sin(rotationAngle);
        final var cost = Math.cos(rotationAngle);

        final var a = semiMajorAxis;
        final var b = semiMinorAxis;

        final var xc2 = xc * xc;
        final var yc2 = yc * yc;

        final var sint2 = sint * sint;
        final var cost2 = cost * cost;

        final var a2 = a * a;
        final var b2 = b * b;

        final var aParam = a2 * sint2 + b2 * cost2;
        final var bParam = 2.0 * (b2 - a2) * sint * cost;
        final var cParam = a2 * cost2 + b2 * sint2;
        final var dParam = -2.0 * aParam * xc - bParam * yc;
        final var eParam = -bParam * xc - 2.0 * cParam * yc;
        final var fParam = aParam * xc2 + bParam * xc * yc + cParam * yc2 - a2 * b2;

        final var bConic = bParam / 2.0;
File Line
com/irurueta/geometry/estimators/MSACEuclideanTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 542
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 347
}

                    @Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return nonRobustEstimator.getMinimumPoints();
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<EuclideanTransformation2D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final EuclideanTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return MSACEuclideanTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACEuclideanTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 542
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 602
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 346
}

                    @Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return nonRobustEstimator.getMinimumPoints();
                    }

                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<EuclideanTransformation3D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final EuclideanTransformation3D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return MSACEuclideanTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACMetricTransformation3DRobustEstimator.java 261
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 542
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 600
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 346
}

            @Override
            public int getTotalSamples() {
                return inputPoints.size();
            }

            @Override
            public int getSubsetSize() {
                return nonRobustEstimator.getMinimumPoints();
            }

            @Override
            public void estimatePreliminarSolutions(
                    final int[] samplesIndices, final List<MetricTransformation3D> solutions) {
                subsetInputPoints.clear();
                subsetOutputPoints.clear();
                for (final var samplesIndex : samplesIndices) {
                    subsetInputPoints.add(inputPoints.get(samplesIndex));
                    subsetOutputPoints.add(outputPoints.get(samplesIndex));
                }

                try {
                    nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                    solutions.add(nonRobustEstimator.estimate());
                } catch (final Exception e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final MetricTransformation3D currentEstimation, final int i) {
                final var inputPoint = inputPoints.get(i);
                final var outputPoint = outputPoints.get(i);

                // transform input point and store result in mTestPoint
                currentEstimation.transform(inputPoint, testPoint);

                return outputPoint.distanceTo(testPoint);
            }

            @Override
            public boolean isReady() {
                return MSACMetricTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PinholeCameraEstimator.java 760
com/irurueta/geometry/refiners/DecomposedLinePlaneCorrespondencePinholeCameraRefiner.java 169
com/irurueta/geometry/refiners/DecomposedPointCorrespondencePinholeCameraRefiner.java 171
}

    /**
     * Gets minimum suggestion weight. This weight is used to slowly draw
     * original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @return minimum suggestion weight.
     */
    public double getMinSuggestionWeight() {
        return minSuggestionWeight;
    }

    /**
     * Sets minimum suggestion weight. This weight is used to slowly draw
     * original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @param minSuggestionWeight minimum suggestion weight.
     * @throws LockedException if estimator is locked.
     */
    public void setMinSuggestionWeight(final double minSuggestionWeight) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.minSuggestionWeight = minSuggestionWeight;
    }

    /**
     * Gets maximum suggestion weight. This weight is used to slowly draw
     * original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @return maximum suggestion weight.
     */
    public double getMaxSuggestionWeight() {
        return maxSuggestionWeight;
    }

    /**
     * Sets maximum suggestion weight. This weight is used to slowly draw
     * original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @param maxSuggestionWeight maximum suggestion weight.
     * @throws LockedException if estimator is locked.
     */
    public void setMaxSuggestionWeight(final double maxSuggestionWeight) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.maxSuggestionWeight = maxSuggestionWeight;
    }

    /**
     * Sets minimum and maximum suggestion weights. Suggestion weight is used to
     * slowly draw original camera parameters into desired suggested values.
     * Suggestion weight slowly increases each time Levenberg-Marquardt is used
     * to find a solution so that the algorithm can converge into desired value.
     * The faster the weights are increased the less likely that suggested
     * values can be converged if they differ too much from the original ones.
     *
     * @param minSuggestionWeight minimum suggestion weight.
     * @param maxSuggestionWeight maximum suggestion weight.
     * @throws LockedException          if estimator is locked.
     * @throws IllegalArgumentException if minimum suggestion weight is greater
     *                                  or equal than maximum value.
     */
    public void setMinMaxSuggestionWeight(final double minSuggestionWeight, final double maxSuggestionWeight)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (minSuggestionWeight >= maxSuggestionWeight) {
            throw new IllegalArgumentException();
        }

        this.minSuggestionWeight = minSuggestionWeight;
        this.maxSuggestionWeight = maxSuggestionWeight;
    }

    /**
     * Gets step to increase suggestion weight. This weight is used to slowly
     * draw original camera parameters into desired suggested values. Suggestion
     * weight slowly increases each time Levenberg-Marquardt is used to find a
     * solution so that the algorithm can converge into desired value. The
     * faster the weights are increased the less likely that suggested values
     * can be converged if they differ too much from the original ones.
     *
     * @return step to increase suggestion weight.
     */
    public double getSuggestionWeightStep() {
        return suggestionWeightStep;
    }

    /**
     * Sets step to increase suggestion weight. This weight is used to slowly
     * draw original camera parameters into desired suggested values. Suggestion
     * weight slowly increases each time Levenberg-Marquardt is used to find a
     * solution so that the algorithm can converge into desired value. The
     * faster the weights are increased the less likely that suggested values
     * can be converged if they differ too much from the original ones.
     *
     * @param suggestionWeightStep step to increase suggestion weight.
     * @throws LockedException          if estimator is locked.
     * @throws IllegalArgumentException if provided step is negative or zero.
     */
    public void setSuggestionWeightStep(final double suggestionWeightStep) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (suggestionWeightStep <= 0.0) {
            throw new IllegalArgumentException();
        }

        this.suggestionWeightStep = suggestionWeightStep;
    }
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 393
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 393
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 392
final List<Point2D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 540
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 524
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 708
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 532
PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.this, progress);
                }
            }

            @Override
            public double[] getQualityScores() {
                return qualityScores;
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES) {
File Line
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 196
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 155
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 336
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 379
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 232
}

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences or 2D line/3D plane
     * correspondences found using the robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setLMSESolutionAllowed(false);
        nonRobustEstimator.setPointCorrespondencesNormalized(normalizeSubsetPointCorrespondences);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new LMedSRobustEstimator<>(new LMedSRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/PROMedSConicRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSLine2DRobustEstimator.java 190
final ConicRobustEstimatorListener listener, final List<Point2D> points, final double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a conic using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated conic found using the robust
     * estimator.
     *
     * @return a conic.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Conic estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 481
PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.this, progress);
                }
            }

            @Override
            public double[] getQualityScores() {
                return qualityScores;
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();

        // avoid setting a threshold too strict
        final var threshold = inliersData.getEstimatedThreshold();
        return Math.max(threshold, stopThreshold);
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
File Line
com/irurueta/geometry/estimators/PROMedSDualConicRobustEstimator.java 190
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 191
final DualConicRobustEstimatorListener listener, final List<Line2D> lines, final double[] qualityScores) {
        super(listener, lines);

        if (qualityScores.length != lines.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each provided line.
     * The larger the score value the better the quality of the sampled line.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided line.
     * The larger the score value the better the quality of the sampled line.
     *
     * @param qualityScores quality scores corresponding to each line.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE lines are available
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == lines.size();
    }

    /**
     * Estimates a dual conic using a robust estimator and the best set of 2D
     * lines that fit into the locus of the estimated dual conic found using the
     * robust estimator.
     *
     * @return a dual conic.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public DualConic estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSDualQuadricRobustEstimator.java 191
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 190
final DualQuadricRobustEstimatorListener listener, final List<Plane> planes, final double[] qualityScores) {
        super(listener, planes);

        if (qualityScores.length != planes.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each provided plane.
     * The larger the score value the better the quality of the sampled plane.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided plane.
     * The larger the score value the better the quality of the sampled plane.
     *
     * @param qualityScores quality scores corresponding to each plane.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 9 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the quadric estimation.
     * This is true when input data (i.e. 3D planes and quality scores) are
     * provided and a minimum of MINIMUM_SIZE planes are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
    }

    /**
     * Estimates a dual quadric using a robust estimator and the best set of 3D
     * planes that fit into the locus of the estimated dual quadric found using
     * the robust estimator.
     *
     * @return a dual quadric.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public DualQuadric estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 393
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 391
final List<Point3D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an Euclidean 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 391
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 392
final List<Point2D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the metric 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates a metric 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
File Line
com/irurueta/geometry/estimators/PROMedSPlaneRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSQuadricRobustEstimator.java 190
com/irurueta/geometry/estimators/PROMedSSphereRobustEstimator.java 190
final PlaneRobustEstimatorListener listener, final List<Point3D> points, final double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the 2D line estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a 3D plane using a robust estimator and the best set of 3D
     * points that pass through the estimated 3D plane (i.e. belong to its
     * locus).
     *
     * @return a 3D plane.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Plane estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 171
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 172
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 170
final CircleRobustEstimatorListener listener, final List<Point2D> points, final double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a circle using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated circle found using the robust
     * estimator.
     *
     * @return a circle.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Circle estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 170
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 173
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 170
final PlaneRobustEstimatorListener listener, final List<Point3D> points, final double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the 2D line estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a 3D plane using a robust estimator and the best set of 3D
     * points that pass through the estimated 3D plane (i.e. belong to its
     * locus).
     *
     * @return a 3D plane.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Plane estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/refiners/LineCorrespondenceAffineTransformation2DRefiner.java 212
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation2DRefiner.java 209
final var y = residual(transformation, inputLine, outputLine);
                    gradientEstimator.gradient(params, derivatives);

                    return y;
                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain estimated params
            final var params = fitter.getA();

            // update transformation

            // copy values for A matrix
            System.arraycopy(params, 0, result.getA().getBuffer(), 0,
                    AffineTransformation2D.INHOM_COORDS * AffineTransformation2D.INHOM_COORDS);
            // copy values for translation
            System.arraycopy(params, AffineTransformation2D.INHOM_COORDS * AffineTransformation2D.INHOM_COORDS,
                    result.getTranslation(), 0, AffineTransformation2D.NUM_TRANSLATION_COORDS);

            if (keepCovariance) {
                // keep covariance
                covariance = fitter.getCovar();
            }

            final var finalTotalResidual = totalResidual(result);
            final var errorDecreased = finalTotalResidual < initialTotalResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;

        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Computes the residual between the affine transformation and a pair of
     * matched lines.
     *
     * @param transformation a transformation.
     * @param inputLine      input 2D line.
     * @param outputLine     output 2D line.
     * @return residual.
     */
    private double residual(final AffineTransformation2D transformation, final Line2D inputLine,
File Line
com/irurueta/geometry/refiners/PlaneCorrespondenceAffineTransformation3DRefiner.java 211
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation3DRefiner.java 212
final var y = residual(transformation, inputPlane, outputPlane);
                    gradientEstimator.gradient(params, derivatives);

                    return y;
                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain estimated params
            final var params = fitter.getA();

            // update transformation

            // copy values for A matrix
            System.arraycopy(params, 0, result.getA().getBuffer(), 0,
                    AffineTransformation3D.INHOM_COORDS * AffineTransformation3D.INHOM_COORDS);
            // copy values for translation
            System.arraycopy(params, AffineTransformation3D.INHOM_COORDS * AffineTransformation3D.INHOM_COORDS,
                    result.getTranslation(), 0, AffineTransformation3D.NUM_TRANSLATION_COORDS);

            if (keepCovariance) {
                // keep covariance
                covariance = fitter.getCovar();
            }

            final var finalTotalResidual = totalResidual(result);
            final var errorDecreased = finalTotalResidual < initialTotalResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;

        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Computes the residual between the affine transformation and a pair of
     * matched planes.
     *
     * @param transformation a transformation.
     * @param inputPlane     input 3D plane.
     * @param outputPlane    output 3D plane.
     * @return residual.
     */
    private double residual(final AffineTransformation3D transformation, final Plane inputPlane,
File Line
com/irurueta/geometry/estimators/AffineTransformation2DRobustEstimator.java 212
com/irurueta/geometry/estimators/CircleRobustEstimator.java 210
com/irurueta/geometry/estimators/ConicRobustEstimator.java 226
com/irurueta/geometry/estimators/DualConicRobustEstimator.java 224
com/irurueta/geometry/estimators/DualQuadricRobustEstimator.java 223
com/irurueta/geometry/estimators/Line2DRobustEstimator.java 210
com/irurueta/geometry/estimators/PlaneRobustEstimator.java 210
com/irurueta/geometry/estimators/QuadricRobustEstimator.java 225
com/irurueta/geometry/estimators/SphereRobustEstimator.java 210
return mListener != null;
    }

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
File Line
com/irurueta/geometry/estimators/CircleRobustEstimator.java 211
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 486
com/irurueta/geometry/estimators/EuclideanTransformation3DRobustEstimator.java 485
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 483
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 483
com/irurueta/geometry/estimators/PinholeCameraRobustEstimator.java 833
}

    /**
     * Indicates if this instance is locked because estimation is being computed
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Returns list of points to be used to estimate a circle.
     * Provided list must have a size greater or equal than MINIMUM_SIZE.
     *
     * @return list of points to be used to estimate a circle.
     */
    public List<Point2D> getPoints() {
File Line
com/irurueta/geometry/estimators/ConicRobustEstimator.java 227
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 486
com/irurueta/geometry/estimators/EuclideanTransformation3DRobustEstimator.java 485
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 483
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 483
com/irurueta/geometry/estimators/PinholeCameraRobustEstimator.java 833
}

    /**
     * Indicates if this instance is locked because estimation is being computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Returns list of points to be used to estimate a conic.
     * Provided list must have a size greater or equal than MINIMUM_SIZE.
     *
     * @return list of points to be used to estimate a conic.
     */
    public List<Point2D> getPoints() {
File Line
com/irurueta/geometry/estimators/DualConicRobustEstimator.java 225
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 486
com/irurueta/geometry/estimators/EuclideanTransformation3DRobustEstimator.java 485
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 483
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 483
com/irurueta/geometry/estimators/PinholeCameraRobustEstimator.java 833
}

    /**
     * Indicates if this instance is locked because estimation is being computed
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates that
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Returns list of lines to be used to estimate a dual conic.
     * Provided list have a size greater or equal than MINIMUM_SIZE.
     *
     * @return list of lines to be used to estimate a dual conic.
     */
    public List<Line2D> getLines() {
File Line
com/irurueta/geometry/estimators/DualQuadricRobustEstimator.java 224
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 486
com/irurueta/geometry/estimators/EuclideanTransformation3DRobustEstimator.java 485
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 483
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 483
com/irurueta/geometry/estimators/PinholeCameraRobustEstimator.java 833
}

    /**
     * Indicates if this instance is locked because estimation is being computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates that
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Returns list of planes to be used to estimate a dual quadric.
     * Provided list have a size greater or equal than MINIMUM_SIZE.
     *
     * @return list of planes to be used to estimate a dual quadric.
     */
    public List<Plane> getPlanes() {
File Line
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 486
com/irurueta/geometry/estimators/Line2DRobustEstimator.java 211
com/irurueta/geometry/estimators/PlaneRobustEstimator.java 211
com/irurueta/geometry/estimators/QuadricRobustEstimator.java 226
com/irurueta/geometry/estimators/SphereRobustEstimator.java 211
}

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Gets data related to inliers found after estimation.
     *
     * @return data related to inliers found after estimation.
     */
    public InliersData getInliersData() {
File Line
com/irurueta/geometry/estimators/Line2DRobustEstimator.java 211
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 483
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 483
com/irurueta/geometry/estimators/PinholeCameraRobustEstimator.java 833
}

    /**
     * Indicates if this instance is locked because estimation is being computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Returns amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @return amount of progress variation before notifying a progress change
     * during estimation.
     */
    public float getProgressDelta() {
        return progressDelta;
    }

    /**
     * Sets amount of progress variation before notifying a progress change
     * during estimation.
     *
     * @param progressDelta amount of progress variation before notifying a
     *                      progress change during estimation.
     * @throws IllegalArgumentException if progress delta is less than zero or
     *                                  greater than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setProgressDelta(final float progressDelta) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
            throw new IllegalArgumentException();
        }
        this.progressDelta = progressDelta;
    }

    /**
     * Returns amount of confidence expressed as a value between 0.0 and 1.0
     * (which is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @return amount of confidence as a value between 0.0 and 1.0.
     */
    public double getConfidence() {
        return confidence;
    }

    /**
     * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
     * is equivalent to 100%). The amount of confidence indicates the
     * probability that the estimated result is correct. Usually this value will
     * be close to 1.0, but not exactly 1.0.
     *
     * @param confidence confidence to be set as a value between 0.0 and 1.0.
     * @throws IllegalArgumentException if provided value is not between 0.0 and
     *                                  1.0.
     * @throws LockedException          if this estimator is locked because an estimator
     *                                  is being computed.
     */
    public void setConfidence(final double confidence) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
            throw new IllegalArgumentException();
        }
        this.confidence = confidence;
    }

    /**
     * Returns maximum allowed number of iterations. If maximum allowed number
     * of iterations is achieved without converging to a result when calling
     * estimate(), a RobustEstimatorException will be raised.
     *
     * @return maximum allowed number of iterations.
     */
    public int getMaxIterations() {
        return maxIterations;
    }

    /**
     * Sets maximum allowed number of iterations. When the maximum number of
     * iterations is exceeded, result will not be available, however an
     * approximate result will be available for retrieval.
     *
     * @param maxIterations maximum allowed number of iterations to be set.
     * @throws IllegalArgumentException if provided value is less than 1.
     * @throws LockedException          if this estimator is locked because an estimation
     *                                  is being computed.
     */
    public void setMaxIterations(final int maxIterations) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (maxIterations < MIN_ITERATIONS) {
            throw new IllegalArgumentException();
        }
        this.maxIterations = maxIterations;
    }

    /**
     * Returns list of points to be used to estimate a 2D line.
     * Provided list must have a size greater or equal than MINIMUM_SIZE.
     *
     * @return list of points to be used to estimate a 2D line.
     */
    public List<Point2D> getPoints() {
File Line
com/irurueta/geometry/estimators/MSACDualConicRobustEstimator.java 166
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 284
com/irurueta/geometry/estimators/RANSACDualConicRobustEstimator.java 165
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<DualConic>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return lines.size();
            }

            @Override
            public int getSubsetSize() {
                return DualConicRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<DualConic> solutions) {
                final var line1 = lines.get(samplesIndices[0]);
                final var line2 = lines.get(samplesIndices[1]);
                final var line3 = lines.get(samplesIndices[2]);
                final var line4 = lines.get(samplesIndices[3]);
                final var line5 = lines.get(samplesIndices[4]);

                try {
                    final var dualConic = new DualConic(line1, line2, line3, line4, line5);
                    solutions.add(dualConic);
                } catch (final CoincidentLinesException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final DualConic currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 228
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 228
final List<Point2D> inputPoints, final List<Point2D> outputPoints, final double[] qualityScores) {
        super(listener, inputPoints, outputPoints);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 676
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 524
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 526
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 675
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 674
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 526
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 529
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 493
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 496
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 494
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 497
PROSACEuclideanTransformation2DRobustEstimator.this, progress);
                        }
                    }

                    @Override
                    public double[] getQualityScores() {
                        return qualityScores;
                    }
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < getMinimumPoints()) {
File Line
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 218
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 218
final EuclideanTransformation3DRobustEstimatorListener listener,
            final List<Point3D> inputPoints, final List<Point3D> outputPoints, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/AffineTransformation2D.java 510
com/irurueta/geometry/AffineTransformation3D.java 540
public void setParameters(final AffineParameters2D parameters) throws AlgebraException {
        final var decomposer = new RQDecomposer(a);
        decomposer.decompose();
        final var params = parameters.asMatrix();
        final var rotation = decomposer.getQ();

        params.multiply(rotation);
        a = params;
    }

    /**
     * Returns 2D translation assigned to this transformation as an array
     * expressed in inhomogeneous coordinates.
     *
     * @return 2D translation array.
     */
    public double[] getTranslation() {
        return translation;
    }

    /**
     * Sets 2D translation assigned to this transformation as an array expressed
     * in inhomogeneous coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void setTranslation(final double[] translation) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }

        this.translation = translation;
    }

    /**
     * Adds provided translation to current translation on this transformation.
     * Provided translation must be expressed as an array of inhomogeneous
     * coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void addTranslation(final double[] translation) {
        ArrayUtils.sum(this.translation, translation, this.translation);
    }

    /**
     * Returns current x coordinate translation assigned to this transformation.
     *
     * @return X coordinate translation.
     */
    public double getTranslationX() {
        return translation[0];
    }

    /**
     * Sets x coordinate translation to be made by this transformation.
     *
     * @param translationX X coordinate translation to be set.
     */
    public void setTranslationX(final double translationX) {
        translation[0] = translationX;
    }

    /**
     * Returns current y coordinate translation assigned to this transformation.
     *
     * @return Y coordinate translation.
     */
    public double getTranslationY() {
        return translation[1];
    }

    /**
     * Sets y coordinate translation to be made by this transformation.
     *
     * @param translationY Y coordinate translation to be set.
     */
    public void setTranslationY(final double translationY) {
        translation[1] = translationY;
    }

    /**
     * Sets x, y coordinates of translation to be made by this transformation.
     *
     * @param translationX translation x coordinate to be set.
     * @param translationY translation y coordinate to be set.
     */
    public void setTranslation(final double translationX, final double translationY) {
File Line
com/irurueta/geometry/estimators/LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 195
com/irurueta/geometry/estimators/MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 183
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 333
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 407
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 259
}

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTLinePlaneCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setLMSESolutionAllowed(false);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new LMedSRobustEstimator<>(new LMedSRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/PROMedSConicRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSPlaneRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSQuadricRobustEstimator.java 190
com/irurueta/geometry/estimators/PROMedSSphereRobustEstimator.java 190
final ConicRobustEstimatorListener listener, final List<Point2D> points, final double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a conic using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated conic found using the robust
     * estimator.
     *
     * @return a conic.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Conic estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSLine2DRobustEstimator.java 190
com/irurueta/geometry/estimators/PROMedSPlaneRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSQuadricRobustEstimator.java 190
com/irurueta/geometry/estimators/PROMedSSphereRobustEstimator.java 190
final Line2DRobustEstimatorListener listener, final List<Point2D> points, final double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 2 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the 2D line estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a 2D line using a robust estimator and the best set of 2D
     * points that pass through the estimated 2D line (i.e. belong to its locus).
     *
     * @return a 2D line.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Line2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 228
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 228
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 228
final List<Point2D> inputPoints, final List<Point2D> outputPoints, final double[] qualityScores) {
        super(listener, inputPoints, outputPoints);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 171
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 170
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 173
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 170
final CircleRobustEstimatorListener listener, final List<Point2D> points, final double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a circle using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated circle found using the robust
     * estimator.
     *
     * @return a circle.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Circle estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 172
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 170
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 173
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 170
final ConicRobustEstimatorListener listener, final List<Point2D> points, final double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a conic using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated conic found using the robust
     * estimator.
     *
     * @return a conic.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Conic estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 170
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 170
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 173
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 170
final Line2DRobustEstimatorListener listener, final List<Point2D> points, final double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 2 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the 2D line estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a 2D line using a robust estimator and the best set of 2D
     * points that pass through the estimated 2D line (i.e. belong to its locus)
     *
     * @return a 2D line.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Line2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/MSACCircleRobustEstimator.java 161
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 280
com/irurueta/geometry/estimators/RANSACCircleRobustEstimator.java 161
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Circle>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return CircleRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Circle> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);

                try {
                    final var circle = new Circle(point1, point2, point3);
                    solutions.add(circle);
                } catch (final ColinearPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Circle currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACCircleRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACPlaneRobustEstimator.java 161
com/irurueta/geometry/estimators/RANSACPlaneRobustEstimator.java 161
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Plane>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return PlaneRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Plane> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);

                try {
                    final var plane = new Plane(point1, point2, point3);
                    solutions.add(plane);
                } catch (final ColinearPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Plane currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACPlaneRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 219
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 216
final EuclideanTransformation2DRobustEstimatorListener listener,
            final List<Point2D> inputPoints, final List<Point2D> outputPoints, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/MSACSphereRobustEstimator.java 166
com/irurueta/geometry/estimators/PROMedSSphereRobustEstimator.java 325
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 284
com/irurueta/geometry/estimators/RANSACSphereRobustEstimator.java 166
}

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return SphereRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Sphere> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);
                final var point4 = points.get(samplesIndices[3]);

                try {
                    final var sphere = new Sphere(point1, point2, point3, point4);
                    solutions.add(sphere);
                } catch (final CoplanarPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Sphere currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACSphereRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 363
com/irurueta/geometry/estimators/RANSACPoint3DRobustEstimator.java 236
final var innerEstimator = new PROSACRobustEstimator<>(new PROSACRobustEstimatorListener<Point3D>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return Point3DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Point3D> solutions) {
                final var plane1 = planes.get(samplesIndices[0]);
                final var plane2 = planes.get(samplesIndices[1]);
                final var plane3 = planes.get(samplesIndices[2]);

                try {
                    final var point = plane1.getIntersection(plane2, plane3);
                    solutions.add(point);
                } catch (final NoIntersectionException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Point3D currentEstimation, final int i) {
                return residual(currentEstimation, planes.get(i));
            }

            @Override
            public boolean isReady() {
                return PROSACPoint3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSSphereRobustEstimator.java 202
com/irurueta/geometry/estimators/MSACSphereRobustEstimator.java 168
com/irurueta/geometry/estimators/PROMedSSphereRobustEstimator.java 327
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 286
com/irurueta/geometry/estimators/RANSACSphereRobustEstimator.java 168
@Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return SphereRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Sphere> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);
                final var point4 = points.get(samplesIndices[3]);

                try {
                    final var sphere = new Sphere(point1, point2, point3, point4);
                    solutions.add(sphere);
                } catch (final CoplanarPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Sphere currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return LMedSSphereRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 322
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 335
com/irurueta/geometry/estimators/LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 409
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 341
LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.this, progress);
                }
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            innerEstimator.setStopThreshold(stopThreshold);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.LMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (LMedSRobustEstimator.LMedSInliersData) getInliersData();

        // avoid setting a threshold too strict
        final var threshold = inliersData.getEstimatedThreshold();
        return Math.max(threshold, stopThreshold);
    }
}
File Line
com/irurueta/geometry/estimators/PROMedSCircleRobustEstimator.java 190
com/irurueta/geometry/estimators/PROMedSConicRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSLine2DRobustEstimator.java 190
com/irurueta/geometry/estimators/PROMedSPlaneRobustEstimator.java 189
com/irurueta/geometry/estimators/PROMedSQuadricRobustEstimator.java 190
com/irurueta/geometry/estimators/PROMedSSphereRobustEstimator.java 190
final CircleRobustEstimatorListener listener, final List<Point2D> points, double[] qualityScores) {
        super(listener, points);

        if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a circle using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated circle found using the robust
     * estimator.
     *
     * @return a circle.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Circle estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 142
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 141
public RANSACDLTPointCorrespondencePinholeCameraRobustEstimator(
            final PinholeCameraRobustEstimatorListener listener,
            final List<Point3D> points3D, final List<Point2D> points2D) {
        super(listener, points3D, points2D);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1142
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 979
}

    /**
     * Fills a row of constraint matrix for solution 2.
     *
     * @param row row to be filled.
     * @param c   matrix to be filled.
     * @param vai i-th control point in camera coordinates of last column of v
     *            (i.e. the null-space).
     * @param vaj j-th control point in camera coordinates of last column of v
     *            (i.e. the null-space).
     * @param vbi i-th control point in camera coordinates of second last column
     *            of v (i.e. the null-space).
     * @param vbj j-th control point in camera coordinates of second last column
     *            of v (i.e. the null-space).
     */
    private static void fillRowConstraintMatrixSolution2(
            final int row, final Matrix c, final Point3D vai, final Point3D vaj, final Point3D vbi, final Point3D vbj) {

        final var vaix = vai.getInhomX();
        final var vaiy = vai.getInhomY();
        final var vaiz = vai.getInhomZ();

        final var vajx = vaj.getInhomX();
        final var vajy = vaj.getInhomY();
        final var vajz = vaj.getInhomZ();

        final var vbix = vbi.getInhomX();
        final var vbiy = vbi.getInhomY();
        final var vbiz = vbi.getInhomZ();

        final var vbjx = vbj.getInhomX();
        final var vbjy = vbj.getInhomY();
        final var vbjz = vbj.getInhomZ();

        // 1st column
        c.setElementAt(row, 0, Math.pow(vaix - vajx, 2.0) + Math.pow(vaiy - vajy, 2.0)
File Line
com/irurueta/geometry/estimators/LMedSDualQuadricRobustEstimator.java 204
com/irurueta/geometry/estimators/MSACDualQuadricRobustEstimator.java 172
com/irurueta/geometry/estimators/PROMedSDualQuadricRobustEstimator.java 330
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 291
com/irurueta/geometry/estimators/RANSACDualQuadricRobustEstimator.java 172
@Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return DualQuadricRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<DualQuadric> solutions) {
                final var plane1 = planes.get(samplesIndices[0]);
                final var plane2 = planes.get(samplesIndices[1]);
                final var plane3 = planes.get(samplesIndices[2]);
                final var plane4 = planes.get(samplesIndices[3]);
                final var plane5 = planes.get(samplesIndices[4]);
                final var plane6 = planes.get(samplesIndices[5]);
                final var plane7 = planes.get(samplesIndices[6]);
                final var plane8 = planes.get(samplesIndices[7]);
                final var plane9 = planes.get(samplesIndices[8]);

                try {
                    final DualQuadric dualQuadric = new DualQuadric(plane1, plane2, plane3, plane4, plane5, plane6,
File Line
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 151
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 151
final AffineTransformation2DRobustEstimatorListener listener,
            final List<Line2D> inputLines, final List<Line2D> outputLines) {
        super(listener, inputLines, outputLines);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether lines are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, lines are considered equal, since sign changes are not taken
     * into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched lines are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether lines are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, lines are considered equal, since sign changes are not taken
     * into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched lines are inliers
     *                  or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 144
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 144
final AffineTransformation3DRobustEstimatorListener listener,
            final List<Point3D> inputPoints, final List<Point3D> outputPoints) {
        super(listener, inputPoints, outputPoints);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not when
     *                  testing possible estimation solutions.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/ProjectiveTransformation2D.java 425
com/irurueta/geometry/ProjectiveTransformation3D.java 424
public ProjectiveTransformation2D(final AffineParameters2D params, final Rotation2D rotation,
                                      final double[] translation, final double[] projectiveParameters) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }
        if (projectiveParameters.length != HOM_COORDS) {
            throw new IllegalArgumentException();
        }

        try {
            final var a = params.asMatrix();
            a.multiply(rotation.asInhomogeneousMatrix());
            t = Matrix.identity(HOM_COORDS, HOM_COORDS);
            // set A
            t.setSubmatrix(0, 0, INHOM_COORDS - 1,
                    INHOM_COORDS - 1, a);
            // set translation
            t.setSubmatrix(0, HOM_COORDS - 1, translation.length - 1,
                    HOM_COORDS - 1, translation);
            final var value = projectiveParameters[HOM_COORDS - 1];
            t.multiplyByScalar(value);

            t.setSubmatrix(HOM_COORDS - 1, 0, HOM_COORDS - 1,
                    HOM_COORDS - 1, projectiveParameters);
        } catch (final WrongSizeException ignore) {
            // never happens
        }
        normalize();
    }

    /**
     * Creates transformation by estimating its internal matrix by providing 4
     * corresponding original and transformed points.
     *
     * @param inputPoint1  1st input point.
     * @param inputPoint2  2nd input point.
     * @param inputPoint3  3rd input point.
     * @param inputPoint4  4th input point.
     * @param outputPoint1 1st transformed point corresponding to 1st input
     *                     point.
     * @param outputPoint2 2nd transformed point corresponding to 2nd input
     *                     point.
     * @param outputPoint3 3rd transformed point corresponding to 3rd input
     *                     point.
     * @param outputPoint4 4th transformed point corresponding to 4th input
     *                     point.
     * @throws CoincidentPointsException raised if transformation cannot be
     *                                   estimated for some reason (point configuration degeneracy, duplicate
     *                                   points or numerical instabilities).
     */
    public ProjectiveTransformation2D(
File Line
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 151
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 150
final AffineTransformation3DRobustEstimatorListener listener,
            final List<Plane> inputPlanes, final List<Plane> outputPlanes) {
        super(listener, inputPlanes, outputPlanes);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D lines correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 321
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 318
final EuclideanTransformation2DRobustEstimatorListener listener, final List<Point2D> inputPoints,
            final List<Point2D> outputPoints, final boolean weakMinimumSizeAllowed) {
        this(listener);
        this.weakMinimumSizeAllowed = weakMinimumSizeAllowed;
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Returns list of input points to be used to estimate an Euclidean 2D
     * transformation.
     * Each point in the list of input points must be matched with the
     * corresponding point in the list of output points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of input points to be used to estimate an Euclidean 2D
     * transformation.
     */
    public List<Point2D> getInputPoints() {
        return inputPoints;
    }

    /**
     * Returns list of output points to be used to estimate an Euclidean 2D
     * transformation.
     * Each point in the list of output points must be matched with the
     * corresponding point in the list of input points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of output points to be used to estimate an Euclidean 2D
     * transformation.
     */
    public List<Point2D> getOutputPoints() {
        return outputPoints;
    }

    /**
     * Sets list of points to be used to estimate an Euclidean 2D
     * transformation.
     * Points in the list located at the same position are considered to be
     * matched. Hence, both lists must have the same size, and their size must
     * be greater or equal than MINIMUM_SIZE.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     Euclidean 2D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     Euclidean 2D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     * @throws LockedException          if estimator is locked because a computation is
     *                                  already in progress.
     */
    public void setPoints(final List<Point2D> inputPoints, final List<Point2D> outputPoints) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points) are provided
     * and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    public boolean isReady() {
        return inputPoints != null && outputPoints != null && inputPoints.size() == outputPoints.size()
                && inputPoints.size() >= getMinimumPoints();
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     * This implementation always returns null.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    public double[] getQualityScores() {
        return null;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     * This implementation makes no action.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    public void setQualityScores(final double[] qualityScores) throws LockedException {
    }

    /**
     * Returns reference to listener to be notified of events such as when
     * estimation starts, ends or its progress significantly changes.
     *
     * @return listener to be notified of events.
     */
    public EuclideanTransformation2DRobustEstimatorListener getListener() {
File Line
com/irurueta/geometry/estimators/EuclideanTransformation3DRobustEstimator.java 320
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 318
final EuclideanTransformation3DRobustEstimatorListener listener,
            final List<Point3D> inputPoints, final List<Point3D> outputPoints, final boolean weakMinimumSizeAllowed) {
        this(listener);
        this.weakMinimumSizeAllowed = weakMinimumSizeAllowed;
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Returns list of input points to be used to estimate an Euclidean 3D
     * transformation.
     * Each point in the list of input points must be matched with the
     * corresponding point in the list of output points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of input points to be used to estimate an Euclidean 3D
     * transformation.
     */
    public List<Point3D> getInputPoints() {
        return inputPoints;
    }

    /**
     * Returns list of output points to be used to estimate an Euclidean 3D
     * transformation.
     * Each point in the list of output points must be matched with the
     * corresponding point in the list of input points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of output points to be used to estimate an Euclidean 3D
     * transformation.
     */
    public List<Point3D> getOutputPoints() {
        return outputPoints;
    }

    /**
     * Sets list of points to be used to estimate an Euclidean 3D
     * transformation.
     * Points in the list located at the same position are considered to be
     * matched. Hence, both lists must have the same size, and their size must
     * be greater or equal than MINIMUM_SIZE.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     Euclidean 3D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     Euclidean 3D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     * @throws LockedException          if estimator is locked because a computation is
     *                                  already in progress.
     */
    public void setPoints(final List<Point3D> inputPoints, final List<Point3D> outputPoints) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points) are provided
     * and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    public boolean isReady() {
        return inputPoints != null && outputPoints != null && inputPoints.size() == outputPoints.size()
                && inputPoints.size() >= getMinimumPoints();
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     * This implementation always returns null.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    public double[] getQualityScores() {
        return null;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     * This implementation makes no action.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    public void setQualityScores(final double[] qualityScores) throws LockedException {
    }

    /**
     * Returns reference to listener to be notified of events such as when
     * estimation starts, ends or its progress significantly changes.
     *
     * @return listener to be notified of events.
     */
    public EuclideanTransformation3DRobustEstimatorListener getListener() {
File Line
com/irurueta/geometry/DualQuadric.java 489
com/irurueta/geometry/Quadric.java 482
throw new CoincidentPlanesException();
            }

            // the right null-space of m contains the parameters a, b, c, d, e ,f
            // of the conic
            final var v = decomposer.getV();

            final var a = v.getElementAt(0, 9);
            final var b = v.getElementAt(1, 9);
            final var c = v.getElementAt(2, 9);
            final var d = v.getElementAt(3, 9);

            final var f = v.getElementAt(4, 9);
            final var e = v.getElementAt(5, 9);

            final var g = v.getElementAt(6, 9);
            final var h = v.getElementAt(7, 9);
            final var i = v.getElementAt(8, 9);
            final var j = v.getElementAt(9, 9);

            setParameters(a, b, c, d, e, f, g, h, i, j);
        } catch (final AlgebraException ex) {
            throw new CoincidentPlanesException(ex);
File Line
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 392
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 229
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the metric 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates a metric 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
    @Override
    public MetricTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1260
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 1273
invRotation.rotate(center, center);

        final var camera = new PinholeCamera(intrinsic, rotation, center);

        final var solution = new Solution();
        solution.controlCameraPoints = controlCameraPoints;
        solution.worldToCameraTransformation = worldToCameraTransformation;
        solution.camera = camera;

        // compute projection error
        solution.reprojectionError = reprojectionError(camera);

        return solution;
    }

    /**
     * Estimates world to camera transformation using estimated control points
     * in world and camera coordinates as a metric transformation.
     *
     * @param controlCameraPoints control points in camera coordinates.
     * @return metric transformation relating control points from world to
     * camera coordinates.
     * @throws LockedException           never happens.
     * @throws NotReadyException         never happens.
     * @throws CoincidentPointsException if a point degeneracy has occurred.
     */
    private MetricTransformation3D worldToCameraTransformationMetric(final List<Point3D> controlCameraPoints)
            throws LockedException, NotReadyException, CoincidentPointsException {
        final var estimator = new MetricTransformation3DEstimator(controlWorldPoints, controlCameraPoints, isPlanar);
        return estimator.estimate();
    }

    /**
     * Number of equations required to solve constraints for case 1 to 4.
     *
     * @param numControl number of control points.
     * @return number of constraint equations.
     */
    private static int numEquations(final int numControl) {
        var numEquations = 0;
        for (var i = 1; i < numControl; i++) {
            numEquations += i;
        }
        return numEquations;
    }

    /**
     * Right term of linearized system of equations to solve betas.
     *
     * @param controlWorldPoints control points in world coordinates.
     * @return right term.
     */
    private static double[] rhos(final List<Point3D> controlWorldPoints) {
        final var numControl = controlWorldPoints.size();
        final var numEquations = numEquations(numControl);
        final var rhos = new double[numEquations];
File Line
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 220
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 219
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 219
final List<Point2D> inputPoints, final List<Point2D> outputPoints, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 222
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 405
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 258
final var nonRobustEstimator = new UPnPPointCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setPlanarConfigurationAllowed(planarConfigurationAllowed);
        nonRobustEstimator.setNullspaceDimension2Allowed(nullspaceDimension2Allowed);
        nonRobustEstimator.setPlanarThreshold(planarThreshold);
        nonRobustEstimator.setSkewness(skewness);
        nonRobustEstimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
        nonRobustEstimator.setVerticalPrincipalPoint(verticalPrincipalPoint);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new LMedSRobustEstimator<>(new LMedSRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/MSACLine2DRobustEstimator.java 160
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 278
com/irurueta/geometry/estimators/RANSACLine2DRobustEstimator.java 161
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Line2D>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return Line2DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Line2D> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);

                try {
                    final var line = new Line2D(point1, point2, false);
                    solutions.add(line);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Line2D currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACLine2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 181
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 405
final var nonRobustEstimator = new UPnPPointCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setPlanarConfigurationAllowed(planarConfigurationAllowed);
        nonRobustEstimator.setNullspaceDimension2Allowed(nullspaceDimension2Allowed);
        nonRobustEstimator.setPlanarThreshold(planarThreshold);
        nonRobustEstimator.setSkewness(skewness);
        nonRobustEstimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
        nonRobustEstimator.setVerticalPrincipalPoint(verticalPrincipalPoint);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/PROMedSDualConicRobustEstimator.java 327
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 289
}

            @Override
            public int getTotalSamples() {
                return lines.size();
            }

            @Override
            public int getSubsetSize() {
                return DualConicRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<DualConic> solutions) {
                final var line1 = lines.get(samplesIndices[0]);
                final var line2 = lines.get(samplesIndices[1]);
                final var line3 = lines.get(samplesIndices[2]);
                final var line4 = lines.get(samplesIndices[3]);
                final var line5 = lines.get(samplesIndices[4]);

                try {
                    final var dualConic = new DualConic(line1, line2, line3, line4, line5);
                    solutions.add(dualConic);
                } catch (final CoincidentLinesException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final DualConic currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 361
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 405
final var nonRobustEstimator = new UPnPPointCorrespondencePinholeCameraEstimator();

        nonRobustEstimator.setPlanarConfigurationAllowed(planarConfigurationAllowed);
        nonRobustEstimator.setNullspaceDimension2Allowed(nullspaceDimension2Allowed);
        nonRobustEstimator.setPlanarThreshold(planarThreshold);
        nonRobustEstimator.setSkewness(skewness);
        nonRobustEstimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
        nonRobustEstimator.setVerticalPrincipalPoint(verticalPrincipalPoint);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 219
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 217
final List<Point3D> inputPoints, final List<Point3D> outputPoints, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 217
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 219
final List<Point2D> inputPoints, final List<Point2D> outputPoints, final boolean weakMinimumSizeAllowed) {
        super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a metric 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
File Line
com/irurueta/geometry/Polygon3D.java 189
com/irurueta/geometry/Polygon3D.java 688
while (iterator.hasNext()) {
            curPoint = iterator.next();

            final var inhomX1 = prevPoint.getInhomX();
            final var inhomY1 = prevPoint.getInhomY();
            final var inhomZ1 = prevPoint.getInhomZ();

            final var inhomX2 = curPoint.getInhomX();
            final var inhomY2 = curPoint.getInhomY();
            final var inhomZ2 = curPoint.getInhomZ();

            // compute cross product of ab = (prevPoint - origin) and
            // ac = (curPoint - origin)
            final var abX = inhomX1 - inhomX0;
            final var abY = inhomY1 - inhomY0;
            final var abZ = inhomZ1 - inhomZ0;

            final var acX = inhomX2 - inhomX0;
            final var acY = inhomY2 - inhomY0;
            final var acZ = inhomZ2 - inhomZ0;

            final var crossX = abY * acZ - abZ * acY;
            final var crossY = abZ * acX - abX * acZ;
            final var crossZ = abX * acY - abY * acX;

            avgX += crossX;
            avgY += crossY;
            avgZ += crossZ;

            prevPoint = curPoint;
        }
File Line
com/irurueta/geometry/estimators/LMedSDualConicRobustEstimator.java 202
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 291
@Override
            public int getTotalSamples() {
                return lines.size();
            }

            @Override
            public int getSubsetSize() {
                return DualConicRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<DualConic> solutions) {
                final var line1 = lines.get(samplesIndices[0]);
                final var line2 = lines.get(samplesIndices[1]);
                final var line3 = lines.get(samplesIndices[2]);
                final var line4 = lines.get(samplesIndices[3]);
                final var line5 = lines.get(samplesIndices[4]);

                try {
                    final var dualConic = new DualConic(line1, line2, line3, line4, line5);
                    solutions.add(dualConic);
                } catch (final CoincidentLinesException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final DualConic currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/LMedSMetricTransformation2DRobustEstimator.java 305
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 551
}

                    @SuppressWarnings("DuplicatedCode")
                    @Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<MetricTransformation2D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final MetricTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSMetricTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 224
com/irurueta/geometry/estimators/PROMedSDualQuadricRobustEstimator.java 192
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 191
super(listener, planes, lines);

        if (qualityScores.length != planes.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES (i.e. 4 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 394
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 229
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 394
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 229
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an Euclidean 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 394
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 229
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the metric 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates a metric 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public MetricTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/LineCorrespondenceAffineTransformation2DRobustEstimator.java 112
com/irurueta/geometry/estimators/LineCorrespondenceProjectiveTransformation2DRobustEstimator.java 112
final AffineTransformation2DRobustEstimatorListener listener,
            final List<Line2D> inputLines, final List<Line2D> outputLines) {
        super(listener);
        internalSetLines(inputLines, outputLines);
    }

    /**
     * Returns list of input lines to be used to estimate an affine 2D
     * transformation.
     * Each line in the list of input lines must be matched with the
     * corresponding line in the list of output lines located at the same
     * position. Hence, both input lines and output lines must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of input lines to be used to estimate an affine 2D
     * transformation.
     */
    public List<Line2D> getInputLines() {
        return inputLines;
    }

    /**
     * Returns list of output lines to be used to estimate an affine 2D
     * transformation.
     * Each line in the list of output lines must be matched with the
     * corresponding line in the list of input lines located at the same
     * position. Hence, both input lines and output lines must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of output lines to be used to estimate an affine 2D
     * transformation.
     */
    public List<Line2D> getOutputLines() {
        return outputLines;
    }

    /**
     * Sets lists of lines to be used to estimate an affine 2D transformation.
     * Lines in the list located at the same position are considered to be
     * matched. Hence, both lists must have the same size, and their size must
     * be greater or equal than MINIMUM_SIZE.
     *
     * @param inputLines  list of input lines to be used to estimate an affine
     *                    2D transformation.
     * @param outputLines list of output lines to be used to estimate an affine
     *                    2D transformation.
     * @throws IllegalArgumentException if provided lists of lines don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     * @throws LockedException          if estimator is locked because a computation is
     *                                  already in progress.
     */
    public final void setLines(final List<Line2D> inputLines, final List<Line2D> outputLines) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetLines(inputLines, outputLines);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched lines) are provided
     * and a minimum of MINIMUM_SIZE lines are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    public boolean isReady() {
        return inputLines != null && outputLines != null && inputLines.size() == outputLines.size()
                && inputLines.size() >= MINIMUM_SIZE;
    }

    /**
     * Returns quality scores corresponding to each pair of matched lines.
     * The larger the score value the better the quality of the matching.
     * This implementation always returns null.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    public double[] getQualityScores() {
        return null;
    }

    /**
     * Sets quality scores corresponding to each pair of matched lines.
     * The larger the score value the better the quality of the matching.
     * This implementation makes no action.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    public void setQualityScores(final double[] qualityScores) throws LockedException {
    }

    /**
     * Creates an affine 2D transformation estimator based on 2D line
     * correspondences and using provided robust estimator method.
     *
     * @param method method of a robust estimator algorithm to estimate the
     *               best affine 2D transformation.
     * @return an instance of affine 2D transformation estimator.
     */
    public static LineCorrespondenceAffineTransformation2DRobustEstimator create(final RobustEstimatorMethod method) {
File Line
com/irurueta/geometry/estimators/MSACCircleRobustEstimator.java 166
com/irurueta/geometry/estimators/PROMedSCircleRobustEstimator.java 325
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 285
com/irurueta/geometry/estimators/RANSACCircleRobustEstimator.java 166
}

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return CircleRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Circle> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);

                try {
                    final var circle = new Circle(point1, point2, point3);
                    solutions.add(circle);
                } catch (final ColinearPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Circle currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACCircleRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/MSACPoint2DRobustEstimator.java 161
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 363
com/irurueta/geometry/estimators/RANSACPoint2DRobustEstimator.java 236
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Point2D>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return lines.size();
            }

            @Override
            public int getSubsetSize() {
                return Point2DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Point2D> solutions) {
                final var line1 = lines.get(samplesIndices[0]);
                final var line2 = lines.get(samplesIndices[1]);

                try {
                    final var point = line1.getIntersection(line2);
                    solutions.add(point);
                } catch (final NoIntersectionException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Point2D currentEstimation, final int i) {
                return residual(currentEstimation, lines.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACPoint2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 650
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 491
PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.this, progress);
                }
            }

            @Override
            public double[] getQualityScores() {
                return qualityScores;
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 394
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 229
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an Euclidean 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 394
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 229
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates an Euclidean 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an Euclidean 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 392
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 229
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the metric 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates a metric 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
File Line
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 394
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 229
super(listener, inputPoints, outputPoints, weakMinimumSizeAllowed);

        if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the metric 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
    }

    /**
     * Estimates a metric 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/PointCorrespondenceAffineTransformation2DRobustEstimator.java 112
com/irurueta/geometry/estimators/PointCorrespondenceProjectiveTransformation2DRobustEstimator.java 112
final AffineTransformation2DRobustEstimatorListener listener,
            final List<Point2D> inputPoints, final List<Point2D> outputPoints) {
        super(listener);
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Returns list of input points to be used to estimate an affine 2D
     * transformation.
     * Each point in the list of input points must be matched with the
     * corresponding point in the list of output points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of input points to be used to estimate an affine 2D
     * transformation.
     */
    public List<Point2D> getInputPoints() {
        return inputPoints;
    }

    /**
     * Returns list of output points to be used to estimate an affine 2D
     * transformation.
     * Each point in the list of output points must be matched with the
     * corresponding point in the list of input points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of output points to be used to estimate an affine 2D
     * transformation.
     */
    public List<Point2D> getOutputPoints() {
        return outputPoints;
    }

    /**
     * Sets lists of points to be used to estimate an affine 2D transformation.
     * Points in the list located at the same position are considered to be
     * matched. Hence, both lists must have the same size, and their size must
     * be greater or equal than MINIMUM_SIZE.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     affine 2D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     affine 2D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     * @throws LockedException          if estimator is locked because a computation is
     *                                  already in progress.
     */
    public final void setPoints(final List<Point2D> inputPoints, final List<Point2D> outputPoints)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points) are provided
     * and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    public boolean isReady() {
        return inputPoints != null && outputPoints != null && inputPoints.size() == outputPoints.size()
                && inputPoints.size() >= MINIMUM_SIZE;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     * This implementation always returns null.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    public double[] getQualityScores() {
        return null;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     * This implementation makes no action.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    public void setQualityScores(final double[] qualityScores) throws LockedException {
    }

    /**
     * Creates an affine 2D transformation estimator based on 2D point
     * correspondences and using provided robust estimator method.
     *
     * @param method method of a robust estimator algorithm to estimate
     *               the best affine 2D transformation.
     * @return an instance of affine 2D transformation estimator.
     */
    public static PointCorrespondenceAffineTransformation2DRobustEstimator create(final RobustEstimatorMethod method) {
File Line
com/irurueta/geometry/estimators/PointCorrespondenceAffineTransformation3DRobustEstimator.java 112
com/irurueta/geometry/estimators/PointCorrespondenceProjectiveTransformation3DRobustEstimator.java 112
final AffineTransformation3DRobustEstimatorListener listener,
            final List<Point3D> inputPoints, final List<Point3D> outputPoints) {
        super(listener);
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Returns list of input points to be used to estimate an affine 3D
     * transformation.
     * Each point in the list of input points must be matched with the
     * corresponding point in the list of output points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of input points to be used to estimate an affine 3D
     * transformation.
     */
    public List<Point3D> getInputPoints() {
        return inputPoints;
    }

    /**
     * Returns list of output points to be used to estimate an affine 3D
     * transformation.
     * Each point in the list of output points must be matched with the
     * corresponding point in the list of input points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of output points to be used to estimate an affine 2D
     * transformation.
     */
    public List<Point3D> getOutputPoints() {
        return outputPoints;
    }

    /**
     * Sets lists of points to be used to estimate an affine 3D transformation.
     * Points in the list located at the same position are considered to be
     * matched. Hence, both lists must have the same size, and their size must
     * be greater or equal than MINIMUM_SIZE.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     affine 3D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     affine 3D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     * @throws LockedException          if estimator is locked because a computation is
     *                                  already in progress.
     */
    public final void setPoints(final List<Point3D> inputPoints, final List<Point3D> outputPoints)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Indicates if estimator is ready to start the affine 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points) are provided
     * and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    public boolean isReady() {
        return inputPoints != null && outputPoints != null && inputPoints.size() == outputPoints.size()
                && inputPoints.size() >= MINIMUM_SIZE;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     * This implementation always returns null.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    public double[] getQualityScores() {
        return null;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     * This implementation makes no action.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    public void setQualityScores(final double[] qualityScores) throws LockedException {
    }

    /**
     * Creates an affine 3D transformation estimator based on 2D point
     * correspondences and using provided robust estimator method.
     *
     * @param method method of a robust estimator algorithm to estimate
     *               the best affine 3D transformation.
     * @return an instance of affine 3D transformation estimator.
     */
    public static PointCorrespondenceAffineTransformation3DRobustEstimator create(final RobustEstimatorMethod method) {
File Line
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 143
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 144
final List<Point2D> inputPoints, final List<Point2D> outputPoints) {
        super(listener, inputPoints, outputPoints);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
File Line
com/irurueta/geometry/Polygon3D.java 1103
com/irurueta/geometry/Triangle3D.java 1263
private static double getAngleBetweenOrientations(final double[] orientation1, final double[] orientation2) {
        if (orientation1.length != INHOM_COORDS || orientation2.length != INHOM_COORDS) {
            throw new IllegalArgumentException();
        }

        final var x1 = orientation1[0];
        final var y1 = orientation1[1];
        final var z1 = orientation1[2];

        final var x2 = orientation2[0];
        final var y2 = orientation2[1];
        final var z2 = orientation2[2];

        final var norm1 = Math.sqrt(x1 * x1 + y1 * y1 + z1 * z1);
        final var norm2 = Math.sqrt(x2 * x2 + y2 * y2 + z2 * z2);

        final var dotProduct = (x1 * x2 + y1 * y2 + z1 * z2) / (norm1 * norm2);

        return Math.acos(dotProduct);
    }
}
File Line
com/irurueta/geometry/estimators/LMedSPlaneRobustEstimator.java 203
com/irurueta/geometry/estimators/MSACPlaneRobustEstimator.java 168
com/irurueta/geometry/estimators/RANSACPlaneRobustEstimator.java 168
@Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return PlaneRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Plane> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);

                try {
                    final var plane = new Plane(point1, point2, point3);
                    solutions.add(plane);
                } catch (final ColinearPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Plane currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return LMedSPlaneRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 324
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 368
com/irurueta/geometry/estimators/RANSACPoint3DRobustEstimator.java 241
}

            @Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return Point3DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Point3D> solutions) {
                final var plane1 = planes.get(samplesIndices[0]);
                final var plane2 = planes.get(samplesIndices[1]);
                final var plane3 = planes.get(samplesIndices[2]);

                try {
                    final var point = plane1.getIntersection(plane2, plane3);
                    solutions.add(point);
                } catch (final NoIntersectionException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Point3D currentEstimation, final int i) {
                return residual(currentEstimation, planes.get(i));
            }

            @Override
            public boolean isReady() {
                return PROMedSPoint3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 145
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 144
final List<Point3D> inputPoints, final List<Point3D> outputPoints) {
        super(listener, inputPoints, outputPoints);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not when
     *                  testing possible estimation solutions.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 144
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 145
final List<Point2D> inputPoints, List<Point2D> outputPoints) {
        super(listener, inputPoints, outputPoints);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a projective 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator
     *
     * @return a projective 2D transformation
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc)
     */
    @Override
    public ProjectiveTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/refiners/LineCorrespondenceProjectiveTransformation2DRefiner.java 95
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 93
final List<Line2D> samples1, final List<Line2D> samples2,
            final double refinementStandardDeviation) {
        super(initialEstimation, keepCovariance, inliersData, samples1, samples2, refinementStandardDeviation);
    }

    /**
     * Refines provided initial estimation.
     * This method always sets a value into provided result instance regardless
     * of the fact that error has actually improved in LMSE terms or not.
     *
     * @param result instance where refined estimation will be stored.
     * @return true if result improves (error decreases) in LMSE terms respect
     * to initial estimation, false if no improvement has been achieved.
     * @throws NotReadyException if not enough input data has been provided.
     * @throws LockedException   if estimator is locked because refinement is
     *                           already in progress.
     * @throws RefinerException  if refinement fails for some reason (e.g. unable
     *                           to converge to a result).
     */
    @Override
    public boolean refine(final ProjectiveTransformation2D result) throws NotReadyException, LockedException,
            RefinerException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        locked = true;

        if (listener != null) {
            listener.onRefineStart(this, initialEstimation);
        }

        initialEstimation.normalize();

        final var initialTotalResidual = totalResidual(initialEstimation);

        try {
            final var initParams = new double[
                    ProjectiveTransformation2D.HOM_COORDS * ProjectiveTransformation2D.HOM_COORDS];
            // copy values
            System.arraycopy(initialEstimation.getT().getBuffer(), 0, initParams, 0, initParams.length);

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain 2 sets of 2D lines to compute residuals
            final var nDims = 2 * Line2D.LINE_NUMBER_PARAMS;
File Line
com/irurueta/geometry/estimators/LinePlaneCorrespondencePinholeCameraRobustEstimator.java 631
com/irurueta/geometry/estimators/PointCorrespondencePinholeCameraRobustEstimator.java 1459
keepCovariance, inliersData, planes, lines, getRefinementStandardDeviation());

            try {
                refiner.setSuggestionErrorWeight(weight);

                refiner.setSuggestSkewnessValueEnabled(suggestSkewnessValueEnabled);
                refiner.setSuggestedSkewnessValue(suggestedSkewnessValue);
                refiner.setSuggestHorizontalFocalLengthEnabled(suggestHorizontalFocalLengthEnabled);
                refiner.setSuggestedHorizontalFocalLengthValue(suggestedHorizontalFocalLengthValue);
                refiner.setSuggestVerticalFocalLengthEnabled(suggestVerticalFocalLengthEnabled);
                refiner.setSuggestedVerticalFocalLengthValue(suggestedVerticalFocalLengthValue);
                refiner.setSuggestAspectRatioEnabled(suggestAspectRatioEnabled);
                refiner.setSuggestedAspectRatioValue(suggestedAspectRatioValue);
                refiner.setSuggestPrincipalPointEnabled(suggestPrincipalPointEnabled);
                refiner.setSuggestedPrincipalPointValue(suggestedPrincipalPointValue);
                refiner.setSuggestRotationEnabled(suggestRotationEnabled);
                refiner.setSuggestedRotationValue(suggestedRotationValue);
                refiner.setSuggestCenterEnabled(suggestCenterEnabled);
                refiner.setSuggestedCenterValue(suggestedCenterValue);

                final var result = new PinholeCamera();
                final var improved = refiner.refine(result);

                if (keepCovariance) {
                    // keep covariance
                    covariance = refiner.getCovariance();
                }

                return improved ? result : pinholeCamera;
            } catch (final Exception e) {
                // refinement failed, so we return input value
                return pinholeCamera;
            }
        } else {
            return pinholeCamera;
        }
    }
}
File Line
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 143
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 145
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 145
final List<Point2D> inputPoints, final List<Point2D> outputPoints) {
        super(listener, inputPoints, outputPoints);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers only
     * need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
File Line
com/irurueta/geometry/estimators/LMedSEuclideanTransformation2DRobustEstimator.java 309
com/irurueta/geometry/estimators/MSACEuclideanTransformation2DRobustEstimator.java 275
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 554
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 614
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 359
@Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<EuclideanTransformation2D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final EuclideanTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSEuclideanTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSMetricTransformation2DRobustEstimator.java 308
com/irurueta/geometry/estimators/MSACMetricTransformation2DRobustEstimator.java 273
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 554
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 613
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 357
@Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<MetricTransformation2D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final MetricTransformation2D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSMetricTransformation2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSMetricTransformation3DRobustEstimator.java 301
com/irurueta/geometry/estimators/MSACMetricTransformation3DRobustEstimator.java 273
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 554
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 612
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 358
@Override
                    public void estimatePreliminarSolutions(final int[] samplesIndices,
                                                            final List<MetricTransformation3D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(
                                    samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final MetricTransformation3D currentEstimation, final int i) {
                        final var inputPoint = inputPoints.get(i);
                        final var outputPoint = outputPoints.get(i);

                        // transform input point and store result in mTestPoint
                        currentEstimation.transform(inputPoint, testPoint);

                        return outputPoint.distanceTo(testPoint);
                    }

                    @Override
                    public boolean isReady() {
                        return LMedSMetricTransformation3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/LMedSEuclideanTransformation2DRobustEstimator.java 371
com/irurueta/geometry/estimators/LMedSEuclideanTransformation3DRobustEstimator.java 371
com/irurueta/geometry/estimators/LMedSMetricTransformation2DRobustEstimator.java 369
com/irurueta/geometry/estimators/LMedSMetricTransformation3DRobustEstimator.java 364
LMedSEuclideanTransformation2DRobustEstimator.this, progress);
                        }
                    }
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            innerEstimator.setStopThreshold(stopThreshold);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.LMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (LMedSRobustEstimator.LMedSInliersData) getInliersData();
        return inliersData.getEstimatedThreshold();
    }
}
File Line
com/irurueta/geometry/estimators/LMedSPoint2DRobustEstimator.java 260
com/irurueta/geometry/estimators/LMedSPoint3DRobustEstimator.java 261
listener.onEstimateProgressChange(LMedSPoint2DRobustEstimator.this, progress);
                }
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            innerEstimator.setStopThreshold(stopThreshold);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.LMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (LMedSRobustEstimator.LMedSInliersData) getInliersData();
        return inliersData.getEstimatedThreshold();
    }
}
File Line
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 391
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 376
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 455
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 382
RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.this, progress);
                }
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.RANSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }
}
File Line
com/irurueta/geometry/AffineParameters2D.java 283
com/irurueta/geometry/AffineParameters3D.java 383
scaleY = m.getElementAt(1, 1);
    }

    /**
     * Returns boolean indicating whether provided matrix is a valid matrix
     * to set affine parameters from.
     * Valid matrices need to be 2x2 and upper triangular.
     *
     * @param m A matrix to determine whether it is valid to set affine
     *          parameters from.
     * @return True if matrix is valid, false otherwise.
     */
    public static boolean isValidMatrix(final Matrix m) {
        return isValidMatrix(m, DEFAULT_VALID_THRESHOLD);
    }

    /**
     * Returns boolean indicating whether provided matrix is a valid matrix to
     * set affine parameters form.
     * Valid matrices need to be 2x2 and upper triangular up to provided
     * threshold. In Layman terms, a valid matrix lower triangular elements need
     * to be smaller or equal than provided threshold.
     *
     * @param m         A matrix to determine whether it is valid to set affine
     *                  parameters from.
     * @param threshold A threshold to determine whether provided matrix is
     *                  upper triangular. Matrix will be considered upper triangular if its lower
     *                  triangular elements are smaller or equal than provided threshold (without
     *                  taking into account the sign of the elements).
     * @return True if matrix is valid, false otherwise.
     * @throws IllegalArgumentException Raised if provided threshold is negative.
     */
    @SuppressWarnings("DuplicatedCode")
    public static boolean isValidMatrix(final Matrix m, final double threshold) {
        if (threshold < 0.0) {
            throw new IllegalArgumentException();
        }

        if (m.getRows() != INHOM_COORDS || m.getColumns() != INHOM_COORDS) {
            return false;
        }

        // check is upper triangular
        final var rows = m.getRows();
        final var cols = m.getColumns();

        for (var v = 0; v < cols; v++) {
            for (var u = 0; u < rows; u++) {
                if (u > v && Math.abs(m.getElementAt(u, v)) > threshold) {
                    return false;
                }
            }
        }

        return true;
    }
}
File Line
com/irurueta/geometry/estimators/LinePlaneCorrespondencePinholeCameraEstimator.java 222
com/irurueta/geometry/estimators/PointCorrespondencePinholeCameraEstimator.java 560
false, inliers, residuals, numPoints, planes, lines2D, 0.0);
            try {
                refiner.setMinSuggestionWeight(minSuggestionWeight);
                refiner.setMaxSuggestionWeight(maxSuggestionWeight);
                refiner.setSuggestionWeightStep(suggestionWeightStep);

                refiner.setSuggestSkewnessValueEnabled(suggestSkewnessValueEnabled);
                refiner.setSuggestedSkewnessValue(suggestedSkewnessValue);
                refiner.setSuggestHorizontalFocalLengthEnabled(suggestHorizontalFocalLengthEnabled);
                refiner.setSuggestedHorizontalFocalLengthValue(suggestedHorizontalFocalLengthValue);
                refiner.setSuggestVerticalFocalLengthEnabled(suggestVerticalFocalLengthEnabled);
                refiner.setSuggestedVerticalFocalLengthValue(suggestedVerticalFocalLengthValue);
                refiner.setSuggestAspectRatioEnabled(suggestAspectRatioEnabled);
                refiner.setSuggestedAspectRatioValue(suggestedAspectRatioValue);
                refiner.setSuggestPrincipalPointEnabled(suggestPrincipalPointEnabled);
                refiner.setSuggestedPrincipalPointValue(suggestedPrincipalPointValue);
                refiner.setSuggestRotationEnabled(suggestRotationEnabled);
                refiner.setSuggestedRotationValue(suggestedRotationValue);
                refiner.setSuggestCenterEnabled(suggestCenterEnabled);
                refiner.setSuggestedCenterValue(suggestedCenterValue);

                final var result = new PinholeCamera();
                final var improved = refiner.refine(result);

                return improved ? result : pinholeCamera;

            } catch (final Exception e) {
                return pinholeCamera;
            }
        } else {
            return pinholeCamera;
        }
    }
}
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 616
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 454
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 457
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 616
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 616
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 457
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 450
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 453
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 452
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 455
PROMedSEuclideanTransformation2DRobustEstimator.this, progress);
                        }
                    }

                    @Override
                    public double[] getQualityScores() {
                        return qualityScores;
                    }
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of such
     * threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 253
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 244
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 426
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 244
if (qualityScores.length != planes.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES (i.e. 4 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 426
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 427
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 426
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 207
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 208
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 246
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 247
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 246
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 246
if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 428
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 207
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 208
if (qualityScores.length != inputPoints.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or not
     *                  when testing possible estimation solutions.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == inputPoints.size();
File Line
com/irurueta/geometry/refiners/LineCorrespondenceProjectiveTransformation2DRefiner.java 200
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 198
gradientEstimator.gradient(params, derivatives);

                    return y;

                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain estimated params
            final var params = fitter.getA();

            // update transformation

            // copy values
            System.arraycopy(params, 0, result.getT().getBuffer(), 0, params.length);

            if (keepCovariance) {
                // keep covariance
                covariance = fitter.getCovar();
            }

            final var finalTotalResidual = totalResidual(result);
            final var errorDecreased = finalTotalResidual < initialTotalResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;

        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Computes the residual between the affine transformation and a pair of
     * matched lines.
     *
     * @param transformation a transformation.
     * @param inputLine      input 2D line.
     * @param outputLine     output 2D line.
     * @return residual.
     */
    private double residual(final ProjectiveTransformation2D transformation, final Line2D inputLine,
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 460
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 451
}

    /**
     * Indicates if provided point correspondences are normalized to increase
     * the accuracy of the estimation.
     *
     * @return true if input point correspondences will be normalized, false
     * otherwise.
     */
    @Override
    public boolean arePointCorrespondencesNormalized() {
        return false;
    }

    /**
     * Specifies whether provided point correspondences are normalized to
     * increase the accuracy of the estimation.
     *
     * @param normalize true if input point correspondences will be normalized,
     *                  false otherwise.
     * @throws LockedException if estimator is locked.
     */
    @Override
    public void setPointCorrespondencesNormalized(final boolean normalize) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
    }

    /**
     * Estimates a pinhole camera.
     *
     * @return estimated pinhole camera.
     * @throws LockedException                 if estimator is locked.
     * @throws NotReadyException               if input has not yet been provided.
     * @throws PinholeCameraEstimatorException if an error occurs during
     *                                         estimation, usually because input data is not valid.
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, PinholeCameraEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        try {
            locked = true;
            if (listener != null) {
                listener.onEstimateStart(this);
            }

            computeWorldControlPointsAndPointConfiguration();
            computeBarycentricCoordinates();
            buildM();
            solveNullspace();
        } catch (final AlgebraException e) {
            locked = false;
            throw new PinholeCameraEstimatorException(e);
        }


        solutions = new ArrayList<>();

        // general case
        try {
            generalSolution1();
        } catch (final GeometryException ignore) {
File Line
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 152
com/irurueta/geometry/estimators/RANSACPoint2DRobustEstimator.java 126
super(listener, planes, lines);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 223
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 144
super(listener, intrinsic, points3D, points2D);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences or 2D line/3D plane
     * correspondences found using the robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/MSACPlaneRobustEstimator.java 161
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 279
com/irurueta/geometry/estimators/RANSACPlaneRobustEstimator.java 161
final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Plane>() {

            @Override
            public double getThreshold() {
                return threshold;
            }

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return PlaneRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Plane> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);

                try {
                    final var plane = new Plane(point1, point2, point3);
                    solutions.add(plane);
                } catch (final ColinearPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Plane currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/PROMedSCircleRobustEstimator.java 385
com/irurueta/geometry/estimators/PROMedSConicRobustEstimator.java 388
com/irurueta/geometry/estimators/PROMedSDualConicRobustEstimator.java 389
com/irurueta/geometry/estimators/PROMedSDualQuadricRobustEstimator.java 395
com/irurueta/geometry/estimators/PROMedSLine2DRobustEstimator.java 383
com/irurueta/geometry/estimators/PROMedSPlaneRobustEstimator.java 384
com/irurueta/geometry/estimators/PROMedSQuadricRobustEstimator.java 394
com/irurueta/geometry/estimators/PROMedSSphereRobustEstimator.java 386
listener.onEstimateProgressChange(PROMedSCircleRobustEstimator.this, progress);
                }
            }

            @Override
            public double[] getQualityScores() {
                return qualityScores;
            }
        });

        try {
            locked = true;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            return innerEstimator.estimate();
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }

        this.qualityScores = qualityScores;
    }
}
File Line
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 420
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 375
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 377
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 419
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 420
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 377
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 344
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 348
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 346
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 351
RANSACEuclideanTransformation2DRobustEstimator.this, progress);
                        }
                    }
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.RANSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }
}
File Line
com/irurueta/geometry/estimators/RANSACPoint2DRobustEstimator.java 300
com/irurueta/geometry/estimators/RANSACPoint3DRobustEstimator.java 301
listener.onEstimateProgressChange(RANSACPoint2DRobustEstimator.this, progress);
                }
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.RANSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }
}
File Line
com/irurueta/geometry/refiners/LineCorrespondenceProjectiveTransformation2DRefiner.java 199
com/irurueta/geometry/refiners/PlaneCorrespondenceProjectiveTransformation3DRefiner.java 197
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 200
final var y = residual(transformation, inputLine, outputLine);
                    gradientEstimator.gradient(params, derivatives);

                    return y;

                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain estimated params
            final var params = fitter.getA();

            // update transformation

            // copy values
            System.arraycopy(params, 0, result.getT().getBuffer(), 0, params.length);

            if (keepCovariance) {
                // keep covariance
                covariance = fitter.getCovar();
            }

            final var finalTotalResidual = totalResidual(result);
            final var errorDecreased = finalTotalResidual < initialTotalResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;

        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Computes the residual between the affine transformation and a pair of
     * matched lines.
     *
     * @param transformation a transformation.
     * @param inputLine      input 2D line.
     * @param outputLine     output 2D line.
     * @return residual.
     */
    private double residual(final ProjectiveTransformation2D transformation, final Line2D inputLine,
File Line
com/irurueta/geometry/refiners/NonDecomposedLinePlaneCorrespondencePinholeCameraRefiner.java 105
com/irurueta/geometry/refiners/NonDecomposedPointCorrespondencePinholeCameraRefiner.java 105
final InliersData inliersData, final List<Plane> samples1, final List<Line2D> samples2,
            final double refinementStandardDeviation) {
        super(initialEstimation, keepCovariance, inliersData, samples1, samples2, refinementStandardDeviation);
    }

    /**
     * Gets suggestion error weight. This weight is applied to errors related to
     * suggested camera parameters during computation of projection residuals.
     *
     * @return suggestion error weight.
     */
    public double getSuggestionErrorWeight() {
        return suggestionErrorWeight;
    }

    /**
     * Sets suggestion error weight. This weight is applied to errors related to
     * suggested camera parameters during computation of projection residuals.
     *
     * @param suggestionErrorWeight suggestion error weight.
     * @throws LockedException if estimator is locked.
     */
    public void setSuggestionErrorWeight(final double suggestionErrorWeight) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.suggestionErrorWeight = suggestionErrorWeight;
    }

    /**
     * Refines provided initial estimation.
     * This method always sets a value into provided result instance regardless
     * of the fact that error has actually improved in LMSE terms or not.
     *
     * @param result instance where refined estimation will be stored.
     * @return true if result improves (decreases) in LMSE terms respect to
     * initial estimation, false if no improvement has been achieved.
     * @throws NotReadyException if not enough input data has been provided.
     * @throws LockedException   if estimator is locked because refinement is
     *                           already in progress.
     * @throws RefinerException  if refinement fails for some reason (e.g. unable
     *                           to converge to a result).
     */
    @Override
    public boolean refine(final PinholeCamera result) throws NotReadyException, LockedException, RefinerException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        locked = true;

        if (listener != null) {
            listener.onRefineStart(this, initialEstimation);
        }

        try {
            initialEstimation.normalize();

            // output values to be fitted/optimized will contain residuals
            final var y = new double[numInliers];
            // input values will contain line and plane to compute residuals
            final var nDims = Line2D.LINE_NUMBER_PARAMS + Plane.PLANE_NUMBER_PARAMS;
File Line
com/irurueta/geometry/estimators/EuclideanTransformation3DEstimator.java 385
com/irurueta/geometry/estimators/MetricTransformation3DEstimator.java 386
for (var i = 0; i < n; i++) {
                final var inputPoint = inputPoints.get(i);
                final var outputPoint = outputPoints.get(i);

                col.setElementAtIndex(0, inputPoint.getInhomX() - inCentroid.getElementAtIndex(0));
                col.setElementAtIndex(1, inputPoint.getInhomY() - inCentroid.getElementAtIndex(1));
                col.setElementAtIndex(2, inputPoint.getInhomZ() - inCentroid.getElementAtIndex(2));

                row.setElementAtIndex(0, outputPoint.getInhomX() - outCentroid.getElementAtIndex(0));
                row.setElementAtIndex(1, outputPoint.getInhomY() - outCentroid.getElementAtIndex(1));
                row.setElementAtIndex(2, outputPoint.getInhomZ() - outCentroid.getElementAtIndex(2));
File Line
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 152
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 221
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 220
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 153
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 153
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 220
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 153
com/irurueta/geometry/estimators/RANSACPoint2DRobustEstimator.java 126
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 146
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 145
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 146
super(listener, planes, lines);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
File Line
com/irurueta/geometry/estimators/LMedSEuclideanTransformation2DRobustEstimator.java 371
com/irurueta/geometry/estimators/LMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 311
com/irurueta/geometry/estimators/LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 313
com/irurueta/geometry/estimators/LMedSMetricTransformation2DRobustEstimator.java 369
com/irurueta/geometry/estimators/LMedSMetricTransformation3DRobustEstimator.java 364
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 313
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 316
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 303
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 305
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 305
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 308
LMedSEuclideanTransformation2DRobustEstimator.this, progress);
                        }
                    }
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            innerEstimator.setStopThreshold(stopThreshold);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.LMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (LMedSRobustEstimator.LMedSInliersData) getInliersData();
File Line
com/irurueta/geometry/estimators/MSACLine2DRobustEstimator.java 165
com/irurueta/geometry/estimators/PROMedSLine2DRobustEstimator.java 324
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 283
com/irurueta/geometry/estimators/RANSACLine2DRobustEstimator.java 166
}

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return Line2DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Line2D> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);

                try {
                    final var line = new Line2D(point1, point2, false);
                    solutions.add(line);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Line2D currentEstimation, final int i) {
                return residual(currentEstimation, points.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACLine2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 356
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 332
return super.isReady() && qualityScores != null && qualityScores.length == inputLines.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
                new PROSACRobustEstimatorListener<AffineTransformation2D>() {

                    // line to be reused when computing residuals
                    private final Line2D testLine = new Line2D();
File Line
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 356
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 331
return super.isReady() && qualityScores != null && qualityScores.length == inputLines.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a projective 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return a projective 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public ProjectiveTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
                new PROSACRobustEstimatorListener<ProjectiveTransformation2D>() {

                    // line to be reused when computing residuals
                    private final Line2D testLine = new Line2D();
File Line
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 356
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 333
return super.isReady() && qualityScores != null && qualityScores.length == inputPlanes.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D planes correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
                new PROSACRobustEstimatorListener<AffineTransformation3D>() {

                    // plane to be reused when computing residuals
                    private final Plane testPlane = new Plane();
File Line
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 356
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 331
return super.isReady() && qualityScores != null && qualityScores.length == inputPlanes.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a projective 3D transformation using a robust estimator and
     * the best set of matched 3D planes correspondences found using the robust
     * estimator.
     *
     * @return a projective 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public ProjectiveTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
                new PROSACRobustEstimatorListener<ProjectiveTransformation3D>() {

                    // plane to be reused when computing residuals
                    private final Plane testPlane = new Plane();
File Line
com/irurueta/geometry/refiners/PlaneCorrespondenceProjectiveTransformation3DRefiner.java 198
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 198
gradientEstimator.gradient(params, derivatives);

                    return y;
                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain estimated params
            final var params = fitter.getA();

            // update transformation

            // copy values for A matrix
            System.arraycopy(params, 0, result.getT().getBuffer(), 0, params.length);

            if (keepCovariance) {
                // keep covariance
                covariance = fitter.getCovar();
            }

            final var finalTotalResidual = totalResidual(result);
            final var errorDecreased = finalTotalResidual < initialTotalResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;

        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Computes the residual between the projective transformation and a pair of
     * matched planes.
     *
     * @param transformation a transformation.
     * @param inputPlane     input 3D plane.
     * @param outputPlane    output 3D plane.
     * @return residual.
     */
    private double residual(final ProjectiveTransformation3D transformation, final Plane inputPlane,
File Line
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 198
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 201
mGradientEstimator.gradient(params, derivatives);

                    return y;
                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain estimated params
            final var params = fitter.getA();

            // update transformation

            // copy values
            System.arraycopy(params, 0, result.getT().getBuffer(), 0, params.length);

            if (keepCovariance) {
                // keep covariance
                covariance = fitter.getCovar();
            }

            final var finalTotalResidual = totalResidual(result);
            final var errorDecreased = finalTotalResidual < initialTotalResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;

        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Computes the residual between the affine transformation and a pair of
     * matched points.
     *
     * @param transformation a transformation.
     * @param inputPoint     input 2D point.
     * @param outputPoint    output 2D point.
     * @return residual.
     */
    private double residual(final ProjectiveTransformation2D transformation, final Point2D inputPoint,
File Line
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 152
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 218
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 153
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 152
com/irurueta/geometry/estimators/RANSACPoint2DRobustEstimator.java 126
com/irurueta/geometry/estimators/RANSACPoint3DRobustEstimator.java 125
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 144
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 146
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 145
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 146
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 144
super(listener, planes, lines);
        threshold = DEFAULT_THRESHOLD;
        computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
        computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
File Line
com/irurueta/geometry/estimators/PROMedSCircleRobustEstimator.java 193
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 226
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSDualConicRobustEstimator.java 193
com/irurueta/geometry/estimators/PROMedSDualQuadricRobustEstimator.java 194
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 397
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 396
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 396
com/irurueta/geometry/estimators/PROMedSLine2DRobustEstimator.java 193
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 230
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 394
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 396
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPlaneRobustEstimator.java 192
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 194
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 193
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSQuadricRobustEstimator.java 193
com/irurueta/geometry/estimators/PROMedSSphereRobustEstimator.java 193
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 229
if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
File Line
com/irurueta/geometry/estimators/PROMedSConicRobustEstimator.java 192
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 226
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSDualConicRobustEstimator.java 193
com/irurueta/geometry/estimators/PROMedSDualQuadricRobustEstimator.java 194
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 397
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 396
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 396
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 230
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 394
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 396
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 194
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 193
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 231
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 229
if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        stopThreshold = DEFAULT_STOP_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * As in LMedS, the stop threshold can be used to prevent the PROMedS
     * algorithm iterating too many times in cases where samples have a very
     * similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
File Line
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 174
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 178
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 178
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 173
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 173
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 176
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 173
if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
File Line
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 175
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 178
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 178
if (qualityScores.length != points.size()) {
            throw new IllegalArgumentException();
        }

        threshold = DEFAULT_THRESHOLD;
        internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
File Line
com/irurueta/geometry/estimators/MSACPoint2DRobustEstimator.java 166
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 325
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 368
com/irurueta/geometry/estimators/RANSACPoint2DRobustEstimator.java 241
}

            @Override
            public int getTotalSamples() {
                return lines.size();
            }

            @Override
            public int getSubsetSize() {
                return Point2DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Point2D> solutions) {
                final var line1 = lines.get(samplesIndices[0]);
                final var line2 = lines.get(samplesIndices[1]);

                try {
                    final var point = line1.getIntersection(line2);
                    solutions.add(point);
                } catch (final NoIntersectionException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Point2D currentEstimation, final int i) {
                return residual(currentEstimation, lines.get(i));
            }

            @Override
            public boolean isReady() {
                return MSACPoint2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/EuclideanTransformation2DEstimator.java 454
com/irurueta/geometry/estimators/MetricTransformation2DEstimator.java 470
final var n = points.size();
        for (final var p : points) {
            x += p.getInhomX() / n;
            y += p.getInhomY() / n;
        }

        final var result = new Matrix(Point2D.POINT2D_INHOMOGENEOUS_COORDINATES_LENGTH, 1);
        result.setElementAtIndex(0, x);
        result.setElementAtIndex(1, y);
        return result;
    }

    /**
     * Internal method to set lists of points to be used to estimate an
     * Euclidean 2D transformation.
     * This method does not check whether estimator is locked or not.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     Euclidean 2D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     Euclidean 2D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than #getMinimumPoints.
     */
    private void internalSetPoints(final List<Point2D> inputPoints, final List<Point2D> outputPoints) {
        if (inputPoints.size() < getMinimumPoints()) {
            throw new IllegalArgumentException();
        }
        if (inputPoints.size() != outputPoints.size()) {
            throw new IllegalArgumentException();
        }
        this.inputPoints = inputPoints;
        this.outputPoints = outputPoints;
    }
}
File Line
com/irurueta/geometry/DualQuadric.java 290
com/irurueta/geometry/Quadric.java 265
final var invMatrix = com.irurueta.algebra.Utils.inverse(dualQuadricMatrix);

            final var a = invMatrix.getElementAt(0, 0);
            final var b = invMatrix.getElementAt(1, 1);
            final var c = invMatrix.getElementAt(2, 2);
            final var d = 0.5 * (invMatrix.getElementAt(0, 1) + invMatrix.getElementAt(1, 0));
            final var e = 0.5 * (invMatrix.getElementAt(2, 1) + invMatrix.getElementAt(1, 2));
            final var f = 0.5 * (invMatrix.getElementAt(2, 0) + invMatrix.getElementAt(0, 2));
            final var g = 0.5 * (invMatrix.getElementAt(3, 0) + invMatrix.getElementAt(0, 3));
            final double h = 0.5 * (invMatrix.getElementAt(3, 1)
File Line
com/irurueta/geometry/EuclideanTransformation2D.java 175
com/irurueta/geometry/EuclideanTransformation3D.java 179
public void addRotation(final Rotation2D rotation) {
        this.rotation.combine(rotation);
    }

    /**
     * Returns 2D translation assigned to this transformation as an array
     * expressed in inhomogeneous coordinates.
     *
     * @return 2D translation array.
     */
    public double[] getTranslation() {
        return translation;
    }

    /**
     * Sets 2D translation assigned to this transformation as an array expressed
     * in inhomogeneous coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException Raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void setTranslation(final double[] translation) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }

        this.translation = translation;
    }

    /**
     * Adds provided translation to current translation on this transformation.
     * Provided translation must be expressed as an array of inhomogeneous
     * coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException Raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void addTranslation(final double[] translation) {
        ArrayUtils.sum(this.translation, translation, this.translation);
    }

    /**
     * Returns current x coordinate translation assigned to this transformation.
     *
     * @return X coordinate translation.
     */
    public double getTranslationX() {
        return translation[0];
    }

    /**
     * Sets x coordinate translation to be made by this transformation.
     *
     * @param translationX X coordinate translation to be set.
     */
    public void setTranslationX(final double translationX) {
        translation[0] = translationX;
    }

    /**
     * Returns current y coordinate translation assigned to this transformation.
     *
     * @return Y coordinate translation.
     */
    public double getTranslationY() {
        return translation[1];
    }

    /**
     * Sets y coordinate translation to be made by this transformation.
     *
     * @param translationY Y coordinate translation to be set.
     */
    public void setTranslationY(final double translationY) {
        translation[1] = translationY;
    }

    /**
     * Sets x, y coordinates of translation to be made by this transformation.
     *
     * @param translationX translation x coordinate to be set.
     * @param translationY translation y coordinate to be set.
     */
    public void setTranslation(final double translationX, final double translationY) {
File Line
com/irurueta/geometry/RotationUtils.java 284
com/irurueta/geometry/RotationUtils.java 488
public static void rotationMatrixTimesVector(
            final Quaternion q, final double[] point, final double[] result, final Matrix jacobianQ,
            final Matrix jacobianP) {
        if (point.length != Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH) {
            throw new IllegalArgumentException("point must have length 3");
        }
        if (result.length != Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH) {
            throw new IllegalArgumentException("result must have length 3");
        }
        if (jacobianQ != null && (jacobianQ.getRows() != Quaternion.N_ANGLES
                || jacobianQ.getColumns() != Quaternion.N_PARAMS)) {
            throw new IllegalArgumentException("jacobian wrt of quaternion must be 3x4");
        }
        if (jacobianP != null && (jacobianP.getRows() != MatrixRotation3D.ROTATION3D_INHOM_MATRIX_ROWS
                || jacobianP.getColumns() != MatrixRotation3D.ROTATION3D_INHOM_MATRIX_COLS)) {
            throw new IllegalArgumentException("jacobian wrt of point must be 3x3");
        }

        try {
            final var r = new Matrix(MatrixRotation3D.ROTATION3D_INHOM_MATRIX_ROWS,
File Line
com/irurueta/geometry/AxisRotation3D.java 554
com/irurueta/geometry/MatrixRotation3D.java 865
if (!Rotation3D.isValidRotationMatrix(m, threshold)) {
            throw new InvalidRotationMatrixException();
        }
        if (Math.abs(m.getElementAt(3, 0)) > threshold
                || Math.abs(m.getElementAt(3, 1)) > threshold
                || Math.abs(m.getElementAt(3, 2)) > threshold
                || Math.abs(m.getElementAt(0, 3)) > threshold
                || Math.abs(m.getElementAt(1, 3)) > threshold
                || Math.abs(m.getElementAt(2, 3)) > threshold
                || Math.abs(m.getElementAt(3, 3) - 1.0) > threshold) {
            throw new InvalidRotationMatrixException();
        }
File Line
com/irurueta/geometry/estimators/EuclideanTransformation3DEstimator.java 358
com/irurueta/geometry/estimators/MetricTransformation3DEstimator.java 358
public void estimate(final EuclideanTransformation3D result) throws LockedException, NotReadyException,
            CoincidentPointsException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        try {
            locked = true;

            if (listener != null) {
                listener.onEstimateStart(this);
            }

            final var inCentroid = computeCentroid(inputPoints);
            final var outCentroid = computeCentroid(outputPoints);

            final var m = new Matrix(Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH,
                    Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH);

            final var n = inputPoints.size();
            final var col = new Matrix(Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH, 1);
            final var row = new Matrix(1, Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH);
            final var tmp = new Matrix(Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH,
                    Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH);
File Line
com/irurueta/geometry/BaseConic.java 248
com/irurueta/geometry/BaseQuadric.java 319
f = m.getElementAt(2, 2);
                normalized = false;
            }
        }
    }

    /**
     * This method sets the matrix used for describing a base conic.
     * This matrix must be 3x3 and symmetric.
     *
     * @param m 3x3 Matrix describing a base conic.
     * @throws IllegalArgumentException    Raised when the size of the matrix is
     *                                     not 3x3.
     * @throws NonSymmetricMatrixException Raised when the conic matrix is not
     *                                     symmetric.
     */
    public final void setParameters(final Matrix m) throws NonSymmetricMatrixException {
        setParameters(m, DEFAULT_SYMMETRIC_THRESHOLD);
    }

    /**
     * This method sets the A parameter of a base conic.
     *
     * @param a Parameter A of the given base conic.
     */
    public void setA(final double a) {
        this.a = a;
        normalized = false;
    }

    /**
     * This method sets the B parameter of a base conic.
     *
     * @param b Parameter B of the given base conic.
     */
    public void setB(final double b) {
        this.b = b;
        normalized = false;
    }

    /**
     * This method sets the C parameter of a base conic.
     *
     * @param c Parameter C of the given base conic.
     */
    public void setC(final double c) {
        this.c = c;
        normalized = false;
    }

    /**
     * This method sets the D parameter of a base conic.
     *
     * @param d Parameter D of the given base conic.
     */
    public void setD(final double d) {
        this.d = d;
        normalized = false;
    }

    /**
     * This method sets the E parameter of a base conic.
     *
     * @param e Parameter E of the given base conic.
     */
    public void setE(final double e) {
        this.e = e;
        normalized = false;
    }

    /**
     * This method sets the F parameter of a base conic.
     *
     * @param f Parameter F of the given base conic.
     */
    public void setF(final double f) {
        this.f = f;
        normalized = false;
    }

    /**
     * Returns the matrix that describes this base conic.
     *
     * @return 3x3 matrix describing this base conic.
     */
    public Matrix asMatrix() {
File Line
com/irurueta/geometry/estimators/MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 315
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 301
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 375
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 305
MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.this, progress);
                }
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }
}
File Line
com/irurueta/geometry/refiners/DecomposedLinePlaneCorrespondencePinholeCameraRefiner.java 370
com/irurueta/geometry/refiners/NonDecomposedLinePlaneCorrespondencePinholeCameraRefiner.java 186
line.normalize();
                    x.setElementAt(pos, 0, line.getA());
                    x.setElementAt(pos, 1, line.getB());
                    x.setElementAt(pos, 2, line.getC());
                    x.setElementAt(pos, 3, plane.getA());
                    x.setElementAt(pos, 4, plane.getB());
                    x.setElementAt(pos, 5, plane.getC());
                    x.setElementAt(pos, 6, plane.getD());

                    y[pos] = Math.pow(residuals[i], 2.0) + suggestionResidual;
                    pos++;
                }
            }

            final var evaluator = new LevenbergMarquardtMultiDimensionFunctionEvaluator() {

                private final Plane plane = new Plane();
File Line
com/irurueta/geometry/Polygon2D.java 551
com/irurueta/geometry/Polygon3D.java 583
line.normalize();

        // find the closest point to line
        line.closestPoint(point, pointInLine);
        // to increase accuracy
        pointInLine.normalize();

        if (pointInLine.isBetween(prevPoint, first)) {
            // closest point lies within segment of polygon boundary, so we
            // keep distance
            dist = point.distanceTo(pointInLine);
            if (dist < bestDist) {
                // a better point has been found
                bestDist = dist;
                result.setCoordinates(pointInLine);
                found = true;
            }
        }

        if (!found) {
            // no closest point was found on a segment belonging to polygon
            // boundary, so we search for the closest vertex
            iterator = vertices.iterator();
            while (iterator.hasNext()) {
                curPoint = iterator.next();
                dist = point.distanceTo(curPoint);
                if (dist < bestDist) {
                    // a better vertex has been found
                    bestDist = dist;
                    result.setCoordinates(curPoint);
                }
            }
        }
    }

    /**
     * Triangulates this polygon using this polygon's triangulator method.
     * A polygon only will be triangulated once when required or this method is
     * called.
     * This method will make no action if a polygon is already triangulated
     * unless it's vertices are reset.
     *
     * @throws TriangulatorException Raised if triangulation failed
     * @see #getTriangulatorMethod
     * @see #setTriangulatorMethod(TriangulatorMethod)
     */
    public void triangulate() throws TriangulatorException {
        if (!triangulated) {
            final var triangulator = Triangulator2D.create(triangulatorMethod);
File Line
com/irurueta/geometry/estimators/EuclideanTransformation2DEstimator.java 254
com/irurueta/geometry/estimators/EuclideanTransformation3DEstimator.java 254
com/irurueta/geometry/estimators/MetricTransformation2DEstimator.java 249
com/irurueta/geometry/estimators/MetricTransformation3DEstimator.java 254
public void setListener(final EuclideanTransformation2DEstimatorListener listener) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.listener = listener;
    }

    /**
     * Indicates whether estimation can start with only 2 points or not.
     *
     * @return true allows 2 points, false requires 3.
     */
    public boolean isWeakMinimumSizeAllowed() {
        return weakMinimumSizeAllowed;
    }

    /**
     * Specifies whether estimation can start with only 2 points or not.
     *
     * @param weakMinimumSizeAllowed true allows 2 points, false requires 3.
     * @throws LockedException if estimator is locked.
     */
    public void setWeakMinimumSizeAllowed(final boolean weakMinimumSizeAllowed) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.weakMinimumSizeAllowed = weakMinimumSizeAllowed;
    }

    /**
     * Required minimum number of point correspondences to start the estimation.
     * Can be either 2 or 3.
     *
     * @return minimum number of point correspondences.
     */
    public int getMinimumPoints() {
        return weakMinimumSizeAllowed ? WEAK_MINIMUM_SIZE : MINIMUM_SIZE;
    }

    /**
     * Indicates whether listener has been provided and is available for
     * retrieval.
     *
     * @return true if available, false otherwise.
     */
    public boolean isListenerAvailable() {
        return listener != null;
    }

    /**
     * Indicates if this instance is locked because estimation is being
     * computed.
     *
     * @return true if locked, false otherwise.
     */
    public boolean isLocked() {
        return locked;
    }

    /**
     * Indicates if estimator is ready to start the Euclidean 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points) are provided
     * and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    public boolean isReady() {
        return inputPoints != null && outputPoints != null && inputPoints.size() == outputPoints.size()
                && inputPoints.size() >= getMinimumPoints();
    }

    /**
     * Estimates an Euclidean 2D transformation using the list of matched input
     * and output 2D points.
     * A minimum of 3 matched non-coincident points is required. If more points
     * are provided an LMSE (Least Mean Squared Error) solution will be found.
     *
     * @return estimated euclidean 2D transformation.
     * @throws LockedException           if estimator is locked.
     * @throws NotReadyException         if not enough data has been provided.
     * @throws CoincidentPointsException raised if transformation cannot be
     *                                   estimated for some reason (point configuration degeneracy, duplicate
     *                                   points or numerical instabilities).
     */
    public EuclideanTransformation2D estimate() throws LockedException, NotReadyException, CoincidentPointsException {
File Line
com/irurueta/geometry/estimators/LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 222
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 224
com/irurueta/geometry/estimators/LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 297
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 229
nonRobustEstimator.setLMSESolutionAllowed(false);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new LMedSRobustEstimator<>(new LMedSRobustEstimatorListener<PinholeCamera>() {

            // 3D planes for a subset of samples
            private final List<Plane> subsetPlanes = new ArrayList<>();
File Line
com/irurueta/geometry/estimators/LMedSPoint3DRobustEstimator.java 202
com/irurueta/geometry/estimators/MSACPoint3DRobustEstimator.java 168
@Override
            public int getTotalSamples() {
                return planes.size();
            }

            @Override
            public int getSubsetSize() {
                return Point3DRobustEstimator.MINIMUM_SIZE;
            }

            @SuppressWarnings("DuplicatedCode")
            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Point3D> solutions) {
                final var plane1 = planes.get(samplesIndices[0]);
                final var plane2 = planes.get(samplesIndices[1]);
                final var plane3 = planes.get(samplesIndices[2]);

                try {
                    final var point = plane1.getIntersection(plane2, plane3);
                    solutions.add(point);
                } catch (final NoIntersectionException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Point3D currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/MetricTransformation2DEstimator.java 391
com/irurueta/geometry/estimators/MetricTransformation3DEstimator.java 396
row.setElementAtIndex(1, outputPoint.getInhomY() - outCentroid.getElementAtIndex(1));

                // compute covariances of input and output points
                inCov += Math.pow(Utils.normF(col), 2.0);

                col.multiply(row, tmp);
                m.add(tmp);
            }

            if (inCov == 0.0) {
                throw new CoincidentPointsException();
            }

            final var decomposer = new SingularValueDecomposer(m);
            decomposer.decompose();

            if (!weakMinimumSizeAllowed && decomposer.getNullity() > 0) {
                throw new CoincidentPointsException();
            }

            final var u = decomposer.getU();
            final var v = decomposer.getV();

            final var s = decomposer.getSingularValues();

            // rotation R = V*U^T
            final var r = v.multiplyAndReturnNew(u.transposeAndReturnNew());

            final var e = new double[]{1.0, 1.0};
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 260
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 183
internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES (i.e. 4 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
    }
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 547
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 393
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 457
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 384
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 531
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 393
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 457
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 384
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 715
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 393
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 457
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 384
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 539
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 393
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 457
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 384
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 135
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 135
public LMedSDLTPointCorrespondencePinholeCameraRobustEstimator(
            final PinholeCameraRobustEstimatorListener listener,
            final List<Point3D> points3D, final List<Point2D> points2D) {
        super(listener, points3D, points2D);
        stopThreshold = DEFAULT_STOP_THRESHOLD;
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences or 2D line/3D plane
     * correspondences found using the robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 115
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 116
public MSACDLTPointCorrespondencePinholeCameraRobustEstimator(
            final PinholeCameraRobustEstimatorListener listener,
            final List<Point3D> points3D, final List<Point2D> points2D) {
        super(listener, points3D, points2D);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences or 2D line/3D plane
     * correspondences found using the robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/refiners/EuclideanTransformation3DRefiner.java 265
com/irurueta/geometry/refiners/MetricTransformation3DRefiner.java 264
System.arraycopy(params, Quaternion.N_PARAMS, transformation.getTranslation(), 0,
                            EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2], point[3]);
                    outputPoint.setHomogeneousCoordinates(point[4], point[5], point[6], point[7]);
File Line
com/irurueta/geometry/ProjectiveTransformation3D.java 1514
com/irurueta/geometry/ProjectiveTransformation3D.java 1582
com/irurueta/geometry/ProjectiveTransformation3D.java 1650
com/irurueta/geometry/ProjectiveTransformation3D.java 1718
oW = outputPoint2.getHomW();

            oWiX = oW * iX;
            oWiY = oW * iY;
            oWiZ = oW * iZ;
            oWiW = oW * iW;

            oXiX = oX * iX;
            oXiY = oX * iY;
            oXiZ = oX * iZ;
            oXiW = oX * iW;

            oYiX = oY * iX;
            oYiY = oY * iY;
            oYiZ = oY * iZ;
            oYiW = oY * iW;

            oZiX = oZ * iX;
            oZiY = oZ * iY;
            oZiZ = oZ * iZ;
            oZiW = oZ * iW;

            tmp = oWiX * oWiX + oWiY * oWiY + oWiZ * oWiZ + oWiW * oWiW;
            norm = Math.sqrt(tmp + oXiX * oXiX + oXiY * oXiY + oXiZ * oXiZ + oXiW * oXiW);

            m.setElementAt(3, 0, oWiX / norm);
File Line
com/irurueta/geometry/ProjectiveTransformation3D.java 1929
com/irurueta/geometry/ProjectiveTransformation3D.java 1997
com/irurueta/geometry/ProjectiveTransformation3D.java 2065
com/irurueta/geometry/ProjectiveTransformation3D.java 2133
oD = outputPlane2.getD();

            oDiA = oD * iA;
            oDiB = oD * iB;
            oDiC = oD * iC;
            oDiD = oD * iD;

            oAiA = oA * iA;
            oAiB = oA * iB;
            oAiC = oA * iC;
            oAiD = oA * iD;

            oBiA = oB * iA;
            oBiB = oB * iB;
            oBiC = oB * iC;
            oBiD = oB * iD;

            oCiA = oC * iA;
            oCiB = oC * iB;
            oCiC = oC * iC;
            oCiD = oC * iD;

            tmp = oDiA * oDiA + oDiB * oDiB + oDiC * oDiC + oDiD * oDiD;
            norm = Math.sqrt(tmp + oAiA * oAiA + oAiB * oAiB + oAiC * oAiC + oAiD * oAiD);

            m.setElementAt(3, 0, oDiA / norm);
File Line
com/irurueta/geometry/estimators/MSACEuclideanTransformation2DRobustEstimator.java 337
com/irurueta/geometry/estimators/MSACEuclideanTransformation3DRobustEstimator.java 337
com/irurueta/geometry/estimators/MSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 297
com/irurueta/geometry/estimators/MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 302
com/irurueta/geometry/estimators/MSACMetricTransformation2DRobustEstimator.java 335
com/irurueta/geometry/estimators/MSACMetricTransformation3DRobustEstimator.java 335
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 299
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 305
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 266
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 268
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 270
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 273
MSACEuclideanTransformation2DRobustEstimator.this, progress);
                        }
                    }
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }
}
File Line
com/irurueta/geometry/estimators/MSACPoint2DRobustEstimator.java 225
com/irurueta/geometry/estimators/MSACPoint3DRobustEstimator.java 227
listener.onEstimateProgressChange(MSACPoint2DRobustEstimator.this, progress);
                }
            }
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }
}
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 358
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 330
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 512
return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTLinePlaneCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/refiners/NonDecomposedLinePlaneCorrespondencePinholeCameraRefiner.java 233
com/irurueta/geometry/refiners/NonDecomposedPointCorrespondencePinholeCameraRefiner.java 235
final var y = residualLevenbergMarquardt(pinholeCamera, line, plane, params, suggestionErrorWeight);
                    gradientEstimator.gradient(params, derivatives);

                    return y;
                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y, refinementStandardDeviation);

            fitter.fit();

            final var finalParams = fitter.getA();

            parametersToCamera(finalParams, result);

            if (keepCovariance) {
                covariance = fitter.getCovar();
            }

            final var finalResidual = residualPowell(result, finalParams, suggestionErrorWeight);
            final var errorDecreased = finalResidual < initResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;

        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }
}
File Line
com/irurueta/geometry/estimators/LMedSCircleRobustEstimator.java 203
com/irurueta/geometry/estimators/MSACCircleRobustEstimator.java 168
com/irurueta/geometry/estimators/PROMedSCircleRobustEstimator.java 327
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 287
com/irurueta/geometry/estimators/RANSACCircleRobustEstimator.java 168
@Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return CircleRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Circle> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);

                try {
                    final var circle = new Circle(point1, point2, point3);
                    solutions.add(circle);
                } catch (final ColinearPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Circle currentEstimation, int i) {
File Line
com/irurueta/geometry/estimators/LMedSPlaneRobustEstimator.java 203
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 286
@Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return PlaneRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Plane> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);

                try {
                    final var plane = new Plane(point1, point2, point3);
                    solutions.add(plane);
                } catch (final ColinearPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Plane currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 184
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 215
}

    /**
     * Returns threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given line.
     *
     * @return threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of algebraic error a possible
     * solution has on a given line.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided line.
     * The larger the score value the better the quality of the sampled line.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided line.
     * The larger the score value the better the quality of the sampled line.
     *
     * @param qualityScores quality scores corresponding to each line.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D lines and quality scores) are
     * provided and a minimum of MINIMUM_SIZE lines are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == lines.size();
    }
File Line
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 184
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 216
}

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given plane.
     *
     * @return threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of algebraic error a possible
     * solution has on a given plane.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided plane.
     * The larger the score value the better the quality of the sampled plane.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided plane.
     * The larger the score value the better the quality of the sampled plane.
     *
     * @param qualityScores quality scores corresponding to each plane.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 9 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the quadric estimation.
     * This is true when input data (i.e. 3D planes and quality scores) are
     * provided and a minimum of MINIMUM_SIZE planes are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
    }
File Line
com/irurueta/geometry/AffineTransformation2D.java 518
com/irurueta/geometry/EuclideanTransformation3D.java 181
}

    /**
     * Returns 2D translation assigned to this transformation as an array
     * expressed in inhomogeneous coordinates.
     *
     * @return 2D translation array.
     */
    public double[] getTranslation() {
        return translation;
    }

    /**
     * Sets 2D translation assigned to this transformation as an array expressed
     * in inhomogeneous coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void setTranslation(final double[] translation) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }

        this.translation = translation;
    }

    /**
     * Adds provided translation to current translation on this transformation.
     * Provided translation must be expressed as an array of inhomogeneous
     * coordinates.
     *
     * @param translation 2D translation array.
     * @throws IllegalArgumentException raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void addTranslation(final double[] translation) {
        ArrayUtils.sum(this.translation, translation, this.translation);
    }

    /**
     * Returns current x coordinate translation assigned to this transformation.
     *
     * @return X coordinate translation.
     */
    public double getTranslationX() {
        return translation[0];
    }

    /**
     * Sets x coordinate translation to be made by this transformation.
     *
     * @param translationX X coordinate translation to be set.
     */
    public void setTranslationX(final double translationX) {
        translation[0] = translationX;
    }

    /**
     * Returns current y coordinate translation assigned to this transformation.
     *
     * @return Y coordinate translation.
     */
    public double getTranslationY() {
        return translation[1];
    }

    /**
     * Sets y coordinate translation to be made by this transformation.
     *
     * @param translationY Y coordinate translation to be set.
     */
    public void setTranslationY(final double translationY) {
        translation[1] = translationY;
    }

    /**
     * Sets x, y coordinates of translation to be made by this transformation.
     *
     * @param translationX translation x coordinate to be set.
     * @param translationY translation y coordinate to be set.
     */
    public void setTranslation(final double translationX, final double translationY) {
File Line
com/irurueta/geometry/AffineTransformation3D.java 548
com/irurueta/geometry/EuclideanTransformation2D.java 177
}

    /**
     * Returns 3D translation assigned to this transformation as an array
     * expressed in inhomogeneous coordinates.
     *
     * @return 3D translation array.
     */
    public double[] getTranslation() {
        return translation;
    }

    /**
     * Sets 3D translation assigned to this transformation as an array expressed
     * in inhomogeneous coordinates.
     *
     * @param translation 3D translation array.
     * @throws IllegalArgumentException Raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void setTranslation(final double[] translation) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }

        this.translation = translation;
    }

    /**
     * Adds provided translation to current translation on this transformation.
     * Provided translation must be expressed as an array of inhomogeneous
     * coordinates.
     *
     * @param translation 3D translation array.
     * @throws IllegalArgumentException Raised if provided array does not have
     *                                  length equal to NUM_TRANSLATION_COORDS.
     */
    public void addTranslation(final double[] translation) {
        ArrayUtils.sum(this.translation, translation, this.translation);
    }

    /**
     * Returns current x coordinate translation assigned to this transformation.
     *
     * @return X coordinate translation.
     */
    public double getTranslationX() {
        return translation[0];
    }

    /**
     * Sets x coordinate translation to be made by this transformation.
     *
     * @param translationX X coordinate translation to be set.
     */
    public void setTranslationX(final double translationX) {
        translation[0] = translationX;
    }

    /**
     * Returns current y coordinate translation assigned to this transformation.
     *
     * @return Y coordinate translation.
     */
    public double getTranslationY() {
        return translation[1];
    }

    /**
     * Sets y coordinate translation to be made by this transformation.
     *
     * @param translationY Y coordinate translation to be set.
     */
    public void setTranslationY(final double translationY) {
        translation[1] = translationY;
    }

    /**
     * Returns current z coordinate translation assigned to this transformation.
     *
     * @return Z coordinate translation.
     */
    public double getTranslationZ() {
File Line
com/irurueta/geometry/ProjectiveTransformation2D.java 300
com/irurueta/geometry/ProjectiveTransformation3D.java 299
public ProjectiveTransformation2D(final double scale, final Rotation2D rotation, final double[] translation) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }

        try {
            final var diag = new double[INHOM_COORDS];
            Arrays.fill(diag, scale);
            final var a = Matrix.diagonal(diag);
            a.multiply(rotation.asInhomogeneousMatrix());

            t = Matrix.identity(HOM_COORDS, HOM_COORDS);
            // set A
            t.setSubmatrix(0, 0, INHOM_COORDS - 1,
                    INHOM_COORDS - 1, a);
            // set translation
            t.setSubmatrix(0, HOM_COORDS - 1, translation.length - 1,
                    HOM_COORDS - 1, translation);
        } catch (final WrongSizeException ignore) {
            // never happens
        }
        normalize();
    }

    /**
     * Creates transformation with provided scale, rotation and translation.
     *
     * @param scale                scale value. Values between 0.0 and 1.0 reduce objects,
     *                             values greater than 1.0 enlarge objects and negative values reverse
     *                             objects.
     * @param rotation             a 2D rotation.
     * @param translation          array indicating 2D translation using inhomogeneous
     *                             coordinates.
     * @param projectiveParameters array of length 3 containing projective
     *                             parameters.
     * @throws NullPointerException     raised if provided rotation or translation
     *                                  is null.
     * @throws IllegalArgumentException raised if provided translation does not
     *                                  have length 2 or if projective parameters array doesn't have length 3.
     */
    public ProjectiveTransformation2D(final double scale, final Rotation2D rotation, final double[] translation,
File Line
com/irurueta/geometry/estimators/LMedSPoint3DRobustEstimator.java 213
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 336
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPoint3DRobustEstimator.java 253
@Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Point3D> solutions) {
                final var plane1 = planes.get(samplesIndices[0]);
                final var plane2 = planes.get(samplesIndices[1]);
                final var plane3 = planes.get(samplesIndices[2]);

                try {
                    final var point = plane1.getIntersection(plane2, plane3);
                    solutions.add(point);
                } catch (final NoIntersectionException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Point3D currentEstimation, final int i) {
                return residual(currentEstimation, planes.get(i));
            }

            @Override
            public boolean isReady() {
                return LMedSPoint3DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 179
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 260
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 251
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 183
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 183
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 433
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 178
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 178
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 181
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 178
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 251
internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
File Line
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 180
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 260
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 251
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 433
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 251
internalSetQualityScores(qualityScores);
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
File Line
com/irurueta/geometry/estimators/MSACPlaneRobustEstimator.java 166
com/irurueta/geometry/estimators/PROMedSPlaneRobustEstimator.java 324
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 284
com/irurueta/geometry/estimators/RANSACPlaneRobustEstimator.java 166
}

            @Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return PlaneRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Plane> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);

                try {
                    final var plane = new Plane(point1, point2, point3);
                    solutions.add(plane);
                } catch (final ColinearPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Plane currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 358
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 330
return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
    }

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTLinePlaneCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 359
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 184
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 261
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTLinePlaneCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 331
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 211
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 261
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 513
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 211
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 184
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new EPnPPointCorrespondencePinholeCameraEstimator(intrinsic);
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 683
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 515
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 259
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an Euclidean 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public EuclideanTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 683
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 357
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 208
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 532
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 357
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 208
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 184
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a projective 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return a projective 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public ProjectiveTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 534
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 682
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 513
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 259
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a metric 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return a metric 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public MetricTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 681
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 357
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 208
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 186
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D planes correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 534
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 357
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 186
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a projective 3D transformation using a robust estimator and
     * the best set of matched 3D planes correspondences found using the robust
     * estimator.
     *
     * @return a projective 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public ProjectiveTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 537
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 434
com/irurueta/geometry/estimators/RANSACPoint2DRobustEstimator.java 302
com/irurueta/geometry/estimators/RANSACPoint3DRobustEstimator.java 303
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 435
com/irurueta/geometry/estimators/RANSACPoint2DRobustEstimator.java 302
com/irurueta/geometry/estimators/RANSACPoint3DRobustEstimator.java 303
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 333
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 208
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 501
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 334
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 208
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 186
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 504
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 332
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 208
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 184
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a projective 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return a projective 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public ProjectiveTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 502
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 332
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 186
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates a projective 3D transformation using a robust estimator and
     * the best set of matched 3D point correspondences found using the robust
     * estimator.
     *
     * @return a projective 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public ProjectiveTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROSACRobustEstimator<>(
File Line
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 505
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 423
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 378
com/irurueta/geometry/estimators/RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACMetricTransformation2DRobustEstimator.java 421
com/irurueta/geometry/estimators/RANSACMetricTransformation3DRobustEstimator.java 422
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 383
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 347
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 351
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 349
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 354
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
            innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
File Line
com/irurueta/geometry/refiners/PlaneCorrespondenceAffineTransformation3DRefiner.java 182
com/irurueta/geometry/refiners/PlaneCorrespondenceProjectiveTransformation3DRefiner.java 174
transformation.getTranslation(), 0, AffineTransformation3D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPlane, outputPlane);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPlane.setParameters(point[0], point[1], point[2], point[3]);
                    outputPlane.setParameters(point[4], point[5], point[6], point[7]);

                    // copy values for A matrix
                    System.arraycopy(params, 0, transformation.getA().getBuffer(), 0,
File Line
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation3DRefiner.java 182
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 177
transformation.getTranslation(), 0, AffineTransformation3D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);

                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2], point[3]);
                    outputPoint.setHomogeneousCoordinates(point[4], point[5], point[6], point[7]);

                    // copy values for A matrix
                    System.arraycopy(params, 0, transformation.getA().getBuffer(), 0,
File Line
com/irurueta/geometry/estimators/LMedSPlaneRobustEstimator.java 203
com/irurueta/geometry/estimators/PROMedSPlaneRobustEstimator.java 326
@Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return PlaneRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Plane> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);
                final var point3 = points.get(samplesIndices[2]);

                try {
                    final var plane = new Plane(point1, point2, point3);
                    solutions.add(plane);
                } catch (final ColinearPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Plane currentEstimation, final int i) {
File Line
com/irurueta/geometry/estimators/PlaneCorrespondenceAffineTransformation3DRobustEstimator.java 545
com/irurueta/geometry/estimators/PlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 555
final AffineTransformation3DRobustEstimatorListener listener, final List<Plane> inputPlanes,
            final List<Plane> outputPlanes, final double[] qualityScores) {
        return create(listener, inputPlanes, outputPlanes, qualityScores, DEFAULT_ROBUST_METHOD);
    }

    /**
     * Internal method to set lists of planes to be used to estimate an affine
     * 3D transformation.
     * This method does not check whether estimator is locked or not.
     *
     * @param inputPlanes  list of input planes to be used to estimate an affine
     *                     3D transformation.
     * @param outputPlanes list of output planes to be used to estimate an
     *                     affine 3D transformation.
     * @throws IllegalArgumentException if provided lists of lines don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     */
    private void internalSetPlanes(final List<Plane> inputPlanes, final List<Plane> outputPlanes) {
        if (inputPlanes.size() < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }
        if (inputPlanes.size() != outputPlanes.size()) {
            throw new IllegalArgumentException();
        }
        this.inputPlanes = inputPlanes;
        this.outputPlanes = outputPlanes;
    }

    /**
     * Computes residual by comparing two lines algebraically by doing the
     * dot product of their parameters.
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product was -1, then although their director vectors are opposed,
     * lines are considered equal, since sign changes are not taken into account.
     *
     * @param plane            originally sampled output plane.
     * @param transformedPlane estimated output plane obtained after using
     *                         estimated transformation.
     * @return computed residual.
     */
    @SuppressWarnings("DuplicatedCode")
    protected static double getResidual(final Plane plane, final Plane transformedPlane) {
File Line
com/irurueta/geometry/refiners/HomogeneousPoint2DRefiner.java 189
com/irurueta/geometry/refiners/HomogeneousPoint3DRefiner.java 190
com/irurueta/geometry/refiners/InhomogeneousPoint2DRefiner.java 190
com/irurueta/geometry/refiners/InhomogeneousPoint3DRefiner.java 191
final var y = residual(this.point, line);
                    gradientEstimator.gradient(params, derivatives);

                    return y;
                }
            };

            final var fitter = new LevenbergMarquardtMultiDimensionFitter(evaluator, x, y,
                    getRefinementStandardDeviation());

            fitter.fit();

            // obtain estimated params
            final var params = fitter.getA();

            // update point
            result.setCoordinates(params);

            if (keepCovariance) {
                // keep covariance
                covariance = fitter.getCovar();
            }

            final var finalTotalResidual = totalResidual(result);
            final var errorDecreased = finalTotalResidual < initialTotalResidual;

            if (listener != null) {
                listener.onRefineEnd(this, initialEstimation, result, errorDecreased);
            }

            return errorDecreased;
        } catch (final Exception e) {
            throw new RefinerException(e);
        } finally {
            locked = false;
        }
    }
}
File Line
com/irurueta/geometry/PinholeCamera.java 1943
com/irurueta/geometry/PinholeCamera.java 1958
final var y = -Utils.det(m);

            // build minor using columns 1, 2 and 4
            m.setElementAt(0, 0, internalMatrix.getElementAt(0, 0));
            m.setElementAt(1, 0, internalMatrix.getElementAt(1, 0));
            m.setElementAt(2, 0, internalMatrix.getElementAt(2, 0));

            m.setElementAt(0, 1, internalMatrix.getElementAt(0, 1));
            m.setElementAt(1, 1, internalMatrix.getElementAt(1, 1));
            m.setElementAt(2, 1, internalMatrix.getElementAt(2, 1));

            m.setElementAt(0, 2, internalMatrix.getElementAt(0, 3));
File Line
com/irurueta/geometry/estimators/LMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 138
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 137
super(listener, inputLines, outputLines);
        stopThreshold = DEFAULT_STOP_THRESHOLD;
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new LMedSRobustEstimator<>(
                new LMedSRobustEstimatorListener<AffineTransformation2D>() {

                    // line to be reused when computing residuals
                    private final Line2D testLine = new Line2D();
File Line
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 138
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 137
super(listener, inputPlanes, outputPlanes);
        stopThreshold = DEFAULT_STOP_THRESHOLD;
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Estimates an affine 3D transformation using a robust estimator and
     * the best set of matched 3D lines correspondences found using the robust
     * estimator.
     *
     * @return an affine 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @SuppressWarnings("DuplicatedCode")
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new LMedSRobustEstimator<>(
                new LMedSRobustEstimatorListener<AffineTransformation3D>() {

                    // plane to be reused when computing residuals
                    private final Plane testPlane = new Plane();
File Line
com/irurueta/geometry/estimators/PROMedSCircleRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 215
}

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a circle using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated circle found using the robust
     * estimator.
     *
     * @return a circle.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Circle estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<Circle>() {
File Line
com/irurueta/geometry/estimators/PROMedSConicRobustEstimator.java 256
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 216
}

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a conic using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated conic found using the robust
     * estimator.
     *
     * @return a conic.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Conic estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<Conic>() {
File Line
com/irurueta/geometry/estimators/PROMedSDualConicRobustEstimator.java 257
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 219
}

    /**
     * Returns quality scores corresponding to each provided line.
     * The larger the score value the better the quality of the sampled line.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided line.
     * The larger the score value the better the quality of the sampled line.
     *
     * @param qualityScores quality scores corresponding to each line.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE lines are available
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == lines.size();
    }

    /**
     * Estimates a dual conic using a robust estimator and the best set of 2D
     * lines that fit into the locus of the estimated dual conic found using the
     * robust estimator.
     *
     * @return a dual conic.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public DualConic estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<DualConic>() {
File Line
com/irurueta/geometry/estimators/PROMedSDualQuadricRobustEstimator.java 258
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 219
}

    /**
     * Returns quality scores corresponding to each provided plane.
     * The larger the score value the better the quality of the sampled plane.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided plane.
     * The larger the score value the better the quality of the sampled plane.
     *
     * @param qualityScores quality scores corresponding to each plane.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 9 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the quadric estimation.
     * This is true when input data (i.e. 3D planes and quality scores) are
     * provided and a minimum of MINIMUM_SIZE planes are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
    }

    /**
     * Estimates a dual quadric using a robust estimator and the best set of 3D
     * planes that fit into the locus of the estimated dual quadric found using
     * the robust estimator.
     *
     * @return a dual quadric.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public DualQuadric estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<DualQuadric>() {
File Line
com/irurueta/geometry/estimators/PROMedSLine2DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 214
}

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 2 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the 2D line estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a 2D line using a robust estimator and the best set of 2D
     * points that pass through the estimated 2D line (i.e. belong to its locus).
     *
     * @return a 2D line.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Line2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<Line2D>() {
File Line
com/irurueta/geometry/estimators/PROMedSPlaneRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 214
}

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the 2D line estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a 3D plane using a robust estimator and the best set of 3D
     * points that pass through the estimated 3D plane (i.e. belong to its
     * locus).
     *
     * @return a 3D plane.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Plane estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<Plane>() {
File Line
com/irurueta/geometry/estimators/PROMedSQuadricRobustEstimator.java 257
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 217
}

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the quadric estimation.
     * This is true when input data (i.e. 3D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a quadric using a robust estimator and the best set of 3D points
     * that fit into the locus of the estimated quadric found using the robust
     * estimator.
     *
     * @return a quadric.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Quadric estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<Quadric>() {
File Line
com/irurueta/geometry/estimators/PROMedSSphereRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 214
}

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
    }

    /**
     * Estimates a sphere using a robust estimator and the best set of 3D points
     * that fit into the locus of the estimated sphere found using the robust
     * estimator.
     *
     * @return a sphere.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Sphere estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new PROMedSRobustEstimator<>(new PROMedSRobustEstimatorListener<Sphere>() {
File Line
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 180
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 436
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 179
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 435
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 179
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 215
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 216
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 182
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 179
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 252
}

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
File Line
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 181
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 436
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 435
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 215
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 216
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 254
}

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided point.
     * The larger the score value the better the quality of the sampled point.
     *
     * @param qualityScores quality scores corresponding to each point.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D points and quality scores) are
     * provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points.size();
File Line
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 261
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 436
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 435
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 215
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 254
}

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES (i.e. 4 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
File Line
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 252
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 436
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 435
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 215
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 216
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 254
}

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or
     *                  not.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points3D.size();
File Line
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 184
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 436
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 435
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 216
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 254
}

    /**
     * Returns threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given line.
     *
     * @return threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of algebraic error a possible
     * solution has on a given line.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided line.
     * The larger the score value the better the quality of the sampled line.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided line.
     * The larger the score value the better the quality of the sampled line.
     *
     * @param qualityScores quality scores corresponding to each line.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 5 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the conic estimation.
     * This is true when input data (i.e. 2D lines and quality scores) are
     * provided and a minimum of MINIMUM_SIZE lines are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == lines.size();
File Line
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 184
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 436
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 435
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 215
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 254
}

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given plane.
     *
     * @return threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of algebraic error a possible
     * solution has on a given plane.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each provided plane.
     * The larger the score value the better the quality of the sampled plane.
     *
     * @return quality scores corresponding to each point.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each provided plane.
     * The larger the score value the better the quality of the sampled plane.
     *
     * @param qualityScores quality scores corresponding to each plane.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 9 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the quadric estimation.
     * This is true when input data (i.e. 3D planes and quality scores) are
     * provided and a minimum of MINIMUM_SIZE planes are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == planes.size();
File Line
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 436
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACMetricTransformation2DRobustEstimator.java 435
com/irurueta/geometry/estimators/PROSACMetricTransformation3DRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 263
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 215
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 216
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 255
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 254
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 254
}

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on a matched pair of points.
     *
     * @param threshold threshold to determine whether points are inliers or
     *                  not.
     * @throws IllegalArgumentException if provided values is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Returns quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    @Override
    public double[] getQualityScores() {
        return qualityScores;
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * The larger the score value the better the quality of the matching.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    @Override
    public void setQualityScores(final double[] qualityScores) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetQualityScores(qualityScores);
    }

    /**
     * Indicates if estimator is ready to start the affine 2D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched points and quality
     * scores) are provided and a minimum of MINIMUM_SIZE points are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    @Override
    public boolean isReady() {
        return super.isReady() && qualityScores != null && qualityScores.length == points3D.size();
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1599
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 1595
buffer = reducedAlpha.getBuffer();

            // copy reducedAlpha into the former components of i-th row of alphas
            alphas.setSubmatrix(i, 0, i, numControlMinusTwo, buffer);

            // The last component of each alpha for each point is computed so
            // that their sum is equal to one
            if (numControl == GENERAL_NUM_CONTROL_POINTS) {
                // general configuration
                alphas.setElementAt(i, numDimensions, 1.0 - buffer[0] - buffer[1] - buffer[2]);
            } else {
                // planar configuration
                alphas.setElementAt(i, numDimensions, 1.0 - buffer[0] - buffer[1]);
            }
        }
    }


    /**
     * Computes control points in world coordinates and determines whether
     * they are located in a planar configuration or not.
     * This method computes the centroid of provided 3D points and their
     * covariance.
     * Uses PCA by means of SVD decomposition of their covariance matrix in
     * order to find the principal directions of the cloud formed by the
     * collection of points and sets control points as the computed centroid
     * and points along the principal axes so that they form a basis that
     * can be used to express any 3D points into.
     * If the smallest singular value is close to zero in comparison to the
     * largest one, then it is assumed that 3D points are in a planar
     * configuration.
     * If a planar configuration is allowed, then only 3 control points are
     * computed along the plane using the centroid and two points on the
     * principal directions of such plane.
     * Otherwise, in general configuration, 4 control points are computed as
     * the centroid and 3 points along the principal axes of the cloud of 3D
     * points.
     *
     * @throws AlgebraException if something fails because of numerical
     *                          instabilities.
     */
    private void computeWorldControlPointsAndPointConfiguration() throws AlgebraException {
        final var centroid = Point3D.centroid(points3D);

        // covariance matrix elements, summed up here for speed
        var c11 = 0.0;
        var c12 = 0.0;
        var c13 = 0.0;
        var c22 = 0.0;
        var c23 = 0.0;
        var c33 = 0.0;
File Line
com/irurueta/geometry/estimators/MSACCircleRobustEstimator.java 98
com/irurueta/geometry/estimators/RANSACCircleRobustEstimator.java 98
public MSACCircleRobustEstimator(final CircleRobustEstimatorListener listener, final List<Point2D> points) {
        super(listener, points);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }


    /**
     * Estimates a circle using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated circle found using the robust
     * estimator.
     *
     * @return a circle.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Circle estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Circle>() {
File Line
com/irurueta/geometry/estimators/MSACConicRobustEstimator.java 100
com/irurueta/geometry/estimators/RANSACConicRobustEstimator.java 102
public MSACConicRobustEstimator(final ConicRobustEstimatorListener listener, final List<Point2D> points) {
        super(listener, points);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Estimates a conic using a robust estimator and the best set of 2D points
     * that fit into the locus of the estimated conic found using the robust
     * estimator.
     *
     * @return a conic.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Conic estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Conic>() {
File Line
com/irurueta/geometry/estimators/MSACDualConicRobustEstimator.java 102
com/irurueta/geometry/estimators/RANSACDualConicRobustEstimator.java 101
public MSACDualConicRobustEstimator(
            final DualConicRobustEstimatorListener listener, final List<Line2D> lines) {
        super(listener, lines);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given line.
     *
     * @return threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of algebraic error a possible
     * solution has on a given line.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }


    /**
     * Estimates a dual conic using a robust estimator and the best set of 2D
     * lines that fit into the locus of the estimated dual conic found using the
     * robust estimator.
     *
     * @return a dual conic.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public DualConic estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<DualConic>() {
File Line
com/irurueta/geometry/estimators/MSACDualQuadricRobustEstimator.java 101
com/irurueta/geometry/estimators/RANSACDualQuadricRobustEstimator.java 101
public MSACDualQuadricRobustEstimator(
            final DualQuadricRobustEstimatorListener listener, final List<Plane> planes) {
        super(listener, planes);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given plane.
     *
     * @return threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of algebraic error a possible
     * solution has on a given plane.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }


    /**
     * Estimates a dual quadric using a robust estimator and the best set of 3D
     * planes that fit into the locus of the estimated dual quadric found using
     * the robust estimator.
     *
     * @return a dual quadric.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public DualQuadric estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<DualQuadric>() {
File Line
com/irurueta/geometry/estimators/MSACLine2DRobustEstimator.java 98
com/irurueta/geometry/estimators/RANSACLine2DRobustEstimator.java 98
public MSACLine2DRobustEstimator(final Line2DRobustEstimatorListener listener, final List<Point2D> points) {
        super(listener, points);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }


    /**
     * Estimates a 2D line using a robust estimator and the best set of 2D
     * points that pass through the estimated 2D line (i.e. belong to its locus).
     *
     * @return a 2D line.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Line2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Line2D>() {
File Line
com/irurueta/geometry/estimators/MSACPlaneRobustEstimator.java 98
com/irurueta/geometry/estimators/RANSACPlaneRobustEstimator.java 98
public MSACPlaneRobustEstimator(final PlaneRobustEstimatorListener listener, final List<Point3D> points) {
        super(listener, points);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }


    /**
     * Estimates a 3D plane using a robust estimator and the best set of 3D
     * points that pass through the estimated 3D plane (i.e. belong to its
     * locus).
     *
     * @return a 3D plane.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Plane estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Plane>() {
File Line
com/irurueta/geometry/estimators/MSACSphereRobustEstimator.java 98
com/irurueta/geometry/estimators/RANSACSphereRobustEstimator.java 98
public MSACSphereRobustEstimator(final SphereRobustEstimatorListener listener, final List<Point3D> points) {
        super(listener, points);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * given point.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on
     * a given point.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }


    /**
     * Estimates a sphere using a robust estimator and the best set of 3D points
     * that fit into the locus of the estimated sphere found using the robust
     * estimator.
     *
     * @return a sphere.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public Sphere estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<Sphere>() {
File Line
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 331
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 211
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 184
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 261
}

    /**
     * Indicates whether inliers must be computed and kept.
     *
     * @return true if inliers must be computed and kept, false if inliers
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepInliersEnabled() {
        return computeAndKeepInliers;
    }

    /**
     * Specifies whether inliers must be computed and kept.
     *
     * @param computeAndKeepInliers true if inliers must be computed and kept,
     *                              false if inliers only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepInliers = computeAndKeepInliers;
    }

    /**
     * Indicates whether residuals must be computed and kept.
     *
     * @return true if residuals must be computed and kept, false if residuals
     * only need to be computed but not kept.
     */
    public boolean isComputeAndKeepResidualsEnabled() {
        return computeAndKeepResiduals;
    }

    /**
     * Specifies whether residuals must be computed and kept.
     *
     * @param computeAndKeepResiduals true if residuals must be computed and
     *                                kept, false if residuals only need to be computed but not kept.
     * @throws LockedException if estimator is locked.
     */
    public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        this.computeAndKeepResiduals = computeAndKeepResiduals;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D point correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using UPnP (Uncalibrated Perspective-n-Point)
        // algorithm
        final UPnPPointCorrespondencePinholeCameraEstimator nonRobustEstimator =
File Line
com/irurueta/geometry/AffineTransformation3D.java 1457
com/irurueta/geometry/AffineTransformation3D.java 1518
com/irurueta/geometry/AffineTransformation3D.java 1579
oD = outputPlane2.getD();

            oDiA = oD * iA;
            oDiB = oD * iB;
            oDiC = oD * iC;

            oAiA = oA * iA;
            oAiB = oA * iB;
            oAiC = oA * iC;
            oAiD = oA * iD;

            oBiA = oB * iA;
            oBiB = oB * iB;
            oBiC = oB * iC;
            oBiD = oB * iD;

            oCiA = oC * iA;
            oCiB = oC * iB;
            oCiC = oC * iC;
            oCiD = oC * iD;

            tmp = oDiA * oDiA + oDiB * oDiB + oDiC * oDiC;
            norm = Math.sqrt(tmp + oAiA * oAiA + oAiB * oAiB + oAiC * oAiC + oAiD * oAiD);

            m.setElementAt(3, 0, oDiA / norm);
File Line
com/irurueta/geometry/VanGoghTriangulator2D.java 145
com/irurueta/geometry/VanGoghTriangulator3D.java 280
triangle = new Triangle2D(verticesCopy.get(lastElement), verticesCopy.get(0),
                                verticesCopy.get(1));
                    } else {
                        triangle.setVertices(verticesCopy.get(lastElement), verticesCopy.get(0), verticesCopy.get(1));
                    }
                } else if (i == lastElement) {
                    triangle.setVertices(verticesCopy.get(lastElement - 1), verticesCopy.get(lastElement),
                            verticesCopy.get(0));
                } else {
                    triangle.setVertices(verticesCopy.get(i - 1), verticesCopy.get(i), verticesCopy.get(i + 1));
                }
File Line
com/irurueta/geometry/estimators/LineCorrespondenceAffineTransformation2DRobustEstimator.java 542
com/irurueta/geometry/estimators/LineCorrespondenceProjectiveTransformation2DRobustEstimator.java 548
final AffineTransformation2DRobustEstimatorListener listener,
            final List<Line2D> inputLines, final List<Line2D> outputLines, final double[] qualityScores) {
        return create(listener, inputLines, outputLines, qualityScores, DEFAULT_ROBUST_METHOD);
    }

    /**
     * Internal method to set lists of lines to be used to estimate an affine
     * 2D transformation.
     * This method does not check whether estimator is locked or not.
     *
     * @param inputLines  list of input lines to be used to estimate an affine
     *                    2D transformation.
     * @param outputLines list of output lines to be used to estimate an affine
     *                    2D transformation.
     * @throws IllegalArgumentException if provided lists of lines don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     */
    private void internalSetLines(final List<Line2D> inputLines, final List<Line2D> outputLines) {
        if (inputLines.size() < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }
        if (inputLines.size() != outputLines.size()) {
            throw new IllegalArgumentException();
        }
        this.inputLines = inputLines;
        this.outputLines = outputLines;
    }

    /**
     * Computes residual by comparing two lines algebraically by doing the
     * dot product of their parameters.
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product was -1, then although their director vectors are opposed,
     * lines are considered equal, since sign changes are not taken into account.
     *
     * @param line            originally sampled output line.
     * @param transformedLine estimated output line obtained after using
     *                        estimated transformation.
     * @return computed residual.
     */
    protected static double getResidual(final Line2D line, final Line2D transformedLine) {
File Line
com/irurueta/geometry/refiners/EuclideanTransformation2DRefiner.java 239
com/irurueta/geometry/refiners/MetricTransformation2DRefiner.java 242
System.arraycopy(params, 1, transformation.getTranslation(), 0,
                            EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2]);
                    outputPoint.setHomogeneousCoordinates(point[3], point[4], point[5]);

                    // copy values
                    transformation.getRotation().setTheta(params[0]);
File Line
com/irurueta/geometry/estimators/LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 222
com/irurueta/geometry/estimators/MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 210
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 183
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 258
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 188
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 360
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 364
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 534
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 368
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 434
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 407
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 591
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 413
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 286
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 260
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 339
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 265
nonRobustEstimator.setLMSESolutionAllowed(false);

        // suggestions
        nonRobustEstimator.setSuggestSkewnessValueEnabled(isSuggestSkewnessValueEnabled());
        nonRobustEstimator.setSuggestedSkewnessValue(getSuggestedSkewnessValue());
        nonRobustEstimator.setSuggestHorizontalFocalLengthEnabled(isSuggestHorizontalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedHorizontalFocalLengthValue(getSuggestedHorizontalFocalLengthValue());
        nonRobustEstimator.setSuggestVerticalFocalLengthEnabled(isSuggestVerticalFocalLengthEnabled());
        nonRobustEstimator.setSuggestedVerticalFocalLengthValue(getSuggestedVerticalFocalLengthValue());
        nonRobustEstimator.setSuggestAspectRatioEnabled(isSuggestAspectRatioEnabled());
        nonRobustEstimator.setSuggestedAspectRatioValue(getSuggestedAspectRatioValue());
        nonRobustEstimator.setSuggestPrincipalPointEnabled(isSuggestPrincipalPointEnabled());
        nonRobustEstimator.setSuggestedPrincipalPointValue(getSuggestedPrincipalPointValue());
        nonRobustEstimator.setSuggestRotationEnabled(isSuggestRotationEnabled());
        nonRobustEstimator.setSuggestedRotationValue(getSuggestedRotationValue());
        nonRobustEstimator.setSuggestCenterEnabled(isSuggestCenterEnabled());
        nonRobustEstimator.setSuggestedCenterValue(getSuggestedCenterValue());

        final var innerEstimator = new LMedSRobustEstimator<>(new LMedSRobustEstimatorListener<PinholeCamera>() {
File Line
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 483
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 473
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 476
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 476
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 479
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 469
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 472
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 471
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 474
return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();

        // avoid setting a threshold too strict
        final var threshold = inliersData.getEstimatedThreshold();
        return Math.max(threshold, stopThreshold);
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < MIN_NUMBER_OF_LINE_PLANE_CORRESPONDENCES) {
File Line
com/irurueta/geometry/estimators/PointCorrespondenceAffineTransformation2DRobustEstimator.java 574
com/irurueta/geometry/estimators/PointCorrespondenceProjectiveTransformation2DRobustEstimator.java 581
final var result = new AffineTransformation2D();
                final var improved = refiner.refine(result);

                if (keepCovariance) {
                    // keep covariance
                    covariance = refiner.getCovariance();
                }

                return improved ? result : transformation;
            } catch (final Exception e) {
                // refinement failed, so we return input value
                return transformation;
            }
        } else {
            return transformation;
        }
    }

    /**
     * Internal method to set lists of points to be used to estimate an affine
     * 2D transformation.
     * This method does not check whether estimator is locked or not.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     affine 2D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     affine 2D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     */
    private void internalSetPoints(final List<Point2D> inputPoints, final List<Point2D> outputPoints) {
        if (inputPoints.size() < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }
        if (inputPoints.size() != outputPoints.size()) {
            throw new IllegalArgumentException();
        }
        this.inputPoints = inputPoints;
        this.outputPoints = outputPoints;
    }
}
File Line
com/irurueta/geometry/estimators/PointCorrespondenceAffineTransformation3DRobustEstimator.java 570
com/irurueta/geometry/estimators/PointCorrespondenceProjectiveTransformation3DRobustEstimator.java 578
final var result = new AffineTransformation3D();
                final var improved = refiner.refine(result);

                if (keepCovariance) {
                    // keep covariance
                    covariance = refiner.getCovariance();
                }

                return improved ? result : transformation;
            } catch (final Exception e) {
                // refinement failed, so we return input value
                return transformation;
            }
        } else {
            return transformation;
        }
    }

    /**
     * Internal method to set lists of points to be used to estimate an affine
     * 3D transformation.
     * This method does not check whether estimator is locked or not.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     affine 3D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     affine 3D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     */
    private void internalSetPoints(final List<Point3D> inputPoints, final List<Point3D> outputPoints) {
        if (inputPoints.size() < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }
        if (inputPoints.size() != outputPoints.size()) {
            throw new IllegalArgumentException();
        }
        this.inputPoints = inputPoints;
        this.outputPoints = outputPoints;
    }
}
File Line
com/irurueta/geometry/ProjectiveTransformation2D.java 689
com/irurueta/geometry/ProjectiveTransformation3D.java 720
public void addRotation(final Rotation2D rotation) throws AlgebraException {
        final var localRotation = getRotation();
        localRotation.combine(rotation);
        setRotation(localRotation);
    }

    /**
     * Sets scale of this transformation.
     *
     * @param scale scale value to be set. A value between 0.0 and 1.0 indicates
     *              that objects will be reduced, a value greater than 1.0 indicates that
     *              objects will be enlarged, and a negative value indicates that objects
     *              will be reversed.
     * @throws AlgebraException raised if for numerical reasons scale cannot
     *                          be set (usually because of numerical instability in parameters of this
     *                          transformation).
     */
    public void setScale(final double scale) throws AlgebraException {
        normalize();
        final var value = t.getElementAt(HOM_COORDS - 1, HOM_COORDS - 1);
        final var decomposer = new RQDecomposer(t.getSubmatrix(0, 0,
                INHOM_COORDS - 1, INHOM_COORDS - 1));
        decomposer.decompose();
        final var localA = decomposer.getR(); //params
        localA.setElementAt(0, 0, scale * value);
        localA.setElementAt(1, 1, scale * value);
        localA.multiply(decomposer.getQ());
File Line
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 139
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 138
super(listener, inputPlanes, outputPlanes);
        stopThreshold = DEFAULT_STOP_THRESHOLD;
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Estimates a projective 3D transformation using a robust estimator and
     * the best set of matched 3D planes correspondences found using the robust
     * estimator.
     *
     * @return a projective 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public ProjectiveTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new LMedSRobustEstimator<>(
                new LMedSRobustEstimatorListener<ProjectiveTransformation3D>() {

                    // plane to be reused when computing residuals
                    private final Plane testPlane = new Plane();
File Line
com/irurueta/geometry/estimators/MSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 128
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 119
super(listener, inputLines, outputLines);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether lines are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, lines are considered equal, since sign changes are not taken
     * into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched lines are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether lines are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, lines are considered equal, since sign changes are not taken
     * into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched lines are inliers
     *                  or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<AffineTransformation2D>() {

            // line to be reused when computing residuals
            private final Line2D testLine = new Line2D();
File Line
com/irurueta/geometry/estimators/MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 128
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 119
super(listener, inputLines, outputLines);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether lines are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, lines are considered equal, since sign changes are not taken
     * into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched lines are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether lines are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether lines are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and lines were
     * equal.
     * A residual of 1 indicates that dot product was 0 and lines were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, lines are considered equal, since sign changes are not taken
     * into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched lines are inliers
     *                  or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Estimates a projective 2D transformation using a robust estimator and
     * the best set of matched 2D lines correspondences found using the robust
     * estimator.
     *
     * @return a projective 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public ProjectiveTransformation2D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(
                new MSACRobustEstimatorListener<ProjectiveTransformation2D>() {

                    // line to be reused when computing residuals
                    private final Line2D testLine = new Line2D();
File Line
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 128
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 120
super(listener, inputPlanes, outputPlanes);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between lines is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Estimates an affine 2D transformation using a robust estimator and
     * the best set of matched 2D planes correspondences found using the robust
     * estimator.
     *
     * @return an affine 2D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public AffineTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<AffineTransformation3D>() {

            // plane to be reused when computing residuals
            private final Plane testPlane = new Plane();
File Line
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 128
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 119
super(listener, inputPlanes, outputPlanes);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two lines algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Estimates a projective 3D transformation using a robust estimator and
     * the best set of matched 3D planes correspondences found using the robust
     * estimator.
     *
     * @return a projective 3D transformation.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public ProjectiveTransformation3D estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        final var innerEstimator = new MSACRobustEstimator<>(
                new MSACRobustEstimatorListener<ProjectiveTransformation3D>() {

                    // plane to be reused when computing residuals
                    private final Plane testPlane = new Plane();
File Line
com/irurueta/geometry/refiners/EuclideanTransformation3DRefiner.java 266
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation3DRefiner.java 182
EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2], point[3]);
                    outputPoint.setHomogeneousCoordinates(point[4], point[5], point[6], point[7]);
File Line
com/irurueta/geometry/refiners/MetricTransformation3DRefiner.java 265
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation3DRefiner.java 182
EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2], point[3]);
                    outputPoint.setHomogeneousCoordinates(point[4], point[5], point[6], point[7]);
File Line
com/irurueta/geometry/estimators/DLTLinePlaneCorrespondencePinholeCameraEstimator.java 229
com/irurueta/geometry/estimators/DLTPointCorrespondencePinholeCameraEstimator.java 222
+ Math.pow(a.getElementAt(counter, 2), 2.0)
                        + Math.pow(a.getElementAt(counter, 9), 2.0)
                        + Math.pow(a.getElementAt(counter, 10), 2.0)
                        + Math.pow(a.getElementAt(counter, 11), 2.0));

                a.setElementAt(counter, 0, a.getElementAt(counter, 0) / rowNorm);
                a.setElementAt(counter, 1, a.getElementAt(counter, 1) / rowNorm);
                a.setElementAt(counter, 2, a.getElementAt(counter, 2) / rowNorm);
                a.setElementAt(counter, 9, a.getElementAt(counter, 9) / rowNorm);
File Line
com/irurueta/geometry/estimators/WeightedLinePlaneCorrespondencePinholeCameraEstimator.java 422
com/irurueta/geometry/estimators/WeightedPointCorrespondencePinholeCameraEstimator.java 416
+ Math.pow(row.getElementAt(0, 2), 2.0)
                            + Math.pow(row.getElementAt(0, 9), 2.0)
                            + Math.pow(row.getElementAt(0, 10), 2.0)
                            + Math.pow(row.getElementAt(0, 11), 2.0));

                    row.setElementAt(0, 0, row.getElementAt(0, 0) / rowNorm);
                    row.setElementAt(0, 1, row.getElementAt(0, 1) / rowNorm);
                    row.setElementAt(0, 2, row.getElementAt(0, 2) / rowNorm);
                    row.setElementAt(0, 9, row.getElementAt(0, 9) / rowNorm);
File Line
com/irurueta/geometry/estimators/LMedSLine2DRobustEstimator.java 202
com/irurueta/geometry/estimators/MSACLine2DRobustEstimator.java 167
com/irurueta/geometry/estimators/PROMedSLine2DRobustEstimator.java 326
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 285
com/irurueta/geometry/estimators/RANSACLine2DRobustEstimator.java 168
@Override
            public int getTotalSamples() {
                return points.size();
            }

            @Override
            public int getSubsetSize() {
                return Line2DRobustEstimator.MINIMUM_SIZE;
            }

            @Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Line2D> solutions) {
                final var point1 = points.get(samplesIndices[0]);
                final var point2 = points.get(samplesIndices[1]);

                try {
                    final var line = new Line2D(point1, point2, false);
                    solutions.add(line);
                } catch (final CoincidentPointsException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Line2D currentEstimation, int i) {
File Line
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 238
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 238
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 203
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 203
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 386
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 385
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 429
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 427
com/irurueta/geometry/estimators/RANSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 281
com/irurueta/geometry/estimators/RANSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 279
final int[] samplesIndices, final List<AffineTransformation3D> solutions) {
                        final var inputPoint1 = inputPoints.get(samplesIndices[0]);
                        final var inputPoint2 = inputPoints.get(samplesIndices[1]);
                        final var inputPoint3 = inputPoints.get(samplesIndices[2]);
                        final var inputPoint4 = inputPoints.get(samplesIndices[3]);

                        final var outputPoint1 = outputPoints.get(samplesIndices[0]);
                        final var outputPoint2 = outputPoints.get(samplesIndices[1]);
                        final var outputPoint3 = outputPoints.get(samplesIndices[2]);
                        final var outputPoint4 = outputPoints.get(samplesIndices[3]);

                        try {
                            final var transformation = new AffineTransformation3D(inputPoint1, inputPoint2, inputPoint3,
File Line
com/irurueta/geometry/estimators/MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 317
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 472
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 488
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 657
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 498
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 303
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 472
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 488
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 657
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 498
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 377
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 472
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 488
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 657
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 498
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 307
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 472
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 488
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 657
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 498
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/refiners/EuclideanTransformation2DRefiner.java 206
com/irurueta/geometry/refiners/EuclideanTransformation3DRefiner.java 225
com/irurueta/geometry/refiners/MetricTransformation2DRefiner.java 208
com/irurueta/geometry/refiners/MetricTransformation3DRefiner.java 223
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation2DRefiner.java 143
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation3DRefiner.java 143
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 142
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 143
final var x = new Matrix(numInliers, nDims);
            final var nSamples = inliers.length();
            var pos = 0;
            for (var i = 0; i < nSamples; i++) {
                if (inliers.get(i)) {
                    // sample is inlier
                    final var inputPoint = samples1.get(i);
                    final var outputPoint = samples2.get(i);
                    inputPoint.normalize();
                    outputPoint.normalize();
                    x.setElementAt(pos, 0, inputPoint.getHomX());
                    x.setElementAt(pos, 1, inputPoint.getHomY());
                    x.setElementAt(pos, 2, inputPoint.getHomW());
File Line
com/irurueta/geometry/refiners/EuclideanTransformation3DRefiner.java 266
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 177
EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2], point[3]);
                    outputPoint.setHomogeneousCoordinates(point[4], point[5], point[6], point[7]);
File Line
com/irurueta/geometry/refiners/LineCorrespondenceAffineTransformation2DRefiner.java 182
com/irurueta/geometry/refiners/LineCorrespondenceProjectiveTransformation2DRefiner.java 176
transformation.getTranslation(), 0, AffineTransformation2D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputLine, outputLine);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(
                        final int i, final double[] point, final double[] params, final double[] derivatives)
                        throws EvaluationException {
                    inputLine.setParameters(point[0], point[1], point[2]);
                    outputLine.setParameters(point[3], point[4], point[5]);

                    // copy values for A matrix
                    System.arraycopy(params, 0, transformation.getA().getBuffer(), 0,
File Line
com/irurueta/geometry/refiners/MetricTransformation3DRefiner.java 265
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 177
EuclideanTransformation3D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2], point[3]);
                    outputPoint.setHomogeneousCoordinates(point[4], point[5], point[6], point[7]);
File Line
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation2DRefiner.java 180
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 174
transformation.getTranslation(), 0, AffineTransformation2D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2]);
                    outputPoint.setHomogeneousCoordinates(point[3], point[4], point[5]);

                    // copy values for A matrix
                    System.arraycopy(params, 0, transformation.getA().getBuffer(), 0,
File Line
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 172
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation3DRefiner.java 175
private final GradientEstimator mGradientEstimator = new GradientEstimator(params -> {
                    // copy values
                    System.arraycopy(params, 0, transformation.getT().getBuffer(), 0, params.length);
                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2]);
File Line
com/irurueta/geometry/Conic.java 373
com/irurueta/geometry/DualConic.java 353
com/irurueta/geometry/Ellipse.java 719
m.setElementAt(4, 5, w * w);

            // normalize each row to increase accuracy
            final var row = new double[6];
            double rowNorm;

            for (var j = 0; j < 5; j++) {
                m.getSubmatrixAsArray(j, 0, j, 5, row);
                rowNorm = com.irurueta.algebra.Utils.normF(row);
                for (var i = 0; i < 6; i++) {
                    m.setElementAt(j, i, m.getElementAt(j, i) / rowNorm);
                }
            }

            final var decomposer = new SingularValueDecomposer(m);
            decomposer.decompose();

            if (decomposer.getRank() < 5) {
                throw new CoincidentPointsException();
File Line
com/irurueta/geometry/estimators/EuclideanTransformation2DRobustEstimator.java 1389
com/irurueta/geometry/estimators/MetricTransformation2DRobustEstimator.java 1386
final EuclideanTransformation2DRobustEstimatorListener listener, final List<Point2D> inputPoints,
            final List<Point2D> outputPoints, final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        return create(listener, inputPoints, outputPoints, qualityScores, weakMinimumSizeAllowed,
                DEFAULT_ROBUST_METHOD);
    }


    /**
     * Internal method to set lists of points to be used to estimate an
     * Euclidean 2D transformation.
     * This method does not check whether estimator is locked or not.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     Euclidean 2D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     Euclidean 2D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     */
    private void internalSetPoints(final List<Point2D> inputPoints, final List<Point2D> outputPoints) {
        if (inputPoints.size() < getMinimumPoints()) {
            throw new IllegalArgumentException();
        }
        if (inputPoints.size() != outputPoints.size()) {
            throw new IllegalArgumentException();
        }
        this.inputPoints = inputPoints;
        this.outputPoints = outputPoints;
    }

    /**
     * Attempts to refine provided solution if refinement is requested.
     * This method returns a refined solution of the same provided solution
     * if refinement is not requested or has failed.
     * If refinement is enabled, and it is requested to keep covariance, this
     * method will also keep covariance of refined transformation.
     *
     * @param transformation transformation estimated by a robust estimator
     *                       without refinement.
     * @return solution after refinement (if requested) or the provided
     * non-refined solution if not requested or refinement failed.
     */
    protected EuclideanTransformation2D attemptRefine(final EuclideanTransformation2D transformation) {
File Line
com/irurueta/geometry/estimators/EuclideanTransformation3DRobustEstimator.java 1389
com/irurueta/geometry/estimators/MetricTransformation3DRobustEstimator.java 1387
final EuclideanTransformation3DRobustEstimatorListener listener,
            final List<Point3D> inputPoints, final List<Point3D> outputPoints,
            final double[] qualityScores, final boolean weakMinimumSizeAllowed) {
        return create(listener, inputPoints, outputPoints, qualityScores, weakMinimumSizeAllowed,
                DEFAULT_ROBUST_METHOD);
    }


    /**
     * Internal method to set lists of points to be used to estimate an
     * Euclidean 3D transformation.
     * This method does not check whether estimator is locked or not.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     Euclidean 3D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     Euclidean 3D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     */
    private void internalSetPoints(final List<Point3D> inputPoints, final List<Point3D> outputPoints) {
        if (inputPoints.size() < getMinimumPoints()) {
            throw new IllegalArgumentException();
        }
        if (inputPoints.size() != outputPoints.size()) {
            throw new IllegalArgumentException();
        }
        this.inputPoints = inputPoints;
        this.outputPoints = outputPoints;
    }

    /**
     * Attempts to refine provided solution if refinement is requested.
     * This method returns a refined solution of the same provided solution
     * if refinement is not requested or has failed.
     * If refinement is enabled, and it is requested to keep covariance, this
     * method will also keep covariance of refined transformation.
     *
     * @param transformation transformation estimated by a robust estimator
     *                       without refinement.
     * @return solution after refinement (if requested) or the provided
     * non-refined solution if not requested or refinement failed.
     */
    protected EuclideanTransformation3D attemptRefine(final EuclideanTransformation3D transformation) {
File Line
com/irurueta/geometry/estimators/MetricTransformation2DEstimator.java 434
com/irurueta/geometry/estimators/MetricTransformation3DEstimator.java 441
final var rotation = new Rotation2D(r);

            // scale
            final var dot = ArrayUtils.dotProduct(s, e);
            final var invScale = dot / inCov;

            // translation
            final var t = r.multiplyAndReturnNew(inCentroid);
            t.multiplyByScalar(-invScale);
            t.add(outCentroid);

            result.setRotation(rotation);
            result.setTranslation(t.getBuffer());
            result.setScale(invScale);

            if (listener != null) {
                listener.onEstimateEnd(this);
            }
        } catch (final AlgebraException | InvalidRotationMatrixException e) {
            throw new CoincidentPointsException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Computes centroid of provided list of points using inhomogeneous
     * coordinates.
     *
     * @param points list of points to compute centroid.
     * @return centroid.
     * @throws AlgebraException never thrown.
     */
    private static Matrix computeCentroid(final List<Point2D> points) throws AlgebraException {
File Line
com/irurueta/geometry/Conic.java 240
com/irurueta/geometry/DualConic.java 263
final var invMatrix = com.irurueta.algebra.Utils.inverse(conicMatrix);

            // ensure that resulting matrix after inversion is symmetric
            // by computing the mean of off-diagonal elements
            final var a = invMatrix.getElementAt(0, 0);
            final var b = 0.5 * (invMatrix.getElementAt(0, 1) + invMatrix.getElementAt(1, 0));
            final var c = invMatrix.getElementAt(1, 1);
            final var d = 0.5 * (invMatrix.getElementAt(0, 2) + invMatrix.getElementAt(2, 0));
            final var e = 0.5 * (invMatrix.getElementAt(1, 2) + invMatrix.getElementAt(2, 1));
            final var f = invMatrix.getElementAt(2, 2);
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 598
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 581
private void internalSetListsEpnP(final List<Point3D> points3D, final List<Point2D> points2D)
            throws WrongListSizesException {

        if (points3D == null || points2D == null) {
            throw new IllegalArgumentException();
        }

        if (!areValidLists(points3D, points2D)) {
            throw new WrongListSizesException();
        }

        this.points3D = points3D;
        this.points2D = points2D;
    }

    /**
     * Picks best solution (the one having the smallest re-projection error).
     *
     * @return best solution.
     */
    private Solution pickBestSolution() {
        Solution bestSolution = null;
        var bestError = Double.MAX_VALUE;
        for (final var s : solutions) {
            if (s.reprojectionError < bestError) {
                bestError = s.reprojectionError;
                bestSolution = s;
            }
        }

        return bestSolution;
    }

    /**
     * Tests solution 3 for general point configuration.
     * Because solution is up to scale, 8 different solutions for different
     * beta1, beta2 and beta3 signs are tried.
     *
     * @throws AlgebraException          if a numerical degeneracy occurs.
     * @throws LockedException           never happens.
     * @throws NotReadyException         never happens.
     * @throws CoincidentPointsException if a point degeneracy has occurred.
     */
    private void generalSolution3() throws AlgebraException, LockedException, NotReadyException,
File Line
com/irurueta/geometry/EuclideanTransformation3D.java 748
com/irurueta/geometry/MetricTransformation3D.java 416
private void internalSetTransformationFromPoints(
            final Point3D inputPoint1, final Point3D inputPoint2, final Point3D inputPoint3, final Point3D inputPoint4,
            final Point3D outputPoint1, final Point3D outputPoint2, final Point3D outputPoint3,
            final Point3D outputPoint4) throws CoincidentPointsException {
        final var inputPoints = new ArrayList<Point3D>();
        inputPoints.add(inputPoint1);
        inputPoints.add(inputPoint2);
        inputPoints.add(inputPoint3);
        inputPoints.add(inputPoint4);

        final var outputPoints = new ArrayList<Point3D>();
        outputPoints.add(outputPoint1);
        outputPoints.add(outputPoint2);
        outputPoints.add(outputPoint3);
        outputPoints.add(outputPoint4);

        final var estimator = new EuclideanTransformation3DEstimator(inputPoints, outputPoints);
File Line
com/irurueta/geometry/estimators/LMedSPoint2DRobustEstimator.java 213
com/irurueta/geometry/estimators/MSACPoint2DRobustEstimator.java 178
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 337
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 380
com/irurueta/geometry/estimators/RANSACPoint2DRobustEstimator.java 253
@Override
            public void estimatePreliminarSolutions(final int[] samplesIndices, final List<Point2D> solutions) {
                final var line1 = lines.get(samplesIndices[0]);
                final var line2 = lines.get(samplesIndices[1]);

                try {
                    final var point = line1.getIntersection(line2);
                    solutions.add(point);
                } catch (final NoIntersectionException e) {
                    // if points are coincident, no solution is added
                }
            }

            @Override
            public double computeResidual(final Point2D currentEstimation, final int i) {
                return residual(currentEstimation, lines.get(i));
            }

            @Override
            public boolean isReady() {
                return LMedSPoint2DRobustEstimator.this.isReady();
File Line
com/irurueta/geometry/Circle.java 457
com/irurueta/geometry/Ellipse.java 1244
return Math.abs(point.distanceTo(center) - radius) <= threshold;
    }

    /**
     * Determines whether provided point lies at circle boundary or not.
     *
     * @param point Point to be checked.
     * @return True if point lies at circle boundary, false otherwise.
     */
    public boolean isLocus(final Point2D point) {
        return isLocus(point, DEFAULT_THRESHOLD);
    }

    /**
     * Returns a line tangent to this circle at provided point. Provided point
     * must be locus of this circle, otherwise a NotLocusException will be
     * thrown.
     *
     * @param point a locus point of this circle.
     * @return a 2D line tangent to this circle at provided point.
     * @throws NotLocusException if provided point is not locus of this circle
     *                           up to DEFAULT_THRESHOLD.
     */
    public Line2D getTangentLineAt(final Point2D point) throws NotLocusException {
        return getTangentLineAt(point, DEFAULT_THRESHOLD);
    }

    /**
     * Returns a line tangent to this circle at provided point. Provided point
     * must be locus of this circle, otherwise a NotLocusException will be
     * thrown.
     *
     * @param point     a locus point of this circle.
     * @param threshold threshold to determine if provided point is locus.
     * @return a 2D line tangent to this circle at provided point.
     * @throws NotLocusException        if provided point is not locus of this circle
     *                                  up to provided threshold.
     * @throws IllegalArgumentException if provided threshold is negative.
     */
    public Line2D getTangentLineAt(final Point2D point, final double threshold) throws NotLocusException {
        final var line = new Line2D();
        tangentLineAt(point, line, threshold);
        return line;
    }

    /**
     * Computes a line tangent to this circle at provided point. Provided point
     * must be locus of this circle, otherwise a NotLocusException will be
     * thrown.
     *
     * @param point     a locus point of this circle.
     * @param line      instance of a 2D line where result will be stored.
     * @param threshold threshold to determine if provided point is locus.
     * @throws NotLocusException        if provided point is not locus of this circle
     *                                  up to provided threshold.
     * @throws IllegalArgumentException if provided threshold is negative.
     */
    public void tangentLineAt(final Point2D point, final Line2D line, final double threshold) throws NotLocusException {
        if (!isLocus(point, threshold)) {
            throw new NotLocusException();
        }
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1093
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1159
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 1040
final Point3D vci, final Point3D vcj) {

        final var vaix = vai.getInhomX();
        final var vaiy = vai.getInhomY();
        final var vaiz = vai.getInhomZ();

        final var vajx = vaj.getInhomX();
        final var vajy = vaj.getInhomY();
        final var vajz = vaj.getInhomZ();

        final var vbix = vbi.getInhomX();
        final var vbiy = vbi.getInhomY();
        final var vbiz = vbi.getInhomZ();

        final var vbjx = vbj.getInhomX();
        final var vbjy = vbj.getInhomY();
        final var vbjz = vbj.getInhomZ();
File Line
com/irurueta/geometry/estimators/PROMedSCircleRobustEstimator.java 385
com/irurueta/geometry/estimators/PROSACCircleRobustEstimator.java 345
com/irurueta/geometry/estimators/PROSACConicRobustEstimator.java 348
com/irurueta/geometry/estimators/PROSACDualConicRobustEstimator.java 351
com/irurueta/geometry/estimators/PROSACDualQuadricRobustEstimator.java 356
com/irurueta/geometry/estimators/PROSACLine2DRobustEstimator.java 342
com/irurueta/geometry/estimators/PROSACPlaneRobustEstimator.java 344
com/irurueta/geometry/estimators/PROSACQuadricRobustEstimator.java 354
com/irurueta/geometry/estimators/PROSACSphereRobustEstimator.java 345
listener.onEstimateProgressChange(PROMedSCircleRobustEstimator.this, progress);
                }
            }

            @Override
            public double[] getQualityScores() {
                return qualityScores;
            }
        });

        try {
            locked = true;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            return innerEstimator.estimate();
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
File Line
com/irurueta/geometry/ProjectiveTransformation2D.java 387
com/irurueta/geometry/ProjectiveTransformation3D.java 386
public ProjectiveTransformation2D(final AffineParameters2D params, final Rotation2D rotation,
                                      final double[] translation) {
        if (translation.length != NUM_TRANSLATION_COORDS) {
            throw new IllegalArgumentException();
        }

        try {
            final var a = params.asMatrix();
            a.multiply(rotation.asInhomogeneousMatrix());
            t = Matrix.identity(HOM_COORDS, HOM_COORDS);
            // set A
            t.setSubmatrix(0, 0, INHOM_COORDS - 1,
                    INHOM_COORDS - 1, a);
            // set translation
            t.setSubmatrix(0, HOM_COORDS - 1, translation.length - 1,
                    HOM_COORDS - 1, translation);
        } catch (final WrongSizeException ignore) {
            // never happens
        }
        normalize();
    }

    /**
     * Creates transformation with provided parameters, rotation and
     * translation.
     *
     * @param params               affine parameters including horizontal scaling, vertical
     *                             scaling and skewness.
     * @param rotation             a 2D rotation.
     * @param translation          array indicating 2D translation using inhomogeneous
     *                             coordinates.
     * @param projectiveParameters array of length 3 containing projective
     *                             parameters.
     * @throws NullPointerException     raised if provided parameters, rotation or
     *                                  translation is null.
     * @throws IllegalArgumentException raised if provided translation does not
     *                                  have length 2 or if projective parameters array doesn't have length 3.
     */
    public ProjectiveTransformation2D(final AffineParameters2D params, final Rotation2D rotation,
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1436
com/irurueta/geometry/estimators/UPnPPointCorrespondencePinholeCameraEstimator.java 1446
for (int i = 0; i < cols; i++) {
            norm += Math.pow(m.getElementAt(row, i), 2.0);
        }
        norm = Math.sqrt(norm);

        for (var i = 0; i < cols; i++) {
            m.setElementAt(row, i, m.getElementAt(row, i) / norm);
        }
    }

    /**
     * In order to find control points in camera coordinates, an homogeneous
     * linear system of equations must be solved having the form M*x = 0, where
     * x contains the coordinates of all control points in the form [x1, y1, z1,
     * x2, y2, z2, ... ].
     * For general configuration there are 4 control points, hence x has length
     * 12 (3 coordinates * 4 control points).
     * For a planar configuration there are 3 control points, hence x has length
     * 9 (3 coordinates * 3 control points).
     * This method builds M matrix required to solve such linear system of
     * equations, where M has size 2*n x 12 (general configuration) or 2*n x 9
     * (planar configuration), where n is the number of provided 2D observed
     * points.
     *
     * @throws AlgebraException if numerical instabilities occur.
     */
    private void buildM() throws AlgebraException {
        final var n = points2D.size();
        final var numControlPoints = alphas.getColumns();

        m = new Matrix(2 * n, 3 * numControlPoints);
File Line
com/irurueta/geometry/estimators/MSACEuclideanTransformation2DRobustEstimator.java 339
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACEuclideanTransformation3DRobustEstimator.java 339
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 299
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 305
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACMetricTransformation2DRobustEstimator.java 337
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACMetricTransformation3DRobustEstimator.java 337
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 301
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 308
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACPoint2DRobustEstimator.java 227
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 391
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 393
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACPoint3DRobustEstimator.java 229
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 391
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 393
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 268
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 270
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
        });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 273
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 276
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 462
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 623
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 465
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 468
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 458
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 461
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 460
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 463
}
                });

        try {
            locked = true;
            inliersData = null;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var transformation = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/Conic.java 391
com/irurueta/geometry/DualConic.java 371
throw new CoincidentPointsException();
            }

            // the right null-space of m contains the parameters a, b, c, d, e ,f
            // of the conic
            final var v = decomposer.getV();

            final var a = v.getElementAt(0, 5);
            final var b = v.getElementAt(1, 5);
            final var c = v.getElementAt(2, 5);
            final var d = v.getElementAt(3, 5);
            final var e = v.getElementAt(4, 5);
            final var f = v.getElementAt(5, 5);

            setParameters(a, b, c, d, e, f);
        } catch (final AlgebraException ex) {
            throw new CoincidentPointsException(ex);
File Line
com/irurueta/geometry/Line3D.java 242
com/irurueta/geometry/Plane.java 525
}

    /**
     * Returns closest point belonging to this 3D line respect provided point.
     *
     * @param point Point to be checked.
     * @return Closest point belonging to this 3D line respect provided point.
     */
    public Point3D getClosestPoint(final Point3D point) {
        return getClosestPoint(point, DEFAULT_LOCUS_THRESHOLD);
    }

    /**
     * Returns closest point belonging to this 3D line respect provided point
     * up to provided threshold.
     *
     * @param point     Point to be checked.
     * @param threshold Threshold to determine the closest point.
     * @return Closest point belonging to this 3D line respect provided point.
     * @throws IllegalArgumentException Raised if provided threshold is negative.
     */
    public Point3D getClosestPoint(final Point3D point, final double threshold) {
        final var result = Point3D.create();
        closestPoint(point, result, threshold);
        return result;
    }

    /**
     * Computes closest point belonging to this 3D line respect provided point
     * and stores the result in provided instance.
     *
     * @param point  Point to be checked.
     * @param result Instance where computed point will be stored.
     */
    public void closestPoint(final Point3D point, final Point3D result) {
        closestPoint(point, result, DEFAULT_LOCUS_THRESHOLD);
    }

    /**
     * Computes closest point belonging to this 3D line respect provided point
     * up to provided threshold and stores the result in provided instance.
     *
     * @param point     Point to be checked.
     * @param result    Instance where computed point will be stored.
     * @param threshold Threshold to determine the closest point.
     * @throws IllegalArgumentException Raised if provided threshold is negative.
     */
    public void closestPoint(final Point3D point, final Point3D result, final double threshold) {
        if (threshold < MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        // normalize to increase accuracy
        point.normalize();
File Line
com/irurueta/geometry/MetricTransformation2D.java 359
com/irurueta/geometry/MetricTransformation3D.java 372
final MetricTransformation2D inputTransformation, final MetricTransformation2D outputTransformation) {
        // combination in matrix representation is:
        // [s1*R1 t1] * [s2*R2 t2] = [s1*s2*R1*R2 + t1*0T  s1*R1*t2 + t1*1] = [s1*s2*R1*R2  s1*R1*t2 + t1]
        // [0T   1 ]    [0T    1 ]   [0T*s2*R2 + 1*0T      0T*t2 + 1*1    ]   [0T           1            ]

        try {
            // we do translation first, because this.rotation might change later
            final var r1 = getRotation().asInhomogeneousMatrix();
            final var t2 = Matrix.newFromArray(inputTransformation.getTranslation(),
                    true);
            // this is R1 * t2
            r1.multiply(t2);
            r1.multiplyByScalar(this.scale);

            ArrayUtils.sum(r1.toArray(), this.getTranslation(), outputTransformation.getTranslation());

            outputTransformation.setRotation(this.getRotation().combineAndReturnNew(inputTransformation.getRotation()));

            outputTransformation.scale = this.scale * inputTransformation.scale;

        } catch (final WrongSizeException ignore) {
            // never happens
        }
    }
File Line
com/irurueta/geometry/Polygon2D.java 437
com/irurueta/geometry/Polygon3D.java 457
line.normalize();

        // find the closest point to line
        line.closestPoint(point, pointInLine);
        // to increase accuracy
        pointInLine.normalize();

        if (pointInLine.isBetween(prevPoint, first)) {
            // closest point lies within segment of polygon boundary, so we
            // keep distance
            dist = point.distanceTo(pointInLine);
            if (dist < bestDist) {
                // a better point has been found
                bestDist = dist;
                found = true;
            }
        }

        if (!found) {
            // no closest point was found on a segment belonging to polygon
            // boundary, so we search for the closest vertex
            iterator = vertices.iterator();
            while (iterator.hasNext()) {
                // a better vertex has been found
                curPoint = iterator.next();
                dist = point.distanceTo(curPoint);
                if (dist < bestDist) {
                    bestDist = dist;
                }
            }
        }

        return bestDist;
    }

    /**
     * Returns the closest point to provided point that is locus of this
     * polygon (i.e. lies on a border of this polygon).
     *
     * @param point Point to be checked.
     * @return Closest point being locus of this polygon.
     */
    public Point2D getClosestPoint(final Point2D point) {
File Line
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 138
com/irurueta/geometry/estimators/LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 209
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 138
super(listener, points3D, points2D);
        stopThreshold = DEFAULT_STOP_THRESHOLD;
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences or 2D line/3D plane
     * correspondences found using the robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 118
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 190
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 119
super(listener, points3D, points2D);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @return threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether points are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error (i.e. Euclidean distance) a
     * possible solution has on projected 2D points.
     *
     * @param threshold threshold to be set.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D/3D point correspondences or 2D line/3D plane
     * correspondences found using the robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTPointCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/refiners/EuclideanTransformation2DRefiner.java 240
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation2DRefiner.java 180
EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2]);
                    outputPoint.setHomogeneousCoordinates(point[3], point[4], point[5]);
File Line
com/irurueta/geometry/refiners/MetricTransformation2DRefiner.java 243
com/irurueta/geometry/refiners/PointCorrespondenceAffineTransformation2DRefiner.java 180
EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2]);
                    outputPoint.setHomogeneousCoordinates(point[3], point[4], point[5]);
File Line
com/irurueta/geometry/PinholeCamera.java 1918
com/irurueta/geometry/PinholeCamera.java 1933
m.setElementAt(2, 0, internalMatrix.getElementAt(2, 1));

            m.setElementAt(0, 1, internalMatrix.getElementAt(0, 2));
            m.setElementAt(1, 1, internalMatrix.getElementAt(1, 2));
            m.setElementAt(2, 1, internalMatrix.getElementAt(2, 2));

            m.setElementAt(0, 2, internalMatrix.getElementAt(0, 3));
            m.setElementAt(1, 2, internalMatrix.getElementAt(1, 3));
            m.setElementAt(2, 2, internalMatrix.getElementAt(2, 3));

            final var x = Utils.det(m);
File Line
com/irurueta/geometry/estimators/LMedSCircleRobustEstimator.java 261
com/irurueta/geometry/estimators/LMedSConicRobustEstimator.java 262
com/irurueta/geometry/estimators/LMedSDualConicRobustEstimator.java 262
com/irurueta/geometry/estimators/LMedSDualQuadricRobustEstimator.java 269
com/irurueta/geometry/estimators/LMedSLine2DRobustEstimator.java 261
com/irurueta/geometry/estimators/LMedSPlaneRobustEstimator.java 261
com/irurueta/geometry/estimators/LMedSQuadricRobustEstimator.java 267
listener.onEstimateProgressChange(LMedSCircleRobustEstimator.this, progress);
                }
            }
        });

        try {
            locked = true;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            innerEstimator.setStopThreshold(stopThreshold);
            return innerEstimator.estimate();
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.LMEDS;
    }
}
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation2DRobustEstimator.java 634
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 402
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 404
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 509
return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of such
     * threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();
        return inliersData.getEstimatedThreshold();
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < getMinimumPoints()) {
File Line
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 634
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 402
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 404
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 509
return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of such
     * threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();
        return inliersData.getEstimatedThreshold();
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < getMinimumPoints()) {
File Line
com/irurueta/geometry/estimators/PROMedSMetricTransformation2DRobustEstimator.java 634
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 402
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 404
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 509
return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of such
     * threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();
        return inliersData.getEstimatedThreshold();
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < getMinimumPoints()) {
File Line
com/irurueta/geometry/estimators/PROMedSMetricTransformation3DRobustEstimator.java 634
com/irurueta/geometry/estimators/PROMedSPoint2DRobustEstimator.java 402
com/irurueta/geometry/estimators/PROMedSPoint3DRobustEstimator.java 404
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 509
return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of such
     * threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();
        return inliersData.getEstimatedThreshold();
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < getMinimumPoints()) {
File Line
com/irurueta/geometry/estimators/PROSACLineCorrespondenceAffineTransformation2DRobustEstimator.java 545
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 447
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 448
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation2DRobustEstimator.java 514
com/irurueta/geometry/estimators/PROSACPointCorrespondenceAffineTransformation3DRobustEstimator.java 517
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 515
com/irurueta/geometry/estimators/PROSACPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 518
return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }

    /**
     * Sets quality scores corresponding to each pair of matched lines.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }

        this.qualityScores = qualityScores;
    }
}
File Line
com/irurueta/geometry/estimators/PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 547
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 447
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 448
return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }

    /**
     * Sets quality scores corresponding to each pair of matched lines.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }

        this.qualityScores = qualityScores;
    }
}
File Line
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 547
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 447
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 448
return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }

    /**
     * Sets quality scores corresponding to each pair of matched lines.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }

        this.qualityScores = qualityScores;
    }
}
File Line
com/irurueta/geometry/estimators/PROSACPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 550
com/irurueta/geometry/estimators/PROSACPoint2DRobustEstimator.java 447
com/irurueta/geometry/estimators/PROSACPoint3DRobustEstimator.java 448
return attemptRefine(transformation);
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROSAC;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        return threshold;
    }

    /**
     * Sets quality scores corresponding to each pair of matched lines.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(final double[] qualityScores) {
        if (qualityScores.length < MINIMUM_SIZE) {
            throw new IllegalArgumentException();
        }

        this.qualityScores = qualityScores;
    }

}
File Line
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 499
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 473
com/irurueta/geometry/estimators/PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 476
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 476
com/irurueta/geometry/estimators/PROMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 479
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 469
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 472
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 471
com/irurueta/geometry/estimators/PROMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 474
return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (PROMedSRobustEstimator.PROMedSInliersData) getInliersData();

        // avoid setting a threshold too strict
        final var threshold = inliersData.getEstimatedThreshold();
        return Math.max(threshold, stopThreshold);
    }

    /**
     * Sets quality scores corresponding to each pair of matched points.
     * This method is used internally and does not check whether instance is
     * locked or not.
     *
     * @param qualityScores quality scores to be set.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE.
     */
    private void internalSetQualityScores(double[] qualityScores) {
File Line
com/irurueta/geometry/refiners/EuclideanTransformation2DRefiner.java 240
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 174
EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2]);
                    outputPoint.setHomogeneousCoordinates(point[3], point[4], point[5]);
File Line
com/irurueta/geometry/refiners/MetricTransformation2DRefiner.java 243
com/irurueta/geometry/refiners/PointCorrespondenceProjectiveTransformation2DRefiner.java 174
EuclideanTransformation2D.NUM_TRANSLATION_COORDS);

                    return residual(transformation, inputPoint, outputPoint);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    inputPoint.setHomogeneousCoordinates(point[0], point[1], point[2]);
                    outputPoint.setHomogeneousCoordinates(point[3], point[4], point[5]);
File Line
com/irurueta/geometry/estimators/EuclideanTransformation2DEstimator.java 177
com/irurueta/geometry/estimators/MetricTransformation2DEstimator.java 173
final EuclideanTransformation2DEstimatorListener listener,
            final List<Point2D> inputPoints, final List<Point2D> outputPoints, final boolean weakMinimumSizeAllowed) {
        this.weakMinimumSizeAllowed = weakMinimumSizeAllowed;
        this.listener = listener;
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Returns list of input points to be used to estimate an Euclidean 2D
     * transformation.
     * Each point in the list of input points must be matched with the
     * corresponding point in the list of output points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of input points to be used to estimate an Euclidean
     * transformation.
     */
    public List<Point2D> getInputPoints() {
        return inputPoints;
    }

    /**
     * Returns list of output points to be used to estimate an Euclidean 2D
     * transformation.
     * Each point in the list of output points must be matched with the
     * corresponding point in the list of input points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than MINIMUM_SIZE.
     *
     * @return list of input points to be used to estimate an Euclidean
     * transformation.
     */
    public List<Point2D> getOutputPoints() {
        return outputPoints;
    }

    /**
     * Sets list of points to be used to estimate an Euclidean 2D
     * transformation.
     * Points in the list located at the same position are considered to be
     * matched. Hence, both lists must have the same size, and their size must
     * be greater or equal than MINIMUM_SIZE.
     *
     * @param inputPoints  list of input points ot be used ot estimate an
     *                     Euclidean 2D transformation.
     * @param outputPoints list of output points ot be used to estimate an
     *                     Euclidean 2D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than MINIMUM_SIZE.
     * @throws LockedException          if estimator is locked because a computation is
     *                                  already in progress.
     */
    public void setPoints(final List<Point2D> inputPoints, final List<Point2D> outputPoints) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Returns reference to listener to be notified of events such as when
     * estimation starts or ends.
     *
     * @return listener to be notified of events.
     */
    public EuclideanTransformation2DEstimatorListener getListener() {
File Line
com/irurueta/geometry/estimators/EuclideanTransformation3DEstimator.java 177
com/irurueta/geometry/estimators/MetricTransformation3DEstimator.java 177
final EuclideanTransformation3DEstimatorListener listener,
            final List<Point3D> inputPoints, final List<Point3D> outputPoints, final boolean weakMinimumSizeAllowed) {
        this.weakMinimumSizeAllowed = weakMinimumSizeAllowed;
        this.listener = listener;
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Returns list of input points to be used to estimate an Euclidean 3D
     * transformation.
     * Each point in the list of input points must be matched with the
     * corresponding point in the list of output points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than #getMinimumPoints.
     *
     * @return list of input points to be used to estimate an Euclidean 3D
     * transformation.
     */
    public List<Point3D> getInputPoints() {
        return inputPoints;
    }

    /**
     * Returns list of output points ot be used to estimate an Euclidean 3D
     * transformation.
     * Each point in the list of output points must be matched with the
     * corresponding point in the list of input points located at the same
     * position. Hence, both input points and output points must have the same
     * size, and their size must be greater or equal than #getMinimumPoints.
     *
     * @return list of output points to be used to estimate an Euclidean 3D
     * transformation.
     */
    public List<Point3D> getOutputPoints() {
        return outputPoints;
    }

    /**
     * Sets list of points to be used to estimate an Euclidean 3D
     * transformation.
     * Points in the list located at the same position are considered to be
     * matched. Hence, both lists must have the same size, and their size must
     * be greater or equal than #getMinimumPoints.
     *
     * @param inputPoints  list of input points to be used to estimate an
     *                     Euclidean 3D transformation.
     * @param outputPoints list of output points to be used to estimate an
     *                     Euclidean 3D transformation.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size or their size is smaller than #getMinimumPoints.
     * @throws LockedException          if estimator is locked because a computation is
     *                                  already in progress.
     */
    public void setPoints(final List<Point3D> inputPoints, final List<Point3D> outputPoints) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetPoints(inputPoints, outputPoints);
    }

    /**
     * Returns reference to listener to be notified of events such as when
     * estimation starts or ends.
     *
     * @return listener to be notified of events.
     */
    public EuclideanTransformation3DEstimatorListener getListener() {
File Line
com/irurueta/geometry/estimators/MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 323
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 555
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 539
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 723
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 547
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 401
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 386
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 392
innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 309
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 555
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 539
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 723
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 547
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 401
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 386
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 392
innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 383
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 555
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 539
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 723
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 547
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 401
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 386
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 392
innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 313
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 555
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 539
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 723
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 547
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 401
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 386
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 392
innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
File Line
com/irurueta/geometry/estimators/PROMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 478
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 555
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 539
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 723
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 547
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 401
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 386
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 392
innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
File Line
com/irurueta/geometry/estimators/PROMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 494
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 555
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 539
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 723
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 547
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 401
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 386
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 392
innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
File Line
com/irurueta/geometry/estimators/PROMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 663
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 555
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 539
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 723
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 547
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 401
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 386
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 392
innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
File Line
com/irurueta/geometry/estimators/PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 504
com/irurueta/geometry/estimators/PROSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 555
com/irurueta/geometry/estimators/PROSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 539
com/irurueta/geometry/estimators/PROSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 723
com/irurueta/geometry/estimators/PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 547
com/irurueta/geometry/estimators/RANSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 401
com/irurueta/geometry/estimators/RANSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 386
com/irurueta/geometry/estimators/RANSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 465
com/irurueta/geometry/estimators/RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 392
innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            final var result = innerEstimator.estimate();
            inliersData = innerEstimator.getInliersData();
            return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }

    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.PROMEDS;
File Line
com/irurueta/geometry/estimators/LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 137
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 138
com/irurueta/geometry/estimators/LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 209
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 138
super(listener, planes, lines);
        stopThreshold = DEFAULT_STOP_THRESHOLD;
    }

    /**
     * Returns threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @return stop threshold to stop the algorithm prematurely when a certain
     * accuracy has been reached.
     */
    public double getStopThreshold() {
        return stopThreshold;
    }

    /**
     * Sets threshold to be used to keep the algorithm iterating in case that
     * best estimated threshold using median of residuals is not small enough.
     * Once a solution is found that generates a threshold below this value, the
     * algorithm will stop.
     * The stop threshold can be used to prevent the LMedS algorithm iterating
     * too many times in cases where samples have a very similar accuracy.
     * For instance, in cases where proportion of outliers is very small (close
     * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
     * iterate for a long time trying to find the best solution when indeed
     * there is no need to do that if a reasonable threshold has already been
     * reached.
     * Because of this behaviour the stop threshold can be set to a value much
     * lower than the one typically used in RANSAC, and yet the algorithm could
     * still produce even smaller thresholds in estimated results.
     *
     * @param stopThreshold stop threshold to stop the algorithm prematurely
     *                      when a certain accuracy has been reached.
     * @throws IllegalArgumentException if provided value is zero or negative.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setStopThreshold(final double stopThreshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (stopThreshold <= MIN_STOP_THRESHOLD) {
            throw new IllegalArgumentException();
        }

        this.stopThreshold = stopThreshold;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTLinePlaneCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/LinePlaneCorrespondencePinholeCameraEstimator.java 226
com/irurueta/geometry/estimators/LinePlaneCorrespondencePinholeCameraRobustEstimator.java 634
com/irurueta/geometry/estimators/PointCorrespondencePinholeCameraEstimator.java 564
com/irurueta/geometry/estimators/PointCorrespondencePinholeCameraRobustEstimator.java 1462
refiner.setSuggestionWeightStep(suggestionWeightStep);

                refiner.setSuggestSkewnessValueEnabled(suggestSkewnessValueEnabled);
                refiner.setSuggestedSkewnessValue(suggestedSkewnessValue);
                refiner.setSuggestHorizontalFocalLengthEnabled(suggestHorizontalFocalLengthEnabled);
                refiner.setSuggestedHorizontalFocalLengthValue(suggestedHorizontalFocalLengthValue);
                refiner.setSuggestVerticalFocalLengthEnabled(suggestVerticalFocalLengthEnabled);
                refiner.setSuggestedVerticalFocalLengthValue(suggestedVerticalFocalLengthValue);
                refiner.setSuggestAspectRatioEnabled(suggestAspectRatioEnabled);
                refiner.setSuggestedAspectRatioValue(suggestedAspectRatioValue);
                refiner.setSuggestPrincipalPointEnabled(suggestPrincipalPointEnabled);
                refiner.setSuggestedPrincipalPointValue(suggestedPrincipalPointValue);
                refiner.setSuggestRotationEnabled(suggestRotationEnabled);
                refiner.setSuggestedRotationValue(suggestedRotationValue);
                refiner.setSuggestCenterEnabled(suggestCenterEnabled);
                refiner.setSuggestedCenterValue(suggestedCenterValue);

                final var result = new PinholeCamera();
                final var improved = refiner.refine(result);
File Line
com/irurueta/geometry/estimators/MSACDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 126
com/irurueta/geometry/estimators/MSACDLTPointCorrespondencePinholeCameraRobustEstimator.java 118
com/irurueta/geometry/estimators/MSACEPnPPointCorrespondencePinholeCameraRobustEstimator.java 190
com/irurueta/geometry/estimators/MSACUPnPPointCorrespondencePinholeCameraRobustEstimator.java 119
super(listener, planes, lines);
        threshold = DEFAULT_THRESHOLD;
    }

    /**
     * Returns threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @return threshold to determine whether matched planes are inliers or not.
     */
    public double getThreshold() {
        return threshold;
    }

    /**
     * Sets threshold to determine whether planes are inliers or not when
     * testing possible estimation solutions.
     * The threshold refers to the amount of error a possible solution has on a
     * plane respect the back-projected plane of a line using estimated camera
     * Residuals to determine whether planes are inliers or not are computed by
     * comparing two planes algebraically (e.g. doing the dot product of their
     * parameters).
     * A residual of 0 indicates that dot product was 1 or -1 and planes were
     * equal.
     * A residual of 1 indicates that dot product was 0 and planes were
     * orthogonal.
     * If dot product between planes is -1, then although their director vectors
     * are opposed, planes are considered equal, since sign changes are not
     * taken into account and their residuals will be 0.
     *
     * @param threshold threshold to determine whether matched planes are
     *                  inliers or not.
     * @throws IllegalArgumentException if provided value is equal or less than
     *                                  zero.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     */
    public void setThreshold(final double threshold) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (threshold <= MIN_THRESHOLD) {
            throw new IllegalArgumentException();
        }
        this.threshold = threshold;
    }

    /**
     * Estimates a pinhole camera using a robust estimator and
     * the best set of matched 2D line/3D plane correspondences found using the
     * robust estimator.
     *
     * @return a pinhole camera.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws NotReadyException        if provided input data is not enough to start
     *                                  the estimation.
     * @throws RobustEstimatorException if estimation fails for any reason
     *                                  (i.e. numerical instability, no solution available, etc).
     */
    @Override
    public PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        // pinhole camera estimator using DLT (Direct Linear Transform) algorithm
        final var nonRobustEstimator = new DLTLinePlaneCorrespondencePinholeCameraEstimator();
File Line
com/irurueta/geometry/estimators/PlaneCorrespondenceAffineTransformation3DRobustEstimator.java 163
com/irurueta/geometry/estimators/PlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 164
public final void setPlanes(final List<Plane> inputPlanes, final List<Plane> outputPlanes) throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        internalSetPlanes(inputPlanes, outputPlanes);
    }

    /**
     * Indicates if estimator is ready to start the affine 3D transformation
     * estimation.
     * This is true when input data (i.e. lists of matched planes) are provided
     * and a minimum of MINIMUM_SIZE lines are available.
     *
     * @return true if estimator is ready, false otherwise.
     */
    public boolean isReady() {
        return inputPlanes != null && outputPlanes != null && inputPlanes.size() == outputPlanes.size()
                && inputPlanes.size() >= MINIMUM_SIZE;
    }

    /**
     * Returns quality scores corresponding to each pair of matched planes.
     * The larger the score value the better the quality of the matching.
     * This implementation always returns null.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @return quality scores corresponding to each pair of matched points.
     */
    public double[] getQualityScores() {
        return null;
    }

    /**
     * Sets quality scores corresponding to each pair of matched planes.
     * The larger the score value the better the quality of the matching.
     * This implementation makes no action.
     * Subclasses using quality scores must implement proper behaviour.
     *
     * @param qualityScores quality scores corresponding to each pair of matched
     *                      points.
     * @throws LockedException          if robust estimator is locked because an
     *                                  estimation is already in progress.
     * @throws IllegalArgumentException if provided quality scores length is
     *                                  smaller than MINIMUM_SIZE (i.e. 3 samples).
     */
    public void setQualityScores(final double[] qualityScores) throws LockedException {
    }

    /**
     * Creates an affine 3D transformation estimator based on 3D plane
     * correspondences and using provided robust estimator method.
     *
     * @param method method of a robust estimator algorithm to estimate
     *               the best affine 3D transformation.
     * @return an instance of affine 3D transformation estimator.
     */
    public static PlaneCorrespondenceAffineTransformation3DRobustEstimator create(final RobustEstimatorMethod method) {
File Line
com/irurueta/geometry/estimators/DLTLinePlaneCorrespondencePinholeCameraEstimator.java 292
com/irurueta/geometry/estimators/DLTPointCorrespondencePinholeCameraEstimator.java 260
rowNorm = Math.sqrt(Math.pow(a.getElementAt(counter, 6), 2.0)
                        + Math.pow(a.getElementAt(counter, 7), 2.0)
                        + Math.pow(a.getElementAt(counter, 8), 2.0)
                        + Math.pow(a.getElementAt(counter, 9), 2.0)
                        + Math.pow(a.getElementAt(counter, 10), 2.0)
                        + Math.pow(a.getElementAt(counter, 11), 2.0));

                a.setElementAt(counter, 6, a.getElementAt(counter, 6) / rowNorm);
File Line
com/irurueta/geometry/estimators/LMedSDLTLinePlaneCorrespondencePinholeCameraRobustEstimator.java 336
com/irurueta/geometry/estimators/LMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 326
com/irurueta/geometry/estimators/LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 328
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 328
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 331
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 318
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 320
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 320
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 323
com/irurueta/geometry/estimators/LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator.java 355
return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());

        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.LMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (LMedSRobustEstimator.LMedSInliersData) getInliersData();

        // avoid setting a threshold too strict
        final var threshold = inliersData.getEstimatedThreshold();
        return Math.max(threshold, stopThreshold);
    }
}
File Line
com/irurueta/geometry/estimators/LMedSDLTPointCorrespondencePinholeCameraRobustEstimator.java 349
com/irurueta/geometry/estimators/LMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 326
com/irurueta/geometry/estimators/LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 328
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 328
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 331
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 318
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 320
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 320
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 323
return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.LMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (LMedSRobustEstimator.LMedSInliersData) getInliersData();

        // avoid setting a threshold too strict
        final var threshold = inliersData.getEstimatedThreshold();
        return Math.max(threshold, stopThreshold);
    }
}
File Line
com/irurueta/geometry/estimators/LMedSEPnPPointCorrespondencePinholeCameraRobustEstimator.java 423
com/irurueta/geometry/estimators/LMedSLineCorrespondenceAffineTransformation2DRobustEstimator.java 326
com/irurueta/geometry/estimators/LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator.java 328
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceAffineTransformation3DRobustEstimator.java 328
com/irurueta/geometry/estimators/LMedSPlaneCorrespondenceProjectiveTransformation3DRobustEstimator.java 331
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation2DRobustEstimator.java 318
com/irurueta/geometry/estimators/LMedSPointCorrespondenceAffineTransformation3DRobustEstimator.java 320
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation2DRobustEstimator.java 320
com/irurueta/geometry/estimators/LMedSPointCorrespondenceProjectiveTransformation3DRobustEstimator.java 323
return attemptRefine(result, nonRobustEstimator.getMaxSuggestionWeight());
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.LMEDS;
    }

    /**
     * Gets standard deviation used for Levenberg-Marquardt fitting during
     * refinement.
     * Returned value gives an indication of how much variance each residual
     * has.
     * Typically, this value is related to the threshold used on each robust
     * estimation, since residuals of found inliers are within the range of
     * such threshold.
     *
     * @return standard deviation used for refinement.
     */
    @Override
    protected double getRefinementStandardDeviation() {
        final var inliersData = (LMedSRobustEstimator.LMedSInliersData) getInliersData();

        // avoid setting a threshold too strict
        final var threshold = inliersData.getEstimatedThreshold();
        return Math.max(threshold, stopThreshold);
    }
}
File Line
com/irurueta/geometry/estimators/LMedSEuclideanTransformation3DRobustEstimator.java 309
com/irurueta/geometry/estimators/MSACEuclideanTransformation3DRobustEstimator.java 275
com/irurueta/geometry/estimators/PROMedSEuclideanTransformation3DRobustEstimator.java 554
com/irurueta/geometry/estimators/PROSACEuclideanTransformation3DRobustEstimator.java 614
com/irurueta/geometry/estimators/RANSACEuclideanTransformation3DRobustEstimator.java 358
@Override
                    public void estimatePreliminarSolutions(
                            final int[] samplesIndices, final List<EuclideanTransformation3D> solutions) {
                        subsetInputPoints.clear();
                        subsetOutputPoints.clear();
                        for (final var samplesIndex : samplesIndices) {
                            subsetInputPoints.add(inputPoints.get(samplesIndex));
                            subsetOutputPoints.add(outputPoints.get(samplesIndex));
                        }

                        try {
                            nonRobustEstimator.setPoints(subsetInputPoints, subsetOutputPoints);
                            solutions.add(nonRobustEstimator.estimate());
                        } catch (final Exception e) {
                            // if points are coincident, no solution is added
                        }
                    }

                    @Override
                    public double computeResidual(final EuclideanTransformation3D currentEstimation, int i) {
File Line
com/irurueta/geometry/AffineTransformation2D.java 775
com/irurueta/geometry/ProjectiveTransformation2D.java 1109
final var c = inputConic.asMatrix();
        final var invT = inverseAndReturnNew().asMatrix();
        // normalize transformation matrix invT to increase accuracy
        var norm = Utils.normF(invT);
        invT.multiplyByScalar(1.0 / norm);

        final var m = invT.transposeAndReturnNew();
        try {
            m.multiply(c);
            m.multiply(invT);
        } catch (final WrongSizeException ignore) {
            // never happens
        }

        // normalize resulting m matrix to increase accuracy so that it can be
        // considered symmetric
        norm = Utils.normF(m);
        m.multiplyByScalar(1.0 / norm);

        outputConic.setParameters(m);
    }

    /**
     * Transforms a dual conic using this transformation and stores the result
     * into provided output dual conic.
     *
     * @param inputDualConic  dual conic to be transformed.
     * @param outputDualConic instance where data of transformed dual conic will
     *                        be stored.
     * @throws NonSymmetricMatrixException raised if due to numerical precision
     *                                     the resulting output dual conic matrix is not considered to be symmetric.
     */
    @Override
    public void transform(final DualConic inputDualConic, final DualConic outputDualConic)
            throws NonSymmetricMatrixException {
File Line
com/irurueta/geometry/AffineTransformation3D.java 839
com/irurueta/geometry/ProjectiveTransformation3D.java 1183
final var q = inputQuadric.asMatrix();
        final var invT = inverseAndReturnNew().asMatrix();
        // normalize transformation matrix invT to increase accuracy
        var norm = Utils.normF(invT);
        invT.multiplyByScalar(1.0 / norm);

        final var m = invT.transposeAndReturnNew();
        try {
            m.multiply(q);
            m.multiply(invT);
        } catch (final WrongSizeException ignore) {
            // never happens
        }

        // normalize resulting m matrix to increase accuracy so that it can be
        // considered symmetric
        norm = Utils.normF(m);
        m.multiplyByScalar(1.0 / norm);

        outputQuadric.setParameters(m);
    }

    /**
     * Transforms a dual quadric using this transformation and stores the result
     * into provided output dual quadric.
     *
     * @param inputDualQuadric  dual quadric to be transformed.
     * @param outputDualQuadric instance where data of transformed dual quadric
     *                          will be stored.
     * @throws NonSymmetricMatrixException raised if due to numerical precision
     *                                     the resulting output dual conic matrix is not considered to be symmetric.
     */
    @Override
    public void transform(final DualQuadric inputDualQuadric, final DualQuadric outputDualQuadric)
            throws NonSymmetricMatrixException {
File Line
com/irurueta/geometry/EuclideanTransformation2D.java 422
com/irurueta/geometry/ProjectiveTransformation2D.java 1109
final var c = inputConic.asMatrix();
        final var invT = inverseAndReturnNew().asMatrix();
        // normalize transformation matrix T to increase accuracy
        var norm = Utils.normF(invT);
        invT.multiplyByScalar(1.0 / norm);

        final var m = invT.transposeAndReturnNew();
        try {
            m.multiply(c);
            m.multiply(invT);
        } catch (final WrongSizeException ignore) {
            // never happens
        }

        // normalize resulting m matrix to increase accuracy so that it can be
        // considered symmetric
        norm = Utils.normF(m);
        m.multiplyByScalar(1.0 / norm);

        outputConic.setParameters(m);
    }

    /**
     * Transforms a dual conic using this transformation and stores the result
     * into provided output dual conic.
     *
     * @param inputDualConic  dual conic to be transformed.
     * @param outputDualConic instance where data of transformed dual conic will
     *                        be stored.
     * @throws NonSymmetricMatrixException raised if due to numerical precision
     *                                     the resulting output dual conic matrix is not considered to be symmetric.
     */
    @Override
    public void transform(final DualConic inputDualConic, final DualConic outputDualConic)
            throws NonSymmetricMatrixException {
File Line
com/irurueta/geometry/EuclideanTransformation3D.java 463
com/irurueta/geometry/ProjectiveTransformation3D.java 1183
final var q = inputQuadric.asMatrix();
        final var invT = inverseAndReturnNew().asMatrix();
        // normalize transformation matrix invT to increase accuracy
        var norm = Utils.normF(invT);
        invT.multiplyByScalar(1.0 / norm);

        final var m = invT.transposeAndReturnNew();
        try {
            m.multiply(q);
            m.multiply(invT);
        } catch (final WrongSizeException ignore) {
            // never happens
        }

        // normalize resulting m matrix to increase accuracy so that it can be
        // considered symmetric
        norm = Utils.normF(m);
        m.multiplyByScalar(1.0 / norm);

        outputQuadric.setParameters(m);
    }

    /**
     * Transforms a dual quadric using this transformation and stores the result
     * into provided output dual quadric.
     *
     * @param inputDualQuadric  dual quadric to be transformed.
     * @param outputDualQuadric instance where data of transformed dual quadric
     *                          will be stored.
     * @throws NonSymmetricMatrixException raised if due to numerical precision.
     *                                     the resulting output dual quadric matrix is not considered to be
     *                                     symmetric.
     */
    @Override
    public void transform(final DualQuadric inputDualQuadric, final DualQuadric outputDualQuadric)
            throws NonSymmetricMatrixException {
File Line
com/irurueta/geometry/Quaternion.java 1108
com/irurueta/geometry/Quaternion.java 1216
public void quaternionMatrix(final Matrix result) {
        if (result.getRows() != N_PARAMS || result.getColumns() != N_PARAMS) {
            throw new IllegalArgumentException("matrix must be 4x4");
        }

        result.setElementAt(0, 0, a);
        result.setElementAt(1, 0, b);
        result.setElementAt(2, 0, c);
        result.setElementAt(3, 0, d);

        result.setElementAt(0, 1, -b);
        result.setElementAt(1, 1, a);
        result.setElementAt(2, 1, d);
File Line
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1117
com/irurueta/geometry/estimators/EPnPPointCorrespondencePinholeCameraEstimator.java 1175
final var vcjz = vcj.getInhomZ();

        // 1st column
        c.setElementAt(row, 0, Math.pow(vaix - vajx, 2.0) + Math.pow(vaiy - vajy, 2.0)
                + Math.pow(vaiz - vajz, 2.0));

        // 2nd column
        c.setElementAt(row, 1, 2.0 * ((vaix - vajx) * (vbix - vbjx) + (vaiy - vajy) * (vbiy - vbjy)
                + (vaiz - vajz) * (vbiz - vbjz)));

        // 3rd column
        c.setElementAt(row, 2, 2.0 * ((vaix - vajx) * (vcix - vcjx) + (vaiy - vajy) * (vciy - vcjy)
File Line
com/irurueta/geometry/estimators/MSACEuclideanTransformation2DRobustEstimator.java 249
com/irurueta/geometry/estimators/PROSACEuclideanTransformation2DRobustEstimator.java 587
com/irurueta/geometry/estimators/RANSACEuclideanTransformation2DRobustEstimator.java 333
new MSACRobustEstimatorListener<EuclideanTransformation2D>() {

                    // point to be reused when computing residuals
                    private final Point2D testPoint = Point2D.create(CoordinatesType.HOMOGENEOUS_COORDINATES);

                    private final EuclideanTransformation2DEstimator nonRobustEstimator =
                            new EuclideanTransformation2DEstimator(isWeakMinimumSizeAllowed());

                    private final List<Point2D> subsetInputPoints = new ArrayList<>();
                    private final List<Point2D> subsetOutputPoints = new ArrayList<>();

                    @Override
                    public double getThreshold() {
                        return threshold;
                    }

                    @Override
                    public int getTotalSamples() {
                        return inputPoints.size();
                    }

                    @Override
                    public int getSubsetSize() {
                        return nonRobustEstimator.getMinimumPoints();
                    }

                    @Override
File Line
com/irurueta/geometry/refiners/DecomposedLinePlaneCorrespondencePinholeCameraRefiner.java 394
com/irurueta/geometry/refiners/NonDecomposedLinePlaneCorrespondencePinholeCameraRefiner.java 210
return residualLevenbergMarquardt(pinholeCamera, line, plane, params, weight);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {

                    line.setParameters(point[0], point[1], point[2]);
                    plane.setParameters(point[3], point[4], point[5], point[6]);
File Line
com/irurueta/geometry/refiners/DecomposedPointCorrespondencePinholeCameraRefiner.java 397
com/irurueta/geometry/refiners/NonDecomposedPointCorrespondencePinholeCameraRefiner.java 211
return residualLevenbergMarquardt(pinholeCamera, point3D, point2D, params, weight);
                });

                @Override
                public int getNumberOfDimensions() {
                    return nDims;
                }

                @Override
                public double[] createInitialParametersArray() {
                    return initParams;
                }

                @Override
                public double evaluate(final int i, final double[] point, final double[] params,
                                       final double[] derivatives) throws EvaluationException {
                    point2D.setHomogeneousCoordinates(point[0], point[1], point[2]);
                    point3D.setHomogeneousCoordinates(point[3], point[4], point[5], point[6]);
File Line
com/irurueta/geometry/estimators/MSACCircleRobustEstimator.java 226
com/irurueta/geometry/estimators/MSACConicRobustEstimator.java 229
com/irurueta/geometry/estimators/MSACDualConicRobustEstimator.java 233
com/irurueta/geometry/estimators/MSACDualQuadricRobustEstimator.java 237
com/irurueta/geometry/estimators/MSACLine2DRobustEstimator.java 224
com/irurueta/geometry/estimators/MSACPlaneRobustEstimator.java 226
com/irurueta/geometry/estimators/MSACQuadricRobustEstimator.java 236
com/irurueta/geometry/estimators/MSACSphereRobustEstimator.java 227
listener.onEstimateProgressChange(MSACCircleRobustEstimator.this, progress);
                }
            }
        });

        try {
            locked = true;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            return innerEstimator.estimate();
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.MSAC;
    }
}
File Line
com/irurueta/geometry/estimators/RANSACCircleRobustEstimator.java 226
com/irurueta/geometry/estimators/RANSACConicRobustEstimator.java 232
com/irurueta/geometry/estimators/RANSACDualConicRobustEstimator.java 232
com/irurueta/geometry/estimators/RANSACDualQuadricRobustEstimator.java 237
com/irurueta/geometry/estimators/RANSACLine2DRobustEstimator.java 225
com/irurueta/geometry/estimators/RANSACPlaneRobustEstimator.java 226
com/irurueta/geometry/estimators/RANSACQuadricRobustEstimator.java 236
com/irurueta/geometry/estimators/RANSACSphereRobustEstimator.java 227
listener.onEstimateProgressChange(RANSACCircleRobustEstimator.this, progress);
                }
            }
        });

        try {
            locked = true;
            innerEstimator.setConfidence(confidence);
            innerEstimator.setMaxIterations(maxIterations);
            innerEstimator.setProgressDelta(progressDelta);
            return innerEstimator.estimate();
        } catch (final com.irurueta.numerical.LockedException e) {
            throw new LockedException(e);
        } catch (final com.irurueta.numerical.NotReadyException e) {
            throw new NotReadyException(e);
        } finally {
            locked = false;
        }
    }

    /**
     * Returns method being used for robust estimation.
     *
     * @return method being used for robust estimation.
     */
    @Override
    public RobustEstimatorMethod getMethod() {
        return RobustEstimatorMethod.RANSAC;
    }
}