/**Returns true, if the agent overstepped the border of the nextLocation.*/ private boolean getBehindBorder() { /* Vektory startA a endA (agent) určují úsečku "A" od previousLocation k lokaci agenta.*/ Vector2d startA = new Vector2d(previousLocation.x, previousLocation.y); Vector2d endA = new Vector2d(botself.getLocation().x, botself.getLocation().y); Vector2d directionA = new Vector2d(endA.x - startA.x, endA.y - startA.y); /* Vektory startB a endB (border) určují přímku "B" prochízející nextLocation mající směr kolmý na spojnici nextLocation a previousLocation. Je to tedy jakási hranice * a my zkoumáme, zda se agent dostal za tuto hranici.*/ Vector2d startB = new Vector2d(nextLocation.x, nextLocation.y); Vector2d normalDirectionB = new Vector2d(nextLocation.x - previousLocation.x, nextLocation.y - previousLocation.y); Vector2d directionB = new Vector2d(-normalDirectionB.y, normalDirectionB.x); //Vector2d endB = new Vector2d(startB.x + directionB.x, startB.y + directionB.y); Vector2d intersection = SteeringTools.getIntersection(startA, directionA, startB, directionB, SteeringTools.LineType.ABSCISSA, SteeringTools.LineType.STRAIGHT_LINE); /*Pokud úsečka "A" protíná přímku "B" (intersection není null), agent se dostal za hranici a je třeba posunout následující bod na cestě.*/ if (SteeringManager.DEBUG) System.out.println("Jsme za hranicí "+(intersection != null)+" průsečík: "+intersection); return (intersection != null); }
public double adjacentDist(Line l, Point2d pt) { Vector2d v1 = new Vector2d(l.end); v1.sub(l.start); Vector2d v2 = new Vector2d(pt); v2.sub(l.start); double param = v2.dot(v1) / v1.length(); if ( param < 0 || param > v1.length() ) return Double.MAX_VALUE; v1.normalize(); v1.scale( param ); v1.add( l.start ); return new Point2d (v1).distance(pt); }
@Override public List<Point2d> gen(Vector2d left, Vector2d right) { Point2d overhang = new Point2d(right); overhang.scale(0.2); Line l = new Line(new Point2d(), new Point2d(left)); Point2d r = l.project(overhang, false); List<Point2d> out = new ArrayList<>(); out.add(new Point2d()); out.add(overhang); out.add(r); return out; }
public static Point2d project(Line l, Point2d pt) { Vector2d v1 = new Vector2d(l.end); v1.sub(l.start); Vector2d v2 = new Vector2d(pt); v2.sub(l.start); double param = v2.dot(v1) / v1.length(); if (param < 0 || param > v1.length()) return null; v1.normalize(); v1.scale(param); v1.add(l.start); return new Point2d(v1); }
private static Vector2d computeNormal(final Point2d prev, final Point2d current, final Point2d next, final Vector2d prevNormal) { Vector2d normal = new Vector2d(); if (prev == null) { normal.x = current.y - next.y; normal.y = next.x - current.x; } else if (next == null) { normal.x = -current.y + prev.y; normal.y = -prev.x + current.x; } else { normal.x = prev.y - next.y; normal.y = next.x - prev.x; } // normalization if not null (Vector2d.normalize() method returns NaN if norm is 0! double norm = Math.sqrt(normal.x * normal.x + normal.y * normal.y); if (norm > 1.E-6) { normal.x /= norm; normal.y /= norm; } return normal; }
private void finishEdge(Parabola n) { if (n.isLeaf) { return; } double mx; if (n.edge.direction.x > 0) { mx = Math.max(width, n.edge.start.x + 10); } else { mx = Math.min(0, n.edge.start.x - 10); } Vector2d end = new Vector2d(mx, mx*n.edge.f + n.edge.g); n.edge.end = end; points.add(end); finishEdge(n.left()); finishEdge(n.right()); }
/** * Prueft, ob ein Punkt ueber einem Loch liegt * * @param pos * @return true, wenn der Bot ueber dem loch steht */ public boolean checkHole(Point3d pos) { if ((pos.x < 0) || (pos.y < 0) || (pos.x > dimX * blockSizeInM) || (pos.y > dimY * blockSizeInM)) { return true; } Iterator it = holes.iterator(); while (it.hasNext()) { Vector2f min = new Vector2f((Vector2d) it.next()); min.scale(blockSizeInM); Vector2f max = new Vector2f(min); max.add(new Vector2f(blockSizeInM, blockSizeInM)); if ((pos.x > min.x) && (pos.x < max.x) && (pos.y > min.y) && (pos.y < max.y)) { return true; } } return false; }
public void drawChoiceAPI(Graphics2D g, Player[] playerChoices) { if(playerChoices != null) { Player hoveringPlayer = getGameCanvas().getPitchMouseLogic().getHoveringPlayer(); for(Player player: playerChoices) { Vector2d playerPos = player.getPos(); if(playerPos != null) { if(hoveringPlayer != null && playerPos.equals(hoveringPlayer.getPos())) { highlightField(g, playerPos.x, playerPos.y, SBColor.BLUE_BRIGHT_80); drawBeacon(g, playerPos.x, playerPos.y, SBColor.BLUE_BRIGHT); } else { highlightField(g, playerPos.x, playerPos.y, SBColor.YELLOW_80); } } } } }
public void drawFieldAPI(Graphics2D g, Vector2d[] fieldChoices) { if(fieldChoices != null) { for(Vector2d field: fieldChoices) { double[] hoveringFieldCoords = getGameCanvas().getPitchMouseLogic().getMXY(); Vector2d hoveringField = new Vector2d(hoveringFieldCoords[0], hoveringFieldCoords[1]); if(field != null) { if(field.equals(hoveringField)) { highlightField(g, field.x, field.y, SBColor.BLUE_BRIGHT_80); drawBeacon(g, field.x, field.y, SBColor.BLUE_BRIGHT); } else { highlightField(g, field.x, field.y, SBColor.YELLOW_80); } } } } }
private void drawBeacon(Graphics2D g2D, double x, double y, Color color, int a) { g2D.setPaint( new Color(color.getRed(), color.getGreen(), color.getBlue(), (int) (a + 20 * Math.cos((double) getGameCanvas().timer * 3 /180*Math.PI))) ); Vector2d pXYleft = posToDisp(new Vector2d(x * getPW() + getPW()/4, y * getPW() + getPW()/2)), pXYright = posToDisp(new Vector2d(x * getPW() + 3*getPW()/4, y * getPW() + getPW()/2)); GeneralPath beacon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4); beacon.moveTo((pXYleft.x + pXYright.x) / 2, pXYleft.y - 1000); beacon.lineTo(pXYright.x, pXYright.y); beacon.lineTo(pXYleft.x, pXYleft.y); beacon.closePath(); g2D.fill(beacon); }
void setMXY(MouseEvent e) { double xNew = e.getX(), yNew = e.getY(); Vector2d mXYNew = getGameCanvas().getGameRenderer().dispToPos(new Vector2d(xNew, yNew)); double mXNewTemp = mXYNew.x / getpW(), mYNewTemp = mXYNew.y / getpH(); if(mXNewTemp < 0) mXNewTemp -= 1; // fix negative coordinates rounding error if(mYNewTemp < 0) mYNewTemp -= 1; // " int mXNew = (int) mXNewTemp, mYNew = (int) mYNewTemp; mXOld = mX; mYOld = mY; if(mXNew >= 0 && mXNew < Pitch.PITCH_LENGTH && mYNew >= 0 && mYNew < Pitch.PITCH_WIDTH) { mX = mXNew; mY = mYNew; } else { resetMXY(); } }
private void halfTime() { Vector<Player> playersOnThePitch = findPlayersOnThePitch(); clearAllPlayerPos(); getPitch().adjustBallPos(new Vector2d(-1, -1)); teamsSet[0] = false; teamsSet[1] = false; gamePhase = 1; resetPlayerConditions(); checkForSwelteringHeat(playersOnThePitch); sendGame(); checkForTeamCondition(); cleanPlayersAfterTouchdownOrHalfTime(); if(roundCount >= NUMBER_OF_ROUNDS_IN_GAME){ finishGame(); }else{ initiateTeamSetup(coaches[actingPlayer]); } }
/** * Checks whether two field-positions are adjacent * @param pos1 Position of the first Field (as a Vector 2d) * @param pos2 Position of the second Field (as a Vector 2d) * @return Boolean which is true if the two fields are adjacent and false if not */ public boolean isAdjacent(Vector2d pos1, Vector2d pos2){ try{ if(!(isOnField(pos1)) || !(isOnField(pos2))){ throw new SBOutOfFieldException("given position is not on the pitch"); }else{ for(PitchField f: getNeighbours(pos2)){ if(fields[(int)pos1.x][(int)pos1.y] == f){ return true; } } return false; } }catch(SBOutOfFieldException e){ e.printStackTrace(); } return false; }
public void refereeTriesToKeepSurvey(SBProtocolMessage message){ int refereeThrow1 = actor.getMatch().d6.throwDie(); int refereeThrow2 = actor.getMatch().d6.throwDie(); if(refereeThrow1 == refereeThrow2){ if(actor.isHoldingBall()){ actor.invokeSetIsHoldingBall(false); Vector2d newBallPos = new Vector2d(actor.getPos()); newBallPos.add(actor.getMatch().scatter()); actor.getMatch().getPitch().setBallPos(newBallPos); } actor.invokeClearPosition(); actor.invokeSetRedCard(true); int actingUserIndex = -1; if(actor.getMatch().getTeam(0) == actor.getTeam()){ actingUserIndex = 0; }else if(actor.getMatch().getTeam(1) == actor.getTeam()){ actingUserIndex = 1; } ((ServerMatch)actor.getMatch()).endTurn(actingUserIndex); sendMessageShowMe(actor.toString(), "This stupid referee sent me of the pitch!"); returnSuccessMessage(message, SBProtocolMessage.WORKD_PLAYER_HAS_BEEN_SENT_OFF_THE_PITCH_BY_REFEREE); } }
protected boolean beingTackled(SBProtocolMessage message, int i, PitchField... path){ if (actor.isHoldingBall()) { returnSuccessMessage(message, SBProtocolMessage.WORKD_YOU_HAVE_LOST_YOUR_BALLS); } //player gets tackled, he falls down and its no longer your turn sendMessageShowMe(actor.toString(), "Dammit, I was tackled!"); ((RuleBlock) actor.getRule(1)).playerDown(message, actor, RuleBlock.YOU_SUCK); actor.invokeSetRemainingBe(0); returnSuccessMessage(message, SBProtocolMessage.WORKD_YOU_ARE_TACKLED); actor.getMatch().sendPlayer(actor); if(path[i].getPos().equals(actor.getMatch().getPitch().getBallPos())){ Vector2d newBallPos = new Vector2d(actor.getMatch().getPitch().getBallPos()); newBallPos.add(actor.getMatch().scatter()); actor.getMatch().getPitch().setBallPos(newBallPos); } return false; }
/** * the actual throw * @param message the message that initiated the throw * @param destinationField where to throw * @param problems how difficult it is to throw */ protected void throwBall(SBProtocolMessage message, Vector2d destinationField, int problems){ if(geTest(problems)){ successfulThrow(message, destinationField); }else{ notWellThrown(destinationField, message); } actor.invokeSetIsHoldingBall(false); actor.invokeSetRemainingBe(0); actor.getTeam().setPass(false); actor.getMatch().sendBallPos(); if(((ServerMatch)actor.getMatch()).findTeamHoldingTheBall() != actor.getMatch().findUserIndex(message)){ ((ServerMatch)actor.getMatch()).endTurn(message); } actor.getMatch().sendPlayer(actor); }
protected Vector<Player> findPossibleInterceptors(Player thrower, Vector2d b){ int teamIndex = -1; if(thrower.getTeam() == getMatch().getTeam(0)){ teamIndex = 0; }else if(thrower.getTeam() == getMatch().getTeam(1)){ teamIndex = 1; }else{ return null; } Vector<Player> possibleInterceptors = new Vector<Player>(); for(PitchField field: findInterceptPositions(thrower.getPos(), b)){ if(field.getPlayer() != null){ if(field.getPlayer().getTeam() != getMatch().getTeam(teamIndex) && field.getPlayer().invokeGetPlayerCondition() == PlayerCondition.FINE){ possibleInterceptors.add(field.getPlayer()); } } } return possibleInterceptors; }
protected void askForInterception(SBProtocolMessage message, Vector2d destinationField, int throwModificator) { Vector<Player> possibleInterceptors = findPossibleInterceptors(actor, destinationField); if(possibleInterceptors.size() == 0){ throwBall(message, destinationField, throwModificator); }else{ Vector<String> parameters = new Vector<String>(); parameters.add(SBProtocolMessage.EVENT_API_CHOICE); parameters.add(SBProtocolMessage.EVENT_ASK_FOR_INTERCEPTOR); for(Player player:possibleInterceptors){ if(player.getTeam() == getMatch().getTeam(0)){ parameters.add("0"); parameters.add((player.getId()-1) + ""); }else if(player.getTeam() == getMatch().getTeam(1)){ parameters.add("1"); parameters.add((player.getId()-1) + ""); } } String[] parameterArray = parameters.toArray(new String[parameters.size()]); ((ServerMatch)getMatch()).setCurrentModificatorWaitingForAnser(throwModificator); ((ServerMatch)getMatch()).setCurrentDefenderFieldWaitingForAnswer(destinationField); ((ServerMatch)getMatch()).setCurrentMessageWaitingForAnswer(message); ((ServerMatch)getMatch()).setCurrentActorWaitingForAnswer(actor); getMatch().setGamePhase(5); sendMessage(getMatch().getOpponent(actor.getTeam().getCoach()), SBProtocolCommand.EVENT, parameterArray); } }
/** * waits until the user decided if he should follow and then executes his decision * @param defenderField the destination field on which you can follow * @param message SBProtocolMessage * @param answer SBProtocolMessage */ public boolean follow(Vector2d defenderField, SBProtocolMessage message, SBProtocolMessage answer){ actor.getMatch().setGamePhase(3); int decision; try{ decision = Integer.parseInt(answer.getParameterContent(2)); } catch(NumberFormatException e){ returnFailureMessage(message, SBProtocolMessage.FAILD_RECEIVED_WRONG_GAME_DATA); return false; } if(decision == 1){ actor.invokeSetPosition(defenderField); returnSuccessMessage(message, SBProtocolMessage.WORKD_FOLLOWED); } else if(decision ==0){ returnSuccessMessage(message, SBProtocolMessage.WORKD_NOTFOLLOWED); } else{ returnFailureMessage(message, SBProtocolMessage.FAILD_CANT_BACKUP_FOR_SOME_ODD_REASON); return false; } return true; }
/**If it's really the front collision, the "mirror vector" is returned. Otherwise the unchanged parameter normal is returned.*/ private Vector3d computeTreeCollisionVector(Vector3d normal) { Vector3d av = botself.getVelocity().getVector3d(); /* Jestliže signalizuje pravý přední paprsek a ne levý přední - * a navíc jde normálová síla v místě kolize stejným směrem jako jde paprsek, tedy doleva ==> pak by se neměla přičítat tato normála, ale spíše síla na durhou stranu. * Značí to situaci, kdy jsme narazili na úzkou překážku (strom) a levý přední paprsek prošel levým krajem překážky. * Bez tohoto ošetření by nás to stočilo doleva, což nechceme.*/ /* Pro pravou stranu je to naopak. *//* Jestliže signalizuje levý přední paprsek a ne pravý přední - * a navíc jde normálová síla v místě kolize stejným směrem jako jde paprsek, tedy doleva ==> pak by se neměla přičítat tato normála, ale spíše síla na durhou stranu. * Značí to situaci, kdy jsme narazili na úzkou překážku (strom) a levý přední paprsek prošel levým krajem překážky. * Bez tohoto ošetření by nás to stočilo doleva, což nechceme.*/ Vector2d start = new Vector2d(botself.getLocation().x, botself.getLocation().y); Vector2d end = new Vector2d(start.x-av.x, start.y-av.y); Vector2d point = new Vector2d(start.x + normal.x, start.y + normal.y); Vector2d pata = SteeringTools.getNearestPoint(start, end, point, false); Vector2d pointToPata = new Vector2d(pata.x - point.x, pata.y - point.y); pointToPata.scale(2); Vector2d mirrorPoint = new Vector2d(point.x + pointToPata.x, point.y + pointToPata.y); Vector3d result = new Vector3d(mirrorPoint.x - start.x, mirrorPoint.y - start.y, 0); if (SteeringManager.DEBUG) { System.out.println("Obstacle avoidance tree collision. " + result.length()); } return result; }
/**Gets the intersection of the half-lines A and B (line has the start point and its direction. * If there isn't the intersection of the half-lines, or the direction is the same, we return null.*/ public static boolean haveSameDirection(Vector2d sA, Vector2d dA, Vector2d sB, Vector2d dB) { dA.normalize(); dB.normalize(); if (dA.equals(dB)) { return true; } else { return false; } }
/** * @param t * @return */ private ArrayList<Vector2d> getCartesianVectorsList(Thermal t) { ArrayList<Vector2d> driftVectorsCartesian = new ArrayList<>(); for (Circle c : t.circles) { if (c.drift_vector != null) { Vector2d driftCartesian = vectorPolarToCartesian(c); driftVectorsCartesian.add(driftCartesian); } } return driftVectorsCartesian; }
/** * @param averageDriftCartesian * @return */ private PolarVector vectorCartesianToPolar(Vector2d averageDriftCartesian) { PolarVector averageDriftPolar; double average_drift_bearing = Math.atan2(averageDriftCartesian.y, averageDriftCartesian.x); average_drift_bearing = Math.toDegrees(average_drift_bearing); double average_drift_size = Math.sqrt( averageDriftCartesian.x * averageDriftCartesian.x + averageDriftCartesian.y * averageDriftCartesian.y); averageDriftPolar = new PolarVector(average_drift_bearing, average_drift_size); return averageDriftPolar; }
/** * @param c * @return */ private Vector2d vectorPolarToCartesian(Circle c) { double x = c.drift_vector.size * Math.cos(Math.toRadians(c.drift_vector.bearing)); double y = c.drift_vector.size * Math.sin(Math.toRadians(c.drift_vector.bearing)); Vector2d driftCartesian = new Vector2d(x, y); return driftCartesian; }
private void findNeighbours( List<FRect> list ) { for ( FRect a : list ) for ( Dir d : Dir.values() ) { FRect best = null; double bestDist = Double.MAX_VALUE; Vector2d wDir = d.dir(); for ( FRect b : list ) { if ( b == a ) continue; Vector2d delta = new Vector2d(b.getCenter()); delta.sub (a.getCenter()); if (wDir.angle( delta ) > Mathz.PI6 ) continue; double dist = a.getCenter().distanceSquared( b.getCenter() ); if ( dist < bestDist ) { bestDist = dist; best = b; } } a.setAdj( d, best ); } }
public static void extrude( ObjDump out, LoopL<Point2d> slice, double h1, double h2 ) { for (Loop<Point2d> loop : slice) { for (Loopable<Point2d> pt : loop.loopableIterator()) { List<double[]> pts = new ArrayList<>(), norms = new ArrayList<>(); Point2d a = pt.get(), b = pt.getNext().get(); pts.add( new double[] { a.x, h1, a.y} ); pts.add( new double[] { b.x, h1, b.y} ); pts.add( new double[] { b.x, h2, b.y} ); pts.add( new double[] { a.x, h2, a.y} ); Vector2d d = new Vector2d( b); d.sub(a); d.normalize(); double[] norm = new double[] {-d.y, 0, d.x}; // double[] norm = new double[] {d.y, 0, -d.x}; for (int i = 0; i < 4; i++) norms.add(norm); out.addFace(pts.toArray( new double[pts.size()][] ), null, norms.toArray( new double[norms.size()][] )); } } }
public void checkIntersection(final double p1x, final double p1y, final double v1x, final double v1y, final double p2x, final double p2y, final double v2x, final double v2y, final Point2d expected) { Point2d inter = MathUtil.intersectionPoint(new Point2d(p1x, p1y), new Vector2d(v1x, v1y), new Point2d(p2x, p2y), new Vector2d(v2x, v2y)); if (expected == null) { Assert.assertNull(inter); } else { Assert.assertNotNull(inter); Assert.assertEquals(expected.x, inter.x, EPSILON); Assert.assertEquals(expected.y, inter.y, EPSILON); } }
/** * Compute the vector which is perpendicular to the p1p2 vector * @param p1 first point * @param p2 second point * @return n unit vector where n scalar p1p2 = 0 */ public static Vector2d computeNormal(final Point2d p1, final Point2d p2) { Vector2d normal = new Vector2d(p1.y - p2.y, p2.x - p1.x); // normalization if not null (Vector2d.normalize() method returns NaN if norm is 0! double norm = norm(normal); if (norm > 1.E-6) { normal.x /= norm; normal.y /= norm; } return normal; }
/** * Compute the vector which is perpendicular to the v vector * @param v vector to find normal * @return n unit vector where n scalar v = 0 */ public static Vector2d computeNormal(final Vector2d v) { Vector2d normal = new Vector2d(-v.y, v.x); double norm = norm(normal); if (norm > 1.E-6) { normal.x /= norm; normal.y /= norm; } return normal; }
public static List<Site> findSites(List<Vector2d> sites, List<Edge> edges) { ArrayList<Site> result = new ArrayList<>(); ArrayList<Edge> tmpEdges = new ArrayList<>(); HashSet<Vector2d> tmpCorners = new LinkedHashSet<>(); //first trivial implementation for (Vector2d center : sites) { Site site = new Site(); site.center = center; //collect bounding edges tmpEdges.clear(); tmpCorners.clear(); for (Edge e : edges) { if (e.getLeft()==center || e.getRight()==center) { tmpEdges.add(e); tmpCorners.add(e.getStart()); tmpCorners.add(e.getEnd()); } } if (tmpEdges.isEmpty() || tmpCorners.isEmpty()) { LOG.log(Level.WARNING, "no edges for point {0} found!", center); continue; } site.edges = tmpEdges.toArray(new Edge[tmpEdges.size()]); site.corners = tmpCorners.toArray(new Vector2d[tmpCorners.size()]); result.add(site); } return result; }
/** * Prueft, ob ein Punkt innerhalb des Zielfeldes liegt * * @param pos * @return true, falls ja */ public boolean finishReached(Vector3d pos) { for (Vector2d p : finishPositions) { double minX = p.x * blockSizeInM; double maxX = p.x * blockSizeInM + blockSizeInM; double minY = p.y * blockSizeInM; double maxY = p.y * blockSizeInM + blockSizeInM; if ((pos.x > minX) && (pos.x < maxX) && (pos.y > minY) && (pos.y < maxY)) { return true; } } return false; }
/** * For some reason, in some constellation the voronoi algorithm does not * produce a correct result. This method checks by a heuristic if this * situation is the case. * * @param edges * @param size * @return */ public static boolean isValid(List<Edge> edges, float size) { float epsilon = 0.2f * size; epsilon *= epsilon; for (Edge e : edges) { Vector2d v = new Vector2d(e.getStart().x - e.getEnd().x, e.getStart().y - e.getEnd().y); if (v.lengthSquared() > epsilon) { return false; } } return true; }
/** * The first step, compute the cells */ private void computeVoronoi() { if (!initialized || pointCount==0) { return; } LOG.info("compute cells"); //Generate voronoiSites voronoiRandom = new Random(seed); voronoiScale = 100 * pointCount; voronoiSites = new ArrayList<>(pointCount); while (true) { voronoiSites.clear(); for (int i=0; i<pointCount; ++i) { float x = voronoiRandom.nextFloat() * voronoiScale; float y = voronoiRandom.nextFloat() * voronoiScale; voronoiSites.add(new Vector2d(x, y)); } //compute voronoi diagram voronoiEdges = voronoi.getEdges(voronoiSites, voronoiScale, voronoiScale); voronoiEdges = Voronoi.closeEdges(voronoiEdges, voronoiScale, voronoiScale); //relax voronoiSites for (int i=0; i<relaxationIterations; ++i) { voronoiSites = VoronoiUtils.generateRelaxedSites(voronoiSites, voronoiEdges); voronoiEdges = voronoi.getEdges(voronoiSites, voronoiScale, voronoiScale); voronoiEdges = Voronoi.closeEdges(voronoiEdges, voronoiScale, voronoiScale); } //check if valid if (VoronoiUtils.isValid(voronoiEdges, voronoiScale)) { break; } LOG.warning("voronoi diagram is illegal, try again"); } LOG.info("point and edges generated"); //next step generateGraph(); }
private static boolean isInside(Vector2d v, float w, float h) { if (v.x<0 || v.y<0 || v.x>=w || v.y>=h) { return false; } else { return true; } }
private static Vector2d edgeBoxIntersection(Edge e, float w, float h) { double a,b,x,y; if (isInside(e.end, w, h)) { a = e.end.x; b = e.end.y; x = e.start.x; y = e.start.y; } else { a = e.start.x; b = e.start.y; x = e.end.x; y = e.end.y; } double t1 = a/(a-x); double t2 = b/(b-y); double t3 = (w-a)/(x-a); double t4 = (h-b)/(y-b); if (t1<0 || t1>1) t1 = Double.POSITIVE_INFINITY; if (t2<0 || t2>1) t2 = Double.POSITIVE_INFINITY; if (t3<0 || t3>1) t3 = Double.POSITIVE_INFINITY; if (t4<0 || t4>1) t4 = Double.POSITIVE_INFINITY; double t = Math.min(Math.min(t1, t2), Math.min(t3, t4)); if (t == Double.POSITIVE_INFINITY) { return null; } return new Vector2d(a + t*(x-a), b + t*(y-b)); }
private double getXOfEdge(Parabola par, double y) { Parabola left = Parabola.getLeftChild(par); Parabola right = Parabola.getRightChild(par); Vector2d p = left.site; Vector2d r = right.site; double dp = 2 * (p.y - y); double a1 = 1/dp; double b1 = -2 * p.x / dp; double c1 = y + dp/4 + p.x*p.x/dp; dp = 2*(r.y-y); double a2 = 1/dp; double b2 = -2*r.x/dp; double c2 = ly + dp/4 + r.x*r.x/dp; double a = a1-a2; double b = b1-b2; double c = c1-c2; double disc = b*b - 4*a*c; double x1 = (-b + Math.sqrt(disc)) / (2*a); double x2 = ((-b - Math.sqrt(disc)) / (2*a)); double ry; if (p.y < r.y) { ry = Math.max(x1, x2); } else { ry = Math.min(x1, x2); } return ry; }
private double getY(Vector2d p, double x) { double dp = 2*(p.y - ly); double a1 = 1/dp; double b1 = -2*p.x/dp; double c1 = ly+dp/4 + p.x*p.x/dp; return a1*x*x + b1*x + c1; }
public void updateMarkers( Bar b ) { for (Marker m : b.mould.getAnchorsReadOnly( b.start, b.end ) ) { Vector2d dir = new Vector2d (b.end); dir.sub(b.start); dir.scale( Mathz.clamp( weights.get (b), 0.1, 0.9 ) ); dir.add(b.start); m.set( dir ); m.bar = b; } }
Parabola(Vector2d s) { site = s; isLeaf = true; cEvent = null; edge = null; parent = null; }
private void generateVoronoi() { Random rand = new Random(); Voronoi voronoi = new Voronoi(); Set<Vector2d> pointSet = new HashSet<>(); for (int i=0; i<n; ++i) { float x = (rand.nextFloat() * w * scale); float y = (rand.nextFloat() * h * scale); pointSet.add(new Vector2d(x, y)); } points = new ArrayList<>(n); points.addAll(pointSet); long time1 = System.currentTimeMillis(); edges = voronoi.getEdges(points, w*scale, h*scale); edges = Voronoi.closeEdges(edges, w*scale, h*scale); //relax n times int m = 1; for (int i=0; i<m; ++i) { points = VoronoiUtils.generateRelaxedSites(points, edges); edges = voronoi.getEdges(points, w*scale, h*scale); edges = Voronoi.closeEdges(edges, w*scale, h*scale); } long time2 = System.currentTimeMillis(); for (Iterator<Edge> it = edges.iterator(); it.hasNext(); ) { Edge e = it.next(); Vector2d v = new Vector2d(e.getStart().x - e.getEnd().x, e.getEnd().y - e.getEnd().y); if (v.length() > 0.05 * w * scale) { System.out.println("long edge: "+e); // it.remove(); } } System.out.println("edges: ("+edges.size()+")"); // for (Edge e : edges) { // System.out.println(" "+e.start+" -- "+e.end); // } System.out.println("time to compute: "+(time2-time1)+" msec"); panel.repaint(); }