Java Array Distance findMaxDistance24(Double[] quad2, Double[] quad4)

Here you can find the source of findMaxDistance24(Double[] quad2, Double[] quad4)

Description

Finds the maximum separation between two points that are in quadrant2 and quadrant4.

License

Open Source License

Parameter

Parameter Description
quad2 a parameter
quad4 a parameter
angleZero a parameter
angleMax a parameter

Declaration

private static Double findMaxDistance24(Double[] quad2, Double[] quad4) 

Method Source Code

//package com.java2s;
/*//  w w w  . ja  va 2s.  c  om
 * Copyright (C) 2011 apurv
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

public class Main {
    /**
     * Temporary variable for storing the immediate result of calculations.
     */
    private static Double angleZero = Double.NaN;
    /**
     * Temporary variable for storing the immediate result of calculations.
     */
    private static Double angleMax = Double.NaN;
    /**
     * All initializations are done to this value.
     * Also used as a minimum value for distances.
     */
    private static double UNDEFINED = -1.0;

    /**
     * Finds the maximum separation between two points that are in quadrant2 and quadrant4.
     * @param quad2
     * @param quad4
     * @param angleZero
     * @param angleMax
     * @return 
     */
    private static Double findMaxDistance24(Double[] quad2, Double[] quad4) {

        if (quad2.length == 0 || quad4.length == 0) {
            angleZero = Double.NaN;
            angleMax = Double.NaN;
            return UNDEFINED;
        }

        return findMaxDistance13(quad2, quad4);
    }

    /**
     * Finds the maximum separation between two points that are in quadrant1 and quadrant3.
     * Employs a search method similar to binary search. O(n log n) algorithm.
     * @param quad1
     * @param quad3
     * @param angleZero
     * @param angleMax
     * @return 
     */
    private static Double findMaxDistance13(Double[] quad1, Double[] quad3) {

        if (quad1.length == 0 || quad3.length == 0) {
            angleZero = Double.NaN;
            angleMax = Double.NaN;
            return UNDEFINED;
        }

        Double maxDistance = UNDEFINED;
        angleZero = quad1[0];
        angleMax = quad3[0];

        for (Double x : quad1) {
            Double y = findDiametricallyOppositeAngle(x);
            Double z = findClosestAngle(y, quad3);
            Double angularDistance = findMinAngularDistance(z, x);

            if (angularDistance > maxDistance) {
                maxDistance = angularDistance;
                angleZero = x;
                angleMax = z;
            }
        }

        maxDistance = findMinAngularDistance(angleZero, angleMax);

        return maxDistance;
    }

    /**
     * Finds the diametrically opposite angle to this angle.<br>
     * The diametrically opposite angle to 2.5 is -177.5
     * @param angle
     * @return
     */
    private static double findDiametricallyOppositeAngle(double angle) {
        double oppAngle = 0.0;
        double sgn = Math.signum(angle);
        if (sgn == 0) {
            sgn += 1.0;
        }
        oppAngle = -1 * sgn * (180 - Math.abs(angle));
        return oppAngle;
    }

    /**
     * Finds the closest value in quad that is closest in distance to angle.
     * @param angle
     * @param quad
     * @return 
     */
    private static double findClosestAngle(double angle, Double[] quad) {
        double closestAngle = 0;
        int l = 0;
        int u = quad.length - 1;
        int mid = (l + u) / 2;
        while (l <= u) {

            mid = (l + u) / 2;
            if (angle > quad[mid]) {
                l = mid + 1;

            } else if (angle < quad[mid]) {
                u = mid - 1;

            } else {
                break;
            }
        }
        mid = (l + u) / 2;
        closestAngle = quad[mid];

        //IMP: The closestAngle obtained above is the angle just smaller than angle in the array quad.
        //     As an additional correction we need to check which among quad[mid] and quad[mid+1] is closer to angle.
        //     Also the case when size of quad is 1 is also handled.
        //Begin Correction
        if (mid + 1 < quad.length) {
            Double closestAngle1 = quad[mid];
            Double closestAngle2 = quad[mid + 1];
            Double distance1 = findMinAngularDistance(closestAngle1, angle);
            Double distance2 = findMinAngularDistance(closestAngle2, angle);
            if (distance1 < distance2) {
                closestAngle = closestAngle1;

            } else {
                closestAngle = closestAngle2;

            }
        }
        //End Correction

        return closestAngle;
    }

    /**
     * Finds the minimum angular distance between two angles.
     * @param angle1
     * @param angle2
     * @return
     */
    private static double findMinAngularDistance(double angle1, double angle2) {
        double angDistance = 0.0;
        if (Math.signum(angle2) == Math.signum(angle1)) {
            angDistance = Math.abs(angle2 - angle1);
        } else {
            double sumAngle = Math.abs(angle1) + Math.abs(angle2);
            angDistance = Math.min(sumAngle, 360 - sumAngle);
        }
        return angDistance;
    }
}

Related

  1. findMaxDistanceAA(Double[] quadA)