⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 obstacleworld.java

📁 Contiki是一个开源
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        allObstaclesSpatial[x][y].removeAllElements();        outerBounds = new Rectangle2D.Double(0,0,0,0);  }    /**   * Returns true of given point is on a corner of   * any of the structures build from the obstacles.   * Internally this method checks how many of four point    * close to and located around given point (diagonally) are    * inside any obstacle.   * This method returns true if exactly one point is inside an obstacle.   *    * @param point Point to check   * @return True of point is on a corner, false otherwise   */  public boolean pointIsNearCorner(Point2D point) {    double boxWidth = outerBounds.getWidth() / (double) spatialResolution;    double boxHeight = outerBounds.getHeight() / (double) spatialResolution;    double areaStartX = outerBounds.getMinX();    double areaStartY = outerBounds.getMinY();    // Which obstacles should be checked    Point centerInArray = new Point(        (int) ((point.getX() - areaStartX)/boxWidth),        (int) ((point.getY() - areaStartY)/boxHeight)    );    Vector<Rectangle2D> allObstaclesToCheck = null;    if (centerInArray.x < 0)      centerInArray.x = 0;    if (centerInArray.x >= spatialResolution)      centerInArray.x = spatialResolution-1;    if (centerInArray.y < 0)      centerInArray.y = 0;    if (centerInArray.y >= spatialResolution)      centerInArray.y = spatialResolution-1;        allObstaclesToCheck = allObstaclesSpatial[centerInArray.x][centerInArray.y];    if (allObstaclesToCheck.size() == 0) {      return false;    }         // Create the four point to check    double deltaDistance = 0.01; // 1 cm TODO Change this?    Point2D point1 = new Point2D.Double(point.getX() - deltaDistance, point.getY() - deltaDistance);    Point2D point2 = new Point2D.Double(point.getX() - deltaDistance, point.getY() + deltaDistance);    Point2D point3 = new Point2D.Double(point.getX() + deltaDistance, point.getY() - deltaDistance);    Point2D point4 = new Point2D.Double(point.getX() + deltaDistance, point.getY() + deltaDistance);    int containedPoints = 0;    Enumeration<Rectangle2D> allObstaclesToCheckEnum = allObstaclesToCheck.elements();    while (allObstaclesToCheckEnum.hasMoreElements()) {      Rectangle2D obstacleToCheck = allObstaclesToCheckEnum.nextElement();      if (obstacleToCheck.contains(point1))        containedPoints++;      if (obstacleToCheck.contains(point2))        containedPoints++;      if (obstacleToCheck.contains(point3))        containedPoints++;      if (obstacleToCheck.contains(point4))        containedPoints++;      // Abort if already to many contained points      if (containedPoints > 1) {        return false;      }    }        return (containedPoints == 1);  }    /**   * Checks if specified obstacle can be merged with any existing obstacle   * in order to reduce the total number of obstacles. And in that case a merge   * is performed and this method returns the new obstacle object.   * The checking is performed by looping through all existing obstacles and    * for each one comparing the union area of it and the given obstacle to the    * area sum of the two. And since obstacles are not allowed to overlap, if the    * union area is equal to the area sum, they can be merged.   * If a merge is performed, another may be made possible so this method   * should be looped until returning null.   *    * This method does not notify observers of changes made!   *    * @return New object of a merge was performed, null otherwise   */  private Rectangle2D mergeObstacle(Rectangle2D mergeObstacle) {    double mergeObstacleArea = mergeObstacle.getWidth() * mergeObstacle.getHeight();    double mergeObstacleTolerance = mergeObstacleArea * 0.01; // 1%        // Loop through all existing obstacles (but ignore itself)    for (int i=0; i < getNrObstacles(); i++) {      Rectangle2D existingObstacle = getObstacle(i);      if (!existingObstacle.equals(mergeObstacle)) {        double existingObstacleArea = existingObstacle.getWidth() * existingObstacle.getHeight();        Rectangle2D unionObstacle = existingObstacle.createUnion(mergeObstacle);        double unionArea = unionObstacle.getWidth() * unionObstacle.getHeight();                // Fault-tolerance        double faultTolerance = Math.min(mergeObstacleTolerance, existingObstacleArea*0.01);                // Compare areas        if (unionArea - faultTolerance <= existingObstacleArea + mergeObstacleArea) {          // Remove both old obstacles, add union          removeObstacle(mergeObstacle);          removeObstacle(existingObstacle);          addObstacle(unionObstacle, false);                    obstaclesOrganized = false;          return unionObstacle;        }      }    }        return null;  }    /**   * Register new obstacle with given attributes.   * This method will try to merge this obstacle with other already existing obstacles.   *    * @param startX Start X coordinate   * @param startY Start Y coordinate   * @param width Width   * @param height Height   */  public void addObstacle(double startX, double startY, double width, double height) {    addObstacle(startX, startY, width, height, true);  }    /**   * Register new obstacle with given attributes.   * This method will, depending on given argument, try to merge    * this obstacle with other already existing obstacles.   *    * @param startX Start X coordinate   * @param startY Start Y coordinate   * @param width Width   * @param height Height   * @param merge Should this obstacle, if possible, be merged with existing obstacles   */  public void addObstacle(double startX, double startY, double width, double height, boolean merge) {    Rectangle2D newRect = new Rectangle2D.Double(startX, startY, width, height);    addObstacle(newRect, merge);  }    /**   * Registers a given obstacle.   * This method will try to merge this obstacle with other already existing obstacles.   *    * @param obstacle New obstacle   */  public void addObstacle(Rectangle2D obstacle) {    addObstacle(obstacle, true);  }    /**   * Registers a given obstacle.   * This method will, depending on the given argument, try to    * merge this obstacle with other already existing obstacles.   *    * @param obstacle New obstacle   */  public void addObstacle(Rectangle2D obstacle, boolean merge) {    // TODO Should we keep the rounding?    obstacle.setRect(        Math.round(obstacle.getMinX()*1000.0) / 1000.0,        Math.round(obstacle.getMinY()*1000.0) / 1000.0,        Math.round(obstacle.getWidth()*1000.0) / 1000.0,        Math.round(obstacle.getHeight()*1000.0) / 1000.0    );      allObstacles.add(obstacle);    outerBounds = outerBounds.createUnion(obstacle);        if (merge) {      // Check if obstacle can be merged with another obstacle      Rectangle2D mergedObstacle = mergeObstacle(obstacle);            // Keep merging...      while (mergedObstacle != null)        mergedObstacle = mergeObstacle(mergedObstacle);    }        obstaclesOrganized = false;  }    /**   * Remove the given obstacle, if it exists.   *    * @param obstacle Obstacle to remove   */  public void removeObstacle(Rectangle2D obstacle) {    allObstacles.remove(obstacle);        recreateOuterBounds();    obstaclesOrganized = false;  }    /**   * This method recreates the outer bounds of    * this obstacle area by checking all registered   * obstacles.   * This method should never have to be called directly   * by a user.   */  public void recreateOuterBounds() {    outerBounds = new Rectangle2D.Double(0,0,0,0);    for (int i=0; i < allObstacles.size(); i++) {      outerBounds = outerBounds.createUnion(allObstacles.get(i));    }    obstaclesOrganized = false;  }    /**   * Reorganizes all registered obstacles in order to speed up   * searches for obstacles in spatial areas.   * This method is run automatically    */  public void reorganizeSpatialObstacles() {    // Remove all spatial obstacles    for (int x=0; x < spatialResolution; x++)      for (int y=0; y < spatialResolution; y++)         allObstaclesSpatial[x][y].removeAllElements();        double boxWidth = outerBounds.getWidth() / (double) spatialResolution;    double boxHeight = outerBounds.getHeight() / (double) spatialResolution;    double currentBoxMinX = outerBounds.getMinX();    double currentBoxMinY = outerBounds.getMinY();        // For each box, add obstacles that belong there    for (int x=0; x < spatialResolution; x++)      for (int y=0; y < spatialResolution; y++) {        // Check which obstacles should be in this box        Rectangle2D boxToCheck = new Rectangle2D.Double(currentBoxMinX + x*boxWidth, currentBoxMinY + y*boxHeight, boxWidth, boxHeight);        for (int i=0; i < allObstacles.size(); i++) {          if (allObstacles.get(i).intersects(boxToCheck)) {            allObstaclesSpatial[x][y].add(allObstacles.get(i));          }        }      }        obstaclesOrganized = true;        //printObstacleGridToConsole();  }    /**   * Prints a description of all obstacles to the console   */  public void printObstacleGridToConsole() {    logger.info("<<<<<<< printObstacleGridToConsole >>>>>>>");    logger.info(". Number of obstacles:\t" + getNrObstacles());    logger.info(". Outer boundary min:\t" + getOuterBounds().getMinX() + ", " + getOuterBounds().getMinY());    logger.info(". Outer boundary max:\t" + getOuterBounds().getMaxX() + ", " + getOuterBounds().getMaxY());        Vector<Rectangle2D> uniqueSpatialObstacles = new Vector<Rectangle2D>();    for (int x=0; x < spatialResolution; x++)      for (int y=0; y < spatialResolution; y++)         for (int i=0; i < allObstaclesSpatial[x][y].size(); i++)           if (!uniqueSpatialObstacles.contains(allObstaclesSpatial[x][y].get(i)))            uniqueSpatialObstacles.add(allObstaclesSpatial[x][y].get(i));    logger.info(". Unique spatial obstacles:\t" + uniqueSpatialObstacles.size());        int allSpatialObstacles = 0;    for (int x=0; x < spatialResolution; x++)      for (int y=0; y < spatialResolution; y++)         for (int i=0; i < allObstaclesSpatial[x][y].size(); i++)           allSpatialObstacles++;    logger.debug(". All spatial obstacles:\t" + allSpatialObstacles);        logger.info(". Spatial map counts:");    for (int y=0; y < spatialResolution; y++) {      for (int x=0; x < spatialResolution; x++) {        System.out.print(allObstaclesSpatial[x][y].size() + " ");      }      System.out.println("");    }      }    /**   * Returns XML elements representing the current obstacles.   *    * @see #setConfigXML(Collection)   * @return XML elements representing the obstacles   */  public Collection<Element> getConfigXML() {    Vector<Element> config = new Vector<Element>();    Element element;    for (Rectangle2D rect: allObstacles) {      element = new Element("obst");      element.setText(rect.getMinX() + ";" + rect.getMinY() + ";" + rect.getWidth() + ";" + rect.getHeight());      config.add(element);    }    return config;  }  /**   * Sets the current obstacles depending on the given XML elements.   *    * @see #getConfigXML()   * @param configXML   *          Config XML elements   * @return True if config was set successfully, false otherwise   */  public boolean setConfigXML(Collection<Element> configXML) {    for (Element element : configXML) {      if (element.getName().equals("obst")) {        String rectValues[] = element.getText().split(";");        Rectangle2D newObst = new Rectangle2D.Double(            Double.parseDouble(rectValues[0]),            Double.parseDouble(rectValues[1]),            Double.parseDouble(rectValues[2]),            Double.parseDouble(rectValues[3]));        this.addObstacle(newObst, false);      }    }    return true;      }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -