Example usage for java.lang Double POSITIVE_INFINITY

List of usage examples for java.lang Double POSITIVE_INFINITY

Introduction

In this page you can find the example usage for java.lang Double POSITIVE_INFINITY.

Prototype

double POSITIVE_INFINITY

To view the source code for java.lang Double POSITIVE_INFINITY.

Click Source Link

Document

A constant holding the positive infinity of type double .

Usage

From source file:eu.cassandra.sim.utilities.Utils.java

/**
 * Function copied by the Mallet toolbox: http://mallet.cs.umass.edu
 *
 * Returns the KL divergence, K(p1 || p2).
 *
 * The log is w.r.t. base 2. <p>//w ww .  j  a  va  2s .  c  o  m
 *
 * *Note*: If any value in <tt>p2</tt> is <tt>0.0</tt> then the KL-divergence
 * is <tt>infinite</tt>. 
 * 
 */
public static double klDivergence(double[] p1, double[] p2) {
    assert (p1.length == p2.length);
    double klDiv = 0.0;
    for (int i = 0; i < p1.length; ++i) {
        if (p1[i] == 0) {
            continue;
        }
        if (p2[i] == 0) {
            return Double.POSITIVE_INFINITY;
        }
        klDiv += p1[i] * Math.log(p1[i] / p2[i]);
    }
    return klDiv / Math.log(2);
}

From source file:geogebra.common.kernel.algos.AlgoConicFivePoints.java

@Override
public void compute() {
    // compute lines P0 P1, P2 P3,
    // P0 P2, P1 P3
    GeoVec3D.cross(P[0], P[1], line[0]);
    GeoVec3D.cross(P[2], P[3], line[1]);
    GeoVec3D.cross(P[0], P[2], line[2]);
    GeoVec3D.cross(P[1], P[3], line[3]);

    // compute degenerate conics A = line[0] u line[1],
    // B = line[2] u line[3]
    degCone(line[0], line[1], A);/*from w ww .  j a v  a2  s  .c  o m*/
    degCone(line[2], line[3], B);
    e1 = evalMatrix(B, P[4]);
    e2 = -evalMatrix(A, P[4]);

    // try to avoid tiny/huge value for matrix
    if (shouldInvert(e1) && shouldInvert(e2)) {

        double tmp = e1;

        e1 = 1 / e2;
        e2 = 1 / tmp;
    }

    linComb(A, B, e1, e2, C);

    /***
     * Perturbation method to estimate the error of "detS" of the conic
     * 
     * The following is a random perturbation method to estimate detS it is
     * commented out because (1) it is not deterministic (2) it still can't
     * solve the problem of #1294
     * 
     * Tam 6/9/2012
     */

    /*
     * // compute a perturbed Cpert kernel.setSilentMode(true); Ppert = new
     * GeoPoint2[5]; for (int i=0; i<5; i++) { Ppert[i] = new
     * GeoPoint2(P[i]);
     * 
     * }
     */

    /*
     * double maxDistSqr = 0; double temp; int maxDistP1 = 0; int maxDistP2
     * = 0;
     * 
     * 
     * for (int i=0; i<5; i++) { temp = P[0].distanceSqr(P[i]); if ( temp >
     * maxDistSqr) { maxDistP2 = i; maxDistSqr = temp; } } for (int i=0;
     * i<5; i++) { temp = P[i].distanceSqr(P[maxDistP2]); if (temp >
     * maxDistSqr) { maxDistP1 = i; maxDistSqr = temp; } }
     * 
     * if (maxDistSqr!=0) { double t = Kernel.EPSILON/Math.sqrt(maxDistSqr);
     * Ppert[maxDistP1].setCoords( P[maxDistP1].inhomX * (1+t) -
     * P[maxDistP2].inhomX * t, P[maxDistP1].inhomY * (1+t) -
     * P[maxDistP2].inhomY * t, 1 ); Ppert[maxDistP2].setCoords(
     * P[maxDistP2].inhomX * (1+t) - P[maxDistP1].inhomX * t,
     * P[maxDistP2].inhomY * (1+t) - P[maxDistP1].inhomY * t, 1 );
     */

    /*
     * perturbation for finding out deltaS
     */
    /*
     * delta = Kernel.MIN_PRECISION; int repetition = 5; for (int m=0; m<3;
     * m++) for (int n=0; n<3; n++) Cmin[m][n]=Double.POSITIVE_INFINITY;
     * 
     * for (int k=0; k<repetition; k++) { for (int i=0; i<5; i++) {
     * Ppert[i].randomizeForErrorEstimation(); }
     * 
     * GeoVec3D.cross(Ppert[0], Ppert[1], line[0]); GeoVec3D.cross(Ppert[2],
     * Ppert[3], line[1]); GeoVec3D.cross(Ppert[0], Ppert[2], line[2]);
     * GeoVec3D.cross(Ppert[1], Ppert[3], line[3]); degCone(line[0],
     * line[1], A); degCone(line[2], line[3], B); l = evalMatrix(B,
     * Ppert[4]); m = -evalMatrix(A, Ppert[4]); linComb(A, B, l, m, Cpert);
     * 
     * //calculate the estimation of error of detS delta = Math.min(delta,
     * Math.abs( Cpert[0][0]*Cpert[1][1] -
     * (Cpert[0][1]+Cpert[1][0])*(Cpert[0][1]+Cpert[1][0])/4)); for (int
     * m=0; m<3; m++) for (int n=m; n<3; n++)
     * Cmin[m][n]=Math.min(Cmin[m][n],
     * Math.abs((Cpert[m][n]+Cpert[n][m])/2));
     * 
     * }
     * 
     * conic.errDetS = delta; //TODO: this is not reasonable enough. if
     * (Math.abs(C[0][0])< Math.abs(Cmin[0][0])/10) C[0][0]=0; if
     * (Math.abs(C[1][1])< Math.abs(Cmin[1][1])/10) C[1][1]=0; if
     * (Math.abs(C[0][1] + C[1][0])< Math.abs( Cmin[0][1]) /5 ) { C[0][1]=0;
     * C[1][0]=0; }
     */
    /**
     * perturbation method ends
     */

    /***
     * Testing: use analytic method:
     * 
     * solving system of linear equations
     * 
     * uses:
     * 
     * import org.apache.commons.math.linear.AbstractFieldMatrix; import
     * org.apache.commons.math.linear.Array2DRowFieldMatrix; import
     * org.apache.commons.math.linear.Array2DRowRealMatrix; import
     * org.apache.commons.math.linear.FieldMatrix; import
     * org.apache.commons.math.linear.DecompositionSolver; import
     * org.apache.commons.math.linear.QRDecompositionImpl; import
     * org.apache.commons.math.linear.RealMatrix; import
     * org.apache.commons.math.linear.SingularValueDecompositionImpl; import
     * org.apache.commons.math.util.BigReal;
     */
    /*
     * RealMatrix coeffM = new Array2DRowRealMatrix(5, 6);
     * 
     * for (int i = 0; i<5; i++) { coeffM.setRow(i, new double[]
     * {P[i].inhomX * P[i].inhomX,P[i].inhomX * P[i].inhomY,P[i].inhomY *
     * P[i].inhomY, P[i].inhomX , P[i].inhomY, 1.0}); }
     * 
     * SingularValueDecompositionImpl solver = new
     * SingularValueDecompositionImpl(coeffM);
     * 
     * solver.getSolver().solve(new double[] {0,0,0,0,0});
     * 
     * //RealMatrix test1 = solver.getV().multiply(solver.getVT());
     * //RealMatrix test2 = solver.getVT().multiply(solver.getV());
     * 
     * int key = -1; double keysum = 1; for (i=0; i<6; i++) { double sum =
     * 0; for (j=0; j<5; j++) { sum += solver.getV().getEntry(i,j) *
     * solver.getV().getEntry(i,j); } if (sum < keysum) { key = i; keysum =
     * sum; } }
     * 
     * double[] xx = new double[6]; double[] v6 = new double[6]; if
     * (!Kernel.isZero(1-keysum)) { xx[5] = 1/(1-keysum); for (int j=0; j<5;
     * j++) { xx[j] = -xx[5]*solver.getV().getEntry(key,j); } }
     * 
     * for (int i=0; i<5; i++) { v6[i] = 0; }
     * 
     * v6[key] = xx[5];
     * 
     * for (int i=0; i<6; i++) { for (int j=0; j<5; j++) { v6[i] += xx[j] *
     * solver.getV().getEntry(i,j); } }
     * 
     * RealMatrix checkSol = new Array2DRowRealMatrix(6,1);
     * checkSol.setColumn(0, v6); RealMatrix check =
     * coeffM.multiply(checkSol); //double[] solution =
     * solver.getg.getV().getColumn(5); for (int i=0;
     * i<check.getRowDimension(); i++) {
     * System.out.println(check.getRow(1).toString()); }
     * 
     * conic.setMatrix(new double[]
     * {v6[0],v6[2],v6[5],v6[1]/2,v6[3]/2,v6[4]/2});
     */
    /***
     * solving system of linear equations test ends
     ***/

    /***
     * critical case: five points lie on an unstable conic now only for
     * parabola. Need more tests for: one line; two lines; one point; two
     * points
     */

    if (criticalCase) {
        conic.errDetS = Double.POSITIVE_INFINITY;
    } else {
        conic.errDetS = Kernel.MIN_PRECISION;
    }

    conic.setMatrix(C);
    // System.out.println(conic.getTypeString());

}

From source file:com.datumbox.framework.core.statistics.distributions.ContinuousDistributions.java

/**
 * Returns the z score of a specific pvalue for Gaussian
 * Partially ported from http://home.online.no/~pjacklam/notes/invnorm/impl/karimov/StatUtil.java
 * Other implementations http://home.online.no/~pjacklam/notes/invnorm/index.html#Java
 * //from   w w  w.  j  av a2s .  co  m
 * @param p
 * @return 
 */
public static double gaussInverseCdf(double p) {
    final double P_LOW = 0.02425D;
    final double P_HIGH = 1.0D - P_LOW;
    final double ICDF_A[] = { -3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02,
            1.383577518672690e+02, -3.066479806614716e+01, 2.506628277459239e+00 };
    final double ICDF_B[] = { -5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02,
            6.680131188771972e+01, -1.328068155288572e+01 };
    final double ICDF_C[] = { -7.784894002430293e-03, -3.223964580411365e-01, -2.400758277161838e+00,
            -2.549732539343734e+00, 4.374664141464968e+00, 2.938163982698783e+00 };
    final double ICDF_D[] = { 7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00,
            3.754408661907416e+00 };

    // Define break-points.
    // variable for result
    double z;

    if (p == 0) {
        z = Double.NEGATIVE_INFINITY;
    } else if (p == 1) {
        z = Double.POSITIVE_INFINITY;
    } else if (Double.isNaN(p) || p < 0 || p > 1) {
        z = Double.NaN;
    } else if (p < P_LOW) { // Rational approximation for lower region:
        double q = Math.sqrt(-2 * Math.log(p));
        z = (((((ICDF_C[0] * q + ICDF_C[1]) * q + ICDF_C[2]) * q + ICDF_C[3]) * q + ICDF_C[4]) * q + ICDF_C[5])
                / ((((ICDF_D[0] * q + ICDF_D[1]) * q + ICDF_D[2]) * q + ICDF_D[3]) * q + 1);
    } else if (P_HIGH < p) { // Rational approximation for upper region:
        double q = Math.sqrt(-2 * Math.log(1 - p));
        z = -(((((ICDF_C[0] * q + ICDF_C[1]) * q + ICDF_C[2]) * q + ICDF_C[3]) * q + ICDF_C[4]) * q + ICDF_C[5])
                / ((((ICDF_D[0] * q + ICDF_D[1]) * q + ICDF_D[2]) * q + ICDF_D[3]) * q + 1);
    } else { // Rational approximation for central region:
        double q = p - 0.5D;
        double r = q * q;
        z = (((((ICDF_A[0] * r + ICDF_A[1]) * r + ICDF_A[2]) * r + ICDF_A[3]) * r + ICDF_A[4]) * r + ICDF_A[5])
                * q
                / (((((ICDF_B[0] * r + ICDF_B[1]) * r + ICDF_B[2]) * r + ICDF_B[3]) * r + ICDF_B[4]) * r + 1);
    }

    return z;
}

From source file:net.sourceforge.jasa.report.HistoricalDataReport.java

protected void initialisePriceRanges() {
    highestBidPrice = Double.NEGATIVE_INFINITY;
    lowestAskPrice = Double.POSITIVE_INFINITY;

    highestUnacceptedBid = null;/*w w  w. j a v  a 2  s.  c  o m*/
    lowestUnacceptedAsk = null;
}

From source file:it.unibo.alchemist.model.implementations.reactions.SAPEREReaction.java

@Override
protected void updateInternalStatus(final Time curTime, final boolean executed,
        final Environment<List<ILsaMolecule>> env) {
    if (emptyExecution) {
        emptyExecution = false;// w  w w  . j a  v  a 2 s  .co  m
        totalPropensity = 0;
    } else {
        /*
         * Valid nodes must be re-inited, as per issue #
         */
        final Collection<Node<List<ILsaMolecule>>> neighs = environment.getNeighborhood(getNode())
                .getNeighbors();
        validNodes = new ArrayList<>(neighs.size());
        for (final Node<List<ILsaMolecule>> neigh : neighs) {
            validNodes.add((ILsaNode) neigh);
        }
        if (getConditions().isEmpty()) {
            totalPropensity = getTimeDistribution().getRate();
        } else {
            totalPropensity = 0d;
            possibleMatches = new ArrayList<>();
            propensities = new ArrayList<>();
            possibleRemove = new ArrayList<>();
            /*
             * Apply all the conditions as filters
             */
            for (final ILsaCondition cond : getSAPEREConditions()) {
                if (!cond.filter(possibleMatches, validNodes, possibleRemove)) {
                    /*
                     * It is supposed that a condition fails if it must put null
                     * in the filter lists, so null values are not expected.
                     */
                    return;
                }
            }
            if (numericRate()) {
                totalPropensity = possibleMatches.size() * getTimeDistribution().getRate();
            } else {
                /*
                 * For each possible match, compute the propensity
                 */
                for (final Map<HashString, ITreeNode<?>> match : possibleMatches) {
                    timedist.setMatches(match);
                    final double p = timedist.getRate();
                    propensities.add(p);
                    totalPropensity += p;
                    if (totalPropensity == Double.POSITIVE_INFINITY) {
                        return;
                    }
                }
            }
        }
    }
}

From source file:com.datumbox.framework.statistics.distributions.ContinuousDistributions.java

/**
 * Returns the z score of a specific pvalue for Gaussian
 * Partially ported from http://home.online.no/~pjacklam/notes/invnorm/impl/karimov/StatUtil.java
 * Other implementations http://home.online.no/~pjacklam/notes/invnorm/index.html#Java
 * /*from  ww w.  j  a  va 2s  . c  om*/
 * @param p
 * @return 
 */
public static double GaussInverseCdf(double p) {
    final double P_LOW = 0.02425D;
    final double P_HIGH = 1.0D - P_LOW;
    final double ICDF_A[] = { -3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02,
            1.383577518672690e+02, -3.066479806614716e+01, 2.506628277459239e+00 };
    final double ICDF_B[] = { -5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02,
            6.680131188771972e+01, -1.328068155288572e+01 };
    final double ICDF_C[] = { -7.784894002430293e-03, -3.223964580411365e-01, -2.400758277161838e+00,
            -2.549732539343734e+00, 4.374664141464968e+00, 2.938163982698783e+00 };
    final double ICDF_D[] = { 7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00,
            3.754408661907416e+00 };

    // Define break-points.
    // variable for result
    double z = 0;

    if (p == 0) {
        z = Double.NEGATIVE_INFINITY;
    } else if (p == 1) {
        z = Double.POSITIVE_INFINITY;
    } else if (Double.isNaN(p) || p < 0 || p > 1) {
        z = Double.NaN;
    } else if (p < P_LOW) { // Rational approximation for lower region:
        double q = Math.sqrt(-2 * Math.log(p));
        z = (((((ICDF_C[0] * q + ICDF_C[1]) * q + ICDF_C[2]) * q + ICDF_C[3]) * q + ICDF_C[4]) * q + ICDF_C[5])
                / ((((ICDF_D[0] * q + ICDF_D[1]) * q + ICDF_D[2]) * q + ICDF_D[3]) * q + 1);
    } else if (P_HIGH < p) { // Rational approximation for upper region:
        double q = Math.sqrt(-2 * Math.log(1 - p));
        z = -(((((ICDF_C[0] * q + ICDF_C[1]) * q + ICDF_C[2]) * q + ICDF_C[3]) * q + ICDF_C[4]) * q + ICDF_C[5])
                / ((((ICDF_D[0] * q + ICDF_D[1]) * q + ICDF_D[2]) * q + ICDF_D[3]) * q + 1);
    } else { // Rational approximation for central region:
        double q = p - 0.5D;
        double r = q * q;
        z = (((((ICDF_A[0] * r + ICDF_A[1]) * r + ICDF_A[2]) * r + ICDF_A[3]) * r + ICDF_A[4]) * r + ICDF_A[5])
                * q
                / (((((ICDF_B[0] * r + ICDF_B[1]) * r + ICDF_B[2]) * r + ICDF_B[3]) * r + ICDF_B[4]) * r + 1);
    }

    return z;
}

From source file:com.taobao.weex.devtools.json.ObjectMapper.java

private Object getJsonValue(Object value, Class<?> clazz, Field field)
        throws InvocationTargetException, IllegalAccessException {
    if (value == null) {
        // Now technically we /could/ return JsonNode.NULL here but Chrome's webkit inspector croaks
        // if you pass a null "id"
        return null;
    }/*from   w ww  . j  a v a  2  s  .c  o m*/
    if (List.class.isAssignableFrom(clazz)) {
        return convertListToJsonArray(value);
    }
    // Finally check to see if there is a JsonValue present
    Method m = getJsonValueMethod(clazz);
    if (m != null) {
        return m.invoke(value);
    }
    if (!canDirectlySerializeClass(clazz)) {
        return convertValue(value, JSONObject.class);
    }
    // JSON has no support for NaN, Infinity or -Infinity, so we serialize
    // then as strings. Google Chrome's inspector will accept them just fine.
    if (clazz.equals(Double.class) || clazz.equals(Float.class)) {
        double doubleValue = ((Number) value).doubleValue();
        if (Double.isNaN(doubleValue)) {
            return "NaN";
        } else if (doubleValue == Double.POSITIVE_INFINITY) {
            return "Infinity";
        } else if (doubleValue == Double.NEGATIVE_INFINITY) {
            return "-Infinity";
        }
    }
    // hmm we should be able to directly serialize here...
    return value;
}

From source file:io.druid.server.coordinator.CostBalancerStrategy.java

/**
 * For assignment, we want to move to the lowest cost server that isn't already serving the segment.
 *
 * @param proposalSegment A DataSegment that we are proposing to move.
 * @param serverHolders   An iterable of ServerHolders for a particular tier.
 *
 * @return A ServerHolder with the new home for a segment.
 *//*from   w  ww  .  jav a  2s . c o m*/

protected Pair<Double, ServerHolder> chooseBestServer(final DataSegment proposalSegment,
        final Iterable<ServerHolder> serverHolders, final boolean includeCurrentServer) {
    Pair<Double, ServerHolder> bestServer = Pair.of(Double.POSITIVE_INFINITY, null);

    List<ListenableFuture<Pair<Double, ServerHolder>>> futures = Lists.newArrayList();

    for (final ServerHolder server : serverHolders) {
        futures.add(exec.submit(new Callable<Pair<Double, ServerHolder>>() {
            @Override
            public Pair<Double, ServerHolder> call() throws Exception {
                return Pair.of(computeCost(proposalSegment, server, includeCurrentServer), server);
            }
        }));
    }

    final ListenableFuture<List<Pair<Double, ServerHolder>>> resultsFuture = Futures.allAsList(futures);

    try {
        for (Pair<Double, ServerHolder> server : resultsFuture.get()) {
            if (server.lhs < bestServer.lhs) {
                bestServer = server;
            }
        }
    } catch (Exception e) {
        log.makeAlert(e, "Cost Balancer Multithread strategy wasn't able to complete cost computation.").emit();
    }
    return bestServer;
}

From source file:com.rapidminer.gui.new_plotter.engine.jfreechart.ChartAxisFactory.java

private static Pair<Double, Double> calculateUpperAndLowerBounds(ValueSource valueSource,
        PlotInstance plotInstance) {//from   ww  w .  ja va  2 s  . c  o m

    Pair<Double, Double> minMax = new Pair<Double, Double>(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);

    ValueSourceData valueSourceData = plotInstance.getPlotData().getValueSourceData(valueSource);
    GroupCellSeriesData dataForAllGroupCells = valueSourceData.getSeriesDataForAllGroupCells();

    Map<Double, Double> stackedYValues = new HashMap<Double, Double>();

    // Loop all group cells and add data to dataset
    for (GroupCellKeyAndData groupCellKeyAndData : dataForAllGroupCells) {
        GroupCellData groupCellData = groupCellKeyAndData.getData();

        Map<PlotDimension, double[]> dataForUsageType = groupCellData
                .getDataForUsageType(SeriesUsageType.MAIN_SERIES);
        double[] xValues = dataForUsageType.get(PlotDimension.DOMAIN);
        double[] yValues = dataForUsageType.get(PlotDimension.VALUE);
        int rowCount = xValues.length;

        // Loop all rows and add data to series
        for (int row = 0; row < rowCount; ++row) {
            Double x = xValues[row];
            Double stackedYValue = stackedYValues.get(x);
            double d = yValues[row];
            if (!Double.isNaN(d)) {
                if (stackedYValue == null) {
                    stackedYValues.put(x, d);
                } else {
                    double value = stackedYValue + d;
                    stackedYValues.put(x, value);
                }
            }
        }
    }

    for (Double xValue : stackedYValues.keySet()) {
        Double yValue = stackedYValues.get(xValue);
        if (yValue > minMax.getSecond()) {
            minMax.setSecond(yValue);
        }
        if (yValue < minMax.getFirst()) {
            minMax.setFirst(yValue);
        }
    }

    return minMax;
}

From source file:edu.unc.cs.gamma.rvo.Agent.java

/**
 * Computes the new velocity of this agent.
 *//*from  w w w.j  av  a  2  s.  c  o  m*/
void computeNewVelocity() {
    lines.clear();

    final double invTimeHorizonObstacle = 1.0 / timeHorizonObstacles;

    // Create obstacle ORCA lines.
    for (final Pair<Double, Obstacle> obstacleNeighbor : obstacleNeighbors) {
        Obstacle obstacle1 = obstacleNeighbor.getSecond();
        Obstacle obstacle2 = obstacle1.next;

        final Vector2D relativePosition1 = obstacle1.point.subtract(position);
        final Vector2D relativePosition2 = obstacle2.point.subtract(position);

        // Check if velocity obstacle of obstacle is already taken care of
        // by previously constructed obstacle ORCA lines.
        boolean alreadyCovered = false;

        for (final Line orcaLine : lines) {
            if (RVOMath.det(relativePosition1.scalarMultiply(invTimeHorizonObstacle).subtract(orcaLine.point),
                    orcaLine.direction) - invTimeHorizonObstacle * radius >= -RVOMath.EPSILON
                    && RVOMath
                            .det(relativePosition2.scalarMultiply(invTimeHorizonObstacle)
                                    .subtract(orcaLine.point), orcaLine.direction)
                            - invTimeHorizonObstacle * radius >= -RVOMath.EPSILON) {
                alreadyCovered = true;

                break;
            }
        }

        if (alreadyCovered) {
            continue;
        }

        // Not yet covered. Check for collisions.
        final double distanceSq1 = relativePosition1.getNormSq();
        final double distanceSq2 = relativePosition2.getNormSq();
        final double radiusSq = radius * radius;

        final Vector2D obstacleVector = obstacle2.point.subtract(obstacle1.point);
        final double s = -relativePosition1.dotProduct(obstacleVector) / obstacleVector.getNormSq();
        final double distanceSqLine = relativePosition1.add(s, obstacleVector).getNormSq();

        if (s < 0.0 && distanceSq1 <= radiusSq) {
            // Collision with left vertex. Ignore if non-convex.
            if (obstacle1.convex) {
                final Vector2D direction = new Vector2D(-relativePosition1.getY(), relativePosition1.getX())
                        .normalize();
                lines.add(new Line(Vector2D.ZERO, direction));
            }

            continue;
        }

        if (s > 1.0 && distanceSq2 <= radiusSq) {
            // Collision with right vertex. Ignore if non-convex or if it
            // will be taken care of by neighboring obstacle.
            if (obstacle2.convex && RVOMath.det(relativePosition2, obstacle2.direction) >= 0.0) {
                final Vector2D direction = new Vector2D(-relativePosition2.getY(), relativePosition2.getX())
                        .normalize();
                lines.add(new Line(Vector2D.ZERO, direction));
            }

            continue;
        }

        if (s >= 0.0 && s < 1.0 && distanceSqLine <= radiusSq) {
            // Collision with obstacle segment.
            final Vector2D direction = obstacle1.direction.negate();
            lines.add(new Line(Vector2D.ZERO, direction));

            continue;
        }

        // No collision. Compute legs. When obliquely viewed, both legs can
        // come from a single vertex. Legs extend cut-off line when
        // non-convex vertex.
        Vector2D leftLegDirection;
        Vector2D rightLegDirection;

        if (s < 0.0 && distanceSqLine <= radiusSq) {
            // Obstacle viewed obliquely so that left vertex defines
            // velocity obstacle.
            if (!obstacle1.convex) {
                // Ignore obstacle.
                continue;
            }

            obstacle2 = obstacle1;

            final double leg1 = FastMath.sqrt(distanceSq1 - radiusSq);
            leftLegDirection = new Vector2D(relativePosition1.getX() * leg1 - relativePosition1.getY() * radius,
                    relativePosition1.getX() * radius + relativePosition1.getY() * leg1)
                            .scalarMultiply(1.0 / distanceSq1);
            rightLegDirection = new Vector2D(
                    relativePosition1.getX() * leg1 + relativePosition1.getY() * radius,
                    -relativePosition1.getX() * radius + relativePosition1.getY() * leg1)
                            .scalarMultiply(1.0 / distanceSq1);
        } else if (s > 1.0 && distanceSqLine <= radiusSq) {
            // Obstacle viewed obliquely so that right vertex defines
            // velocity obstacle.
            if (!obstacle2.convex) {
                // Ignore obstacle.
                continue;
            }

            obstacle1 = obstacle2;

            final double leg2 = FastMath.sqrt(distanceSq2 - radiusSq);
            leftLegDirection = new Vector2D(relativePosition2.getX() * leg2 - relativePosition2.getY() * radius,
                    relativePosition2.getX() * radius + relativePosition2.getY() * leg2)
                            .scalarMultiply(1.0 / distanceSq2);
            rightLegDirection = new Vector2D(
                    relativePosition2.getX() * leg2 + relativePosition2.getY() * radius,
                    -relativePosition2.getX() * radius + relativePosition2.getY() * leg2)
                            .scalarMultiply(1.0 / distanceSq2);
        } else {
            // Usual situation.
            if (obstacle1.convex) {
                final double leg1 = FastMath.sqrt(distanceSq1 - radiusSq);
                leftLegDirection = new Vector2D(
                        relativePosition1.getX() * leg1 - relativePosition1.getY() * radius,
                        relativePosition1.getX() * radius + relativePosition1.getY() * leg1)
                                .scalarMultiply(1.0 / distanceSq1);
            } else {
                // Left vertex non-convex; left leg extends cut-off line.
                leftLegDirection = obstacle1.direction.negate();
            }

            if (obstacle2.convex) {
                final double leg2 = FastMath.sqrt(distanceSq2 - radiusSq);
                rightLegDirection = new Vector2D(
                        relativePosition2.getX() * leg2 + relativePosition2.getY() * radius,
                        -relativePosition2.getX() * radius + relativePosition2.getY() * leg2)
                                .scalarMultiply(1.0 / distanceSq2);
            } else {
                // Right vertex non-convex; right leg extends cut-off line.
                rightLegDirection = obstacle1.direction;
            }
        }

        // Legs can never point into neighboring edge when convex vertex,
        // take cut-off line of neighboring edge instead. If velocity
        // projected on "foreign" leg, no constraint is added.
        boolean leftLegForeign = false;
        boolean rightLegForeign = false;

        if (obstacle1.convex && RVOMath.det(leftLegDirection, obstacle1.previous.direction.negate()) >= 0.0) {
            // Left leg points into obstacle.
            leftLegDirection = obstacle1.previous.direction.negate();
            leftLegForeign = true;
        }

        if (obstacle2.convex && RVOMath.det(rightLegDirection, obstacle2.direction) <= 0.0) {
            // Right leg points into obstacle.
            rightLegDirection = obstacle2.direction;
            rightLegForeign = true;
        }

        // Compute cut-off centers.
        final Vector2D leftCutOff = obstacle1.point.subtract(position).scalarMultiply(invTimeHorizonObstacle);
        final Vector2D rightCutOff = obstacle2.point.subtract(position).scalarMultiply(invTimeHorizonObstacle);
        final Vector2D cutOffVector = rightCutOff.subtract(leftCutOff);

        // Project current velocity on velocity obstacle.

        // Check if current velocity is projected on cutoff circles.
        final double t = obstacle1 == obstacle2 ? 0.5
                : velocity.subtract(leftCutOff).dotProduct(cutOffVector) / cutOffVector.getNormSq();
        final double tLeft = velocity.subtract(leftCutOff).dotProduct(leftLegDirection);
        final double tRight = velocity.subtract(rightCutOff).dotProduct(rightLegDirection);

        if (t < 0.0 && tLeft < 0.0 || obstacle1 == obstacle2 && tLeft < 0.0 && tRight < 0.0) {
            // Project on left cut-off circle.
            final Vector2D unitW = velocity.subtract(leftCutOff).normalize();

            final Vector2D direction = new Vector2D(unitW.getY(), -unitW.getX());
            final Vector2D point = leftCutOff.add(radius * invTimeHorizonObstacle, unitW);
            lines.add(new Line(point, direction));

            continue;
        }

        if (t > 1.0 && tRight < 0.0) {
            // Project on right cut-off circle.
            final Vector2D unitW = velocity.subtract(rightCutOff).normalize();

            final Vector2D direction = new Vector2D(unitW.getY(), -unitW.getX());
            final Vector2D point = rightCutOff.add(radius * invTimeHorizonObstacle, unitW);
            lines.add(new Line(point, direction));

            continue;
        }

        // Project on left leg, right leg, or cut-off line, whichever is
        // closest to velocity.
        final double distanceSqCutOff = t < 0.0 || t > 1.0 || obstacle1 == obstacle2 ? Double.POSITIVE_INFINITY
                : velocity.distanceSq(leftCutOff.add(cutOffVector.scalarMultiply(t)));
        final double distanceSqLeft = tLeft < 0.0 ? Double.POSITIVE_INFINITY
                : velocity.distanceSq(leftCutOff.add(leftLegDirection.scalarMultiply(tLeft)));
        final double distanceSqRight = tRight < 0.0 ? Double.POSITIVE_INFINITY
                : velocity.distanceSq(rightCutOff.add(rightLegDirection.scalarMultiply(tRight)));

        if (distanceSqCutOff <= distanceSqLeft && distanceSqCutOff <= distanceSqRight) {
            // Project on cut-off line.
            final Vector2D direction = obstacle1.direction.negate();
            final Vector2D point = leftCutOff.add(radius * invTimeHorizonObstacle,
                    new Vector2D(-direction.getY(), direction.getX()));
            lines.add(new Line(point, direction));

            continue;
        }

        if (distanceSqLeft <= distanceSqRight) {
            // Project on left leg.
            if (leftLegForeign) {
                continue;
            }

            final Vector2D point = leftCutOff.add(radius * invTimeHorizonObstacle,
                    new Vector2D(-leftLegDirection.getY(), leftLegDirection.getX()));
            lines.add(new Line(point, leftLegDirection));

            continue;
        }

        // Project on right leg.
        if (rightLegForeign) {
            continue;
        }

        final Vector2D direction = rightLegDirection.negate();
        final Vector2D point = rightCutOff.add(radius * invTimeHorizonObstacle,
                new Vector2D(-direction.getY(), direction.getX()));
        lines.add(new Line(point, direction));
    }

    final int numObstacleLines = lines.size();

    final double invTimeHorizon = 1.0 / timeHorizonAgents;

    // Create agent ORCA lines.
    for (final Pair<Double, Agent> agentNeighbor : agentNeighbors) {
        final Agent other = agentNeighbor.getSecond();

        final Vector2D relativePosition = other.position.subtract(position);
        final Vector2D relativeVelocity = velocity.subtract(other.velocity);
        final double distanceSq = relativePosition.getNormSq();
        final double combinedRadius = radius + other.radius;
        final double combinedRadiusSq = combinedRadius * combinedRadius;

        final Vector2D direction;
        final Vector2D u;

        if (distanceSq > combinedRadiusSq) {
            // No collision.
            final Vector2D w = relativeVelocity.subtract(invTimeHorizon, relativePosition);

            // Vector from cutoff center to relative velocity.
            final double wLengthSq = w.getNormSq();
            final double dotProduct1 = w.dotProduct(relativePosition);

            if (dotProduct1 < 0.0 && dotProduct1 * dotProduct1 > combinedRadiusSq * wLengthSq) {
                // Project on cut-off circle.
                final double wLength = FastMath.sqrt(wLengthSq);
                final Vector2D unitW = w.scalarMultiply(1.0 / wLength);

                direction = new Vector2D(unitW.getY(), -unitW.getX());
                u = unitW.scalarMultiply(combinedRadius * invTimeHorizon - wLength);
            } else {
                // Project on legs.
                final double leg = FastMath.sqrt(distanceSq - combinedRadiusSq);

                if (RVOMath.det(relativePosition, w) > 0.0) {
                    // Project on left leg.
                    direction = new Vector2D(
                            relativePosition.getX() * leg - relativePosition.getY() * combinedRadius,
                            relativePosition.getX() * combinedRadius + relativePosition.getY() * leg)
                                    .scalarMultiply(1.0 / distanceSq);
                } else {
                    // Project on right leg.
                    direction = new Vector2D(
                            relativePosition.getX() * leg + relativePosition.getY() * combinedRadius,
                            -relativePosition.getX() * combinedRadius + relativePosition.getY() * leg)
                                    .scalarMultiply(-1.0 / distanceSq);
                }

                final double dotProduct2 = relativeVelocity.dotProduct(direction);
                u = direction.scalarMultiply(dotProduct2).subtract(relativeVelocity);
            }
        } else {
            // Collision. Project on cut-off circle of time timeStep.
            final double invTimeStep = 1.0 / Simulator.instance.timeStep;

            // Vector from cutoff center to relative velocity.
            final Vector2D w = relativeVelocity.subtract(invTimeStep, relativePosition);

            final double wLength = w.getNorm();
            final Vector2D unitW = w.scalarMultiply(1.0 / wLength);

            direction = new Vector2D(unitW.getY(), -unitW.getX());
            u = unitW.scalarMultiply(combinedRadius * invTimeStep - wLength);
        }

        final Vector2D point = velocity.add(0.5, u);
        lines.add(new Line(point, direction));
    }

    final int lineFail = linearProgram2(lines, preferredVelocity, false);

    if (lineFail < lines.size()) {
        linearProgram3(numObstacleLines, lineFail);
    }
}