List of usage examples for java.lang Double POSITIVE_INFINITY
double POSITIVE_INFINITY
To view the source code for java.lang Double POSITIVE_INFINITY.
Click Source Link
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); } }