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

📄 channelmodel.java

📁 Contiki是一个开源
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                // <<<< Get visible obstacle candidates inside this angle interval >>>>        Vector<Rectangle2D> visibleObstacleCandidates =           myObstacleWorld.getAllObstaclesInAngleInterval(source, angleIntervalToCheck);                //logger.info("Obstacle candidates count = " + visibleObstacleCandidates.size());        if (visibleObstacleCandidates.isEmpty()) {          //logger.info("Visible obstacles candidates empty");          unhandledAngles.remove(angleIntervalToCheck);          break; // Restart without this angle        }                // <<<< Get visible line candidates of these obstacles >>>>        Vector<Line2D> visibleLineCandidates = new Vector<Line2D>();        for (int i=0; i < visibleObstacleCandidates.size(); i++) {          Rectangle2D obstacle = visibleObstacleCandidates.get(i);          int outcode = obstacle.outcode(source);                    if ((outcode & Rectangle2D.OUT_BOTTOM) != 0)            visibleLineCandidates.add(                new Line2D.Double(obstacle.getMinX(), obstacle.getMaxY(), obstacle.getMaxX(), obstacle.getMaxY()));                    if ((outcode & Rectangle2D.OUT_TOP) != 0)            visibleLineCandidates.add(                new Line2D.Double(obstacle.getMinX(), obstacle.getMinY(), obstacle.getMaxX(), obstacle.getMinY()));                    if ((outcode & Rectangle2D.OUT_LEFT) != 0)            visibleLineCandidates.add(                new Line2D.Double(obstacle.getMinX(), obstacle.getMinY(), obstacle.getMinX(), obstacle.getMaxY()));                    if ((outcode & Rectangle2D.OUT_RIGHT) != 0)            visibleLineCandidates.add(                new Line2D.Double(obstacle.getMaxX(), obstacle.getMinY(), obstacle.getMaxX(), obstacle.getMaxY()));        }        //logger.info("Line candidates count = " + visibleLineCandidates.size());        if (visibleLineCandidates.isEmpty()) {          //logger.info("Visible line candidates empty");          unhandledAngles.remove(angleIntervalToCheck);          break; // Restart without this angle        }                // <<<< Get cropped visible line candidates of these lines >>>>        Vector<Line2D> croppedVisibleLineCandidates = new Vector<Line2D>();        for (int i=0; i < visibleLineCandidates.size(); i++) {          Line2D lineCandidate = visibleLineCandidates.get(i);                    // Create angle interval of this line          AngleInterval lineAngleInterval = AngleInterval.getAngleIntervalOfLine(source, lineCandidate);                    AngleInterval intersectionInterval = null;          // Add entire line if it is fully inside our visible angle interval          if (angleIntervalToCheck.contains(lineAngleInterval)) {            if (lookThrough != null) {              // Check if the candidate is "equal" to the see through line              if (Math.abs(lineCandidate.getX1() - lookThrough.getX1()) +                  Math.abs(lineCandidate.getY1() - lookThrough.getY1()) +                  Math.abs(lineCandidate.getX2() - lookThrough.getX2()) +                  Math.abs(lineCandidate.getY2() - lookThrough.getY2()) < 0.01) {                // See through line and candidate line are the same - skip this candidate              }                            // Check if the candidate is on our side of the see through line              else if (new Line2D.Double(                  lineCandidate.getBounds2D().getCenterX(),                   lineCandidate.getBounds2D().getCenterY(),                  sourceX,                  sourceY              ).intersectsLine(lookThrough)) {                croppedVisibleLineCandidates.add(lineCandidate);              } // else Skip line            } else croppedVisibleLineCandidates.add(lineCandidate);                      }                     // Add part of line if it is partly inside our visible angle interval          else if ((intersectionInterval = lineAngleInterval.intersectWith(angleIntervalToCheck)) != null) {                        // Get lines towards the visible segment            Line2D lineToStartAngle = AngleInterval.getDirectedLine(                source,                intersectionInterval.getStartAngle(),                1.0            );            Line2D lineToEndAngle = AngleInterval.getDirectedLine(                source,                intersectionInterval.getEndAngle(),                1.0            );                        // Calculate intersection points            Point2D intersectionStart = getIntersectionPointInfinite(                lineCandidate,                lineToStartAngle            );            Point2D intersectionEnd = getIntersectionPointInfinite(                lineCandidate,                lineToEndAngle            );                        if (                intersectionStart != null &&                intersectionEnd != null &&                intersectionStart.distance(intersectionEnd) > 0.001 // Rounding error limit (1 mm)            ) {              Line2D newCropped = new Line2D.Double(intersectionStart, intersectionEnd);              if (lookThrough != null) {                // Check if the candidate is "equal" to the see through line                if (Math.abs(newCropped.getX1() - lookThrough.getX1()) +                    Math.abs(newCropped.getY1() - lookThrough.getY1()) +                    Math.abs(newCropped.getX2() - lookThrough.getX2()) +                    Math.abs(newCropped.getY2() - lookThrough.getY2()) < 0.01) {                  // See through line and candidate line are the same - skip this candidate                }                                // Check if the candidate is on our side of the see through line                else if (new Line2D.Double(                    newCropped.getBounds2D().getCenterX(),                     newCropped.getBounds2D().getCenterY(),                    sourceX,                    sourceY                ).intersectsLine(lookThrough)) {                  croppedVisibleLineCandidates.add(newCropped);                } // else Skip line              } else croppedVisibleLineCandidates.add(newCropped);            }          }                    // Skip line completely if not in our visible angle interval          else {          }        }        //logger.info("Cropped line candidates count = " + croppedVisibleLineCandidates.size());        if (croppedVisibleLineCandidates.isEmpty()) {          //logger.info("Cropped visible line candidates empty");          unhandledAngles.remove(angleIntervalToCheck);          break; // Restart without this angle        }                        // <<<< Get visible lines from these line candidates >>>>        for (int i=0; i < croppedVisibleLineCandidates.size(); i++) {          Line2D visibleLineCandidate = croppedVisibleLineCandidates.get(i);          AngleInterval visibleLineCandidateAngleInterval =             AngleInterval.getAngleIntervalOfLine(source, visibleLineCandidate).intersectWith(angleIntervalToCheck);                    //logger.info("Incoming angle interval " + angleIntervalToCheck);          //logger.info(". => line interval " + visibleLineCandidateAngleInterval);          // Area to test for shadowing objects          GeneralPath testArea = new GeneralPath();          testArea.moveTo((float) sourceX, (float) sourceY);          testArea.lineTo((float) visibleLineCandidate.getX1(), (float) visibleLineCandidate.getY1());          testArea.lineTo((float) visibleLineCandidate.getX2(), (float) visibleLineCandidate.getY2());          testArea.closePath();                    // Does any other line shadow this line?          boolean unshadowed = true;          boolean unhandledAnglesChanged = false;          for (int j=0; j < croppedVisibleLineCandidates.size(); j++) {                        // Create shadow rectangle            Line2D shadowLineCandidate = croppedVisibleLineCandidates.get(j);            Rectangle2D shadowRectangleCandidate = shadowLineCandidate.getBounds2D();            double minDelta = 0.01*Math.max(                shadowRectangleCandidate.getWidth(),                 shadowRectangleCandidate.getHeight()            );            shadowRectangleCandidate.add(                shadowRectangleCandidate.getCenterX() + minDelta,                shadowRectangleCandidate.getCenterY() + minDelta            );            // Find the shortest of the two            double shadowDistance =              shadowLineCandidate.getP1().distance(source) +               shadowLineCandidate.getP2().distance(source);                        double visibleDistance =              visibleLineCandidate.getP1().distance(source) +               visibleLineCandidate.getP2().distance(source);            double shadowCloseDistance =              Math.min(                  shadowLineCandidate.getP1().distance(source),                  shadowLineCandidate.getP2().distance(source));                        double visibleFarDistance =              Math.max(                  visibleLineCandidate.getP1().distance(source),                  visibleLineCandidate.getP2().distance(source));                        // Does shadow rectangle intersect test area?            if (visibleLineCandidate != shadowLineCandidate &&                testArea.intersects(shadowRectangleCandidate) &&                shadowCloseDistance <= visibleFarDistance) {                            // Shadow line candidate seems to shadow (part of) our visible candidate              AngleInterval shadowLineCandidateAngleInterval =                 AngleInterval.getAngleIntervalOfLine(source, shadowLineCandidate).intersectWith(angleIntervalToCheck);                            if (shadowLineCandidateAngleInterval.contains(visibleLineCandidateAngleInterval)) {                // Covers us entirely, do nothing                                // Special case, both shadow and visible candidate have the same interval                if (visibleLineCandidateAngleInterval.contains(shadowLineCandidateAngleInterval)) {                                    if (visibleDistance > shadowDistance) {                    unshadowed = false;                    break;                  }                } else {                  unshadowed = false;                  break;                }                              } else if (visibleLineCandidateAngleInterval.intersects(shadowLineCandidateAngleInterval)) {                // Covers us partly, split angle interval                Vector<AngleInterval> newIntervalsToAdd = new Vector<AngleInterval>();                                // Create angle interval of intersection between shadow and visible candidate                AngleInterval intersectedInterval =                   visibleLineCandidateAngleInterval.intersectWith(shadowLineCandidateAngleInterval);                if (intersectedInterval != null) {                  Vector<AngleInterval> tempVector1 =                    AngleInterval.intersect(unhandledAngles, intersectedInterval);                                    if (tempVector1 != null)                     for (int k=0; k < tempVector1.size(); k++)                       if (tempVector1.get(k) != null && !tempVector1.get(k).isEmpty()) {                        newIntervalsToAdd.add(tempVector1.get(k));                      }                }                                // Add angle interval of visible candidate without shadow candidate                Vector<AngleInterval> tempVector2 =                   visibleLineCandidateAngleInterval.subtract(shadowLineCandidateAngleInterval);                if (tempVector2 != null)                   for (int k=0; k < tempVector2.size(); k++)                     if (tempVector2.get(k) != null && !tempVector2.get(k).isEmpty())                      newIntervalsToAdd.addAll(AngleInterval.intersect(unhandledAngles, tempVector2.get(k)));                                // Subtract angle interval of visible candidate                unhandledAngles = AngleInterval.subtract(unhandledAngles, visibleLineCandidateAngleInterval);                unhandledAnglesChanged = true;                                // Add new angle intervals                //logger.info("Split angle interval: " + visibleLineCandidateAngleInterval);                for (int k=0; k < newIntervalsToAdd.size(); k++) {                  if (newIntervalsToAdd.get(k) != null && !newIntervalsToAdd.get(k).isEmpty()) {                    //logger.info("> into: " + newIntervalsToAdd.get(k));                    unhandledAngles.add(newIntervalsToAdd.get(k));                    unhandledAnglesChanged = true;                  }                }                                unshadowed = false;                break;              } else {                // Not intersecting after all, just ignore this              }            }                       if (!unshadowed)              break;          }                    if (unhandledAnglesChanged) {            //logger.info("Unhandled angles changed, restarting..");            break;          }                    if (unshadowed) {            // No other lines shadow this line => this line must be visible!                        unhandledAngles = AngleInterval.subtract(unhandledAngles, visibleLineCandidateAngleInterval);            visibleLines.add(visibleLineCandidate);                        //logger.info("Added visible line and removed angle interval: " + visibleLineCandidateAngleInterval);            //logger.info("Number of visible lines sofar: " + visibleLines.size());            break;          }                  }              }          } // End of outer loop        // Save results in order to speed up later calculations    int size = calculatedVisibleSides.size();    // Crop saved sides vectors    if (size >= maxSavedVisibleSides) {      calculatedVisibleSides.remove(size-1);      calculatedVisibleSidesSources.remove(size-1);      calculatedVisibleSidesAngleIntervals.remove(size-1);      calculatedVisibleSidesLines.remove(size-1);    }        calculatedVisibleSides.add(0, visibleLines);    calculatedVisibleSidesSources.add(0, source);    calculatedVisibleSidesAngleIntervals.add(0, angleInterval);    calculatedVisibleSidesLines.add(0, lookThrough);    return visibleLines;  }    /**   * Calculates and returns the received signal strength (dBm) of a signal sent   * from the given source position to the given destination position as a   * random variable. This method uses current parameters such as transmitted   * power, obstacles, overall system loss etc.   *    * @param sourceX   *          Source position X   * @param sourceY   *          Source position Y   * @param destX   *          Destination position X   * @param destY

⌨️ 快捷键说明

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