📄 channelmodel.java
字号:
// Guessing we need to recalculate input to FSPL+Output power needToPrecalculateFSPL = true; needToPrecalculateOutputPower = true; settingsObservable.notifySettingsChanged(); } /** * Returns a parameter description * * @param identifier Parameter identifier * @return Current parameter description */ public String getParameterDescription(String id) { Object value = parameterDescriptions.get(id); if (value == null) { logger.fatal("No parameter description with id:" + id + ", aborting"); return null; } return ((String) value); } /** * When this method is called all settings observers * will be notified. */ public void notifySettingsChanged() { settingsObservable.notifySettingsChanged(); } /** * Returns the Free Space Path Loss factor (in dB), by using * parts of the Friis equation. (FSPL <= 0) * * @param distance Distance from transmitter to receiver * @return FSPL factor */ protected double getFSPL(double distance) { // From Friis equation: // Pr(d) = Pt * (Gt * Gr * w2) / ( (4*PI)2 * d2 * L) // For FSPL, ignoring Pt, Gt, Gr, L: // Pr(d) = 1 * (1 * 1 * w2) / ( (4*PI)2 * d2 * 1) // Pr(d) = w2 / ( (4*PI)2 * d2) // Pr_dB(d) = 20*log10(w) - 20*log10(4*PI) - 20*log10(d) if (needToPrecalculateFSPL) { double w = getParameterDoubleValue("wavelength"); paramFSPL = 20*Math.log10(w) - 20*Math.log10(4*Math.PI); needToPrecalculateFSPL = false; } return Math.min(0.0, paramFSPL - 20*Math.log10(distance)); } /** * Returns the subset of a given line, that is intersecting the given rectangle. * This method returns null if the line does not intersect the rectangle. * The given line is defined by the given (x1, y1) -> (x2, y2). * * @param x1 Line start point X * @param y1 Line start point Y * @param x2 Line end point X * @param y2 Line epoint Y * @param rectangle Rectangle which line may intersect * @return Intersection line of given line and rectangle (or null) */ private Line2D getIntersectionLine(double x1, double y1, double x2, double y2, Rectangle2D rectangle) { // Check if entire line is inside rectangle if (rectangle.contains(x1, y1) && rectangle.contains(x2, y2)) { return new Line2D.Double(x1, y1, x2, y2); } // Get rectangle and test lines Line2D rectangleLower = new Line2D.Double(rectangle.getMinX(), rectangle.getMinY(), rectangle.getMaxX(), rectangle.getMinY()); Line2D rectangleUpper = new Line2D.Double(rectangle.getMinX(), rectangle.getMaxY(), rectangle.getMaxX(), rectangle.getMaxY()); Line2D rectangleLeft = new Line2D.Double(rectangle.getMinX(), rectangle.getMinY(), rectangle.getMinX(), rectangle.getMaxY()); Line2D rectangleRight = new Line2D.Double(rectangle.getMaxX(), rectangle.getMinY(), rectangle.getMaxX(), rectangle.getMaxY()); Line2D testLine = new Line2D.Double(x1, y1, x2, y2); // Check which sides of the rectangle the test line passes through Vector<Line2D> intersectedSides = new Vector<Line2D>(); if (rectangleLower.intersectsLine(testLine)) intersectedSides.add(rectangleLower); if (rectangleUpper.intersectsLine(testLine)) intersectedSides.add(rectangleUpper); if (rectangleLeft.intersectsLine(testLine)) intersectedSides.add(rectangleLeft); if (rectangleRight.intersectsLine(testLine)) intersectedSides.add(rectangleRight); // If no sides are intersected, return null (no intersection) if (intersectedSides.isEmpty()) { return null; } // Calculate all resulting line points (should be 2) Vector<Point2D> intersectingLinePoints = new Vector<Point2D>(); for (int i=0; i < intersectedSides.size(); i++) { intersectingLinePoints.add( getIntersectionPoint(testLine, intersectedSides.get(i)) ); } // If only one side was intersected, one point must be inside rectangle if (intersectingLinePoints.size() == 1) { if (rectangle.contains(x1, y1)) { intersectingLinePoints.add(new Point2D.Double(x1, y1)); } else if (rectangle.contains(x2, y2)) { intersectingLinePoints.add(new Point2D.Double(x2, y2)); } else { // Border case, no intersection line return null; } } if (intersectingLinePoints.size() != 2) { // We should have 2 line points! logger.warn("Intersecting points != 2"); return null; } if (intersectingLinePoints.get(0).distance(intersectingLinePoints.get(1)) < 0.001) return null; return new Line2D.Double( intersectingLinePoints.get(0), intersectingLinePoints.get(1) ); } /** * Returns the intersection point of the two given lines. * * @param firstLine First line * @param secondLine Second line * @return Intersection point of the two lines or null */ private Point2D getIntersectionPoint(Line2D firstLine, Line2D secondLine) { double dx1 = firstLine.getX2() - firstLine.getX1(); double dy1 = firstLine.getY2() - firstLine.getY1(); double dx2 = secondLine.getX2() - secondLine.getX1(); double dy2 = secondLine.getY2() - secondLine.getY1(); double det = (dx2*dy1-dy2*dx1); if (det == 0.0) // Lines parallell, not intersecting return null; double mu = ((firstLine.getX1() - secondLine.getX1())*dy1 - (firstLine.getY1() - secondLine.getY1())*dx1)/det; if (mu >= 0.0 && mu <= 1.0) { Point2D.Double intersectionPoint = new Point2D.Double((secondLine.getX1() + mu*dx2), (secondLine.getY1() + mu*dy2)); return intersectionPoint; } // Lines not intersecting withing segments return null; } /** * Returns the intersection point of the two given lines when streched to infinity. * * @param firstLine First line * @param secondLine Second line * @return Intersection point of the two infinite lines or null if parallell */ private Point2D getIntersectionPointInfinite(Line2D firstLine, Line2D secondLine) { double dx1 = firstLine.getX2() - firstLine.getX1(); double dy1 = firstLine.getY2() - firstLine.getY1(); double dx2 = secondLine.getX2() - secondLine.getX1(); double dy2 = secondLine.getY2() - secondLine.getY1(); double det = (dx2*dy1-dy2*dx1); if (det == 0.0) // Lines parallell, not intersecting return null; double mu = ((firstLine.getX1() - secondLine.getX1())*dy1 - (firstLine.getY1() - secondLine.getY1())*dx1)/det; Point2D.Double intersectionPoint = new Point2D.Double((secondLine.getX1() + mu*dx2), (secondLine.getY1() + mu*dy2)); return intersectionPoint; } /** * This method builds a tree structure with all visible lines from a given source. * It is recursive and depends on the given ray data argument, which holds information * about maximum number of recursions. * Each element in the tree is either produced from a refraction, reflection or a diffraction * (except for the absolute source which is neither), and holds a point and a line. * * @param rayData Holds information about the incident ray * @return Tree of all visibles lines */ private DefaultMutableTreeNode buildVisibleLinesTree(RayData rayData) { DefaultMutableTreeNode thisTree = new DefaultMutableTreeNode(); thisTree.setUserObject(rayData); // If no more rays may be produced there if no need to search for visible lines if (rayData.getSubRaysLimit() <= 0) { return thisTree; } Point2D source = rayData.getSourcePoint(); Line2D line = rayData.getLine(); // Find all visible lines Vector<Line2D> visibleSides = getAllVisibleSides( source.getX(), source.getY(), null, line ); // Create refracted subtrees if (rayData.getRefractedSubRaysLimit() > 0 && visibleSides != null) { Enumeration<Line2D> visibleSidesEnum = visibleSides.elements(); while (visibleSidesEnum.hasMoreElements()) { Line2D refractingSide = visibleSidesEnum.nextElement(); // Keeping old source, but looking through this line to see behind it // Recursively build and add subtrees RayData newRayData = new RayData( RayData.RayType.REFRACTION, source, refractingSide, rayData.getSubRaysLimit() - 1, rayData.getRefractedSubRaysLimit() - 1, rayData.getReflectedSubRaysLimit(), rayData.getDiffractedSubRaysLimit() ); DefaultMutableTreeNode subTree = buildVisibleLinesTree(newRayData); thisTree.add(subTree); } } // Create reflection subtrees if (rayData.getReflectedSubRaysLimit() > 0 && visibleSides != null) { Enumeration<Line2D> visibleSidesEnum = visibleSides.elements(); while (visibleSidesEnum.hasMoreElements()) { Line2D reflectingSide = visibleSidesEnum.nextElement(); // Create new pseudo-source Rectangle2D bounds = reflectingSide.getBounds2D(); double newPsuedoSourceX = source.getX(); double newPsuedoSourceY = source.getY(); if (bounds.getHeight() > bounds.getWidth()) newPsuedoSourceX = 2*reflectingSide.getX1() - newPsuedoSourceX; else newPsuedoSourceY = 2*reflectingSide.getY1() - newPsuedoSourceY; // Recursively build and add subtrees RayData newRayData = new RayData( RayData.RayType.REFLECTION, new Point2D.Double(newPsuedoSourceX, newPsuedoSourceY), reflectingSide, rayData.getSubRaysLimit() - 1, rayData.getRefractedSubRaysLimit(), rayData.getReflectedSubRaysLimit() - 1, rayData.getDiffractedSubRaysLimit() ); DefaultMutableTreeNode subTree = buildVisibleLinesTree(newRayData); thisTree.add(subTree); } } // Get possible diffraction sources Vector<Point2D> diffractionSources = null; if (rayData.getDiffractedSubRaysLimit() > 0) { diffractionSources = getAllDiffractionSources(visibleSides); } // Create diffraction subtrees if (rayData.getDiffractedSubRaysLimit() > 0 && diffractionSources != null) { Enumeration<Point2D> diffractionSourcesEnum = diffractionSources.elements(); while (diffractionSourcesEnum.hasMoreElements()) { Point2D diffractionSource = diffractionSourcesEnum.nextElement(); // Recursively build and add subtrees RayData newRayData = new RayData( RayData.RayType.DIFFRACTION, diffractionSource, null, rayData.getSubRaysLimit() - 1, rayData.getRefractedSubRaysLimit(), rayData.getReflectedSubRaysLimit(), rayData.getDiffractedSubRaysLimit() - 1 ); DefaultMutableTreeNode subTree = buildVisibleLinesTree(newRayData); thisTree.add(subTree); } } return thisTree; } /** * Returns a vector of ray paths from given origin to given destination. * Each ray path consists of a vector of points (including source and destination). * * @param origin Ray paths origin * @param dest Ray paths destination * @param visibleLinesTree Information about all visible lines generated by buildVisibleLinesTree() * @see #buildVisibleLinesTree(RayData) * @return All ray paths from origin to destnation */ private Vector<RayPath> getConnectingPaths(Point2D origin, Point2D dest, DefaultMutableTreeNode visibleLinesTree) { Vector<RayPath> allPaths = new Vector<RayPath>(); // Analyse the possible paths to find which actually reached destination Enumeration treeEnum = visibleLinesTree.breadthFirstEnumeration();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -