📄 gannotator.java
字号:
* any other positionals. The algorithm is to start on polyline at current * location, move back and forth on the line further and further away from * the origin until a free location is found. * * @param positional Positional to adjust. * @param x X values of polyline to position along. * @param y Y values of polyline to position along. * @param pointNo Index in polyline where positional is initially * attached. */ private void findNonOverlappingPosition (GPositional positional, int x[], int y[], int pointNo) { // Find current position along polyline int x0, y0; if (distance_ == 0.0) { x0 = x[pointNo]; y0 = y[pointNo]; } else { double legLength = Geometry.length (x[pointNo], y[pointNo], x[pointNo+1], y[pointNo+1]); double fraction = (double) distance_ / (double) legLength; x0 = (int) Math.round (x[pointNo] + fraction * (x[pointNo+1] - x[pointNo])); y0 = (int) Math.round (y[pointNo] + fraction * (y[pointNo+1] - y[pointNo])); } // Find total length into the polyline double totalLength = 0.0; for (int i = 0; i < pointNo; i++) totalLength += Geometry.length (x[i], y[i], x[i+1], y[i+1]); totalLength += distance_; // Then loop alternating back and forth from x0,y0 and check position boolean isDoneLeft = false; boolean isDoneRight = false; int nAttempts = 0; // We cannot try for ever boolean isDone = false; double left = totalLength -= DLENGTH; double right = totalLength += DLENGTH; int leftPosition[] = {x0, y0}; int rightPosition[] = {x0, y0}; int position[] = new int[2]; Rect leftRectangle = new Rect (positional.getRectangle()); Rect rightRectangle = new Rect (positional.getRectangle()); int dx, dy; while (!isDone) { // Check to the left if (!isDoneLeft) { isDoneLeft = !Geometry.findPolygonPosition (x, y, left, position); if (!isDoneLeft) { dx = leftPosition[0] - position[0]; dy = leftPosition[1] - position[1]; leftRectangle.x -= dx; leftRectangle.y -= dy; if (region_.isInside (leftRectangle)) { positional.getRectangle().copy (leftRectangle); return; } } leftPosition[0] = position[0]; leftPosition[1] = position[1]; nAttempts++; } // Check to the right if (!isDoneRight) { isDoneRight = !Geometry.findPolygonPosition (x, y, right, position); if (!isDoneRight) { dx = rightPosition[0] - position[0]; dy = rightPosition[1] - position[1]; rightRectangle.x -= dx; rightRectangle.y -= dy; if (region_.isInside (rightRectangle)) { positional.getRectangle().copy (rightRectangle); return; } } rightPosition[0] = position[0]; rightPosition[1] = position[1]; nAttempts++; } left -= DLENGTH; right += DLENGTH; isDone = (isDoneLeft && isDoneRight) || nAttempts > MAX_ATTEMTS; } positional.setVisible (false); } /** * Given a polyline (x[], y[]) and a position (pointNo) on this * polyline for the positional. This function is called because we * know that pointNo is outside the visible. We find the closest * point (along line) that is inside. If none is found the positional * is set invisible and no further positioning is required. * If a point is found the positional rectangle is set to the * viewport intersection point, the polyline point is returned and * the distance_ variable is set as the distance from the positional * to the returned point. * * @param positional Positional to move inside window. * @param x X values of polyline. * @param y Y values of polyline. * @param pointNo Index of polyline where positional is initially * attached. * @return New index to attach positional to. */ private int moveInsideWindow (GPositional positional, int x[], int y[], int pointNo) { int intersection[] = null; int iPoint; // Check to the "left" of current point for (iPoint= pointNo - 1; iPoint >= 0; iPoint--) { intersection = findViewportIntersection (x[iPoint+1], y[iPoint+1], x[iPoint], y[iPoint]); if (intersection != null) break; } // Check the "right" of the current point if (intersection == null) { for (iPoint = pointNo; iPoint < x.length - 1; iPoint++) { intersection = findViewportIntersection (x[iPoint], y[iPoint], x[iPoint+1], y[iPoint+1]); if (intersection != null) break; } } if (intersection == null) positional.setVisible (false); else { positional.setVisible (true); positional.getRectangle().x = intersection[0]; positional.getRectangle().y = intersection[1]; distance_ = Geometry.length (intersection[0], intersection[1], x[iPoint], y[iPoint]); } return iPoint; } /** * Find the intersection point of the specified line segment and the * current viewport. * * @param x0 X coordinate of first line segment endpoint. * @param y0 Y coordinate of first line segment endpoint. * @param x1 X coordinate of second line segment endpoint. * @param y1 Y coordinate of second line segment endpoint. * @return Coordinate of intersection (or null if the specified * line segment doesn't intersect the viewport). */ private int[] findViewportIntersection (int x0, int y0, int x1, int y1) { double length[] = new double[2]; int x[] = new int[2]; int y[] = new int[2]; double intersection[] = new double[2]; int result[] = new int[2]; int n = 0; int type; // Top viewport edge type = Geometry.findLineSegmentIntersection (x0, y0, x1, y1, vx0_, vy0_, vx1_, vy1_, intersection); if (type == 1l) { x[n] = (int) Math.round (intersection[0]); y[n] = (int) Math.round (intersection[1]); length[n] = Geometry.length (x0, y0, x[n], y[n]); n++; } // Left viewport edge type = Geometry.findLineSegmentIntersection (x0, y0, x1, y1, vx0_, vy0_, vx2_, vy2_, intersection); if (type == 1) { x[n] = (int) Math.round (intersection[0]); y[n] = (int) Math.round (intersection[1]); length[n] = Geometry.length (x0, y0, x[n], y[n]); n++; } // Right viewport edge if (n < 2) { type = Geometry.findLineSegmentIntersection (x0, y0, x1, y1, vx1_, vy1_, vx3_, vy3_, intersection); if (type == 1) { x[n] = (int) Math.round (intersection[0]); y[n] = (int) Math.round (intersection[1]); length[n] = Geometry.length (x0, y0, x[n], y[n]); n++; } } // Bottom viewport edge if (n < 2) { type = Geometry.findLineSegmentIntersection (x0, y0, x1, y1, vx2_, vy2_, vx3_, vy3_, intersection); if (type == 1) { x[n] = (int) Math.round (intersection[0]); y[n] = (int) Math.round (intersection[1]); length[n] = Geometry.length (x0, y0, x[n], y[n]); n++; } } if (n == 0) return null; if (n == 1) { result[0] = x[0]; result[1] = y[0]; } // Intersects the viewport twice. Pick the closest else { if (length[0] < length[1]) { result[0] = x[0]; result[1] = y[0]; } else { result[0] = x[1]; result[1] = y[1]; } } return result; } /** * This method is used to position a positional on every vertex along * a polyline. The positioanl rectangle x and y values are computed * as delta measure, so that the positionals can later be positioned * by adding this delta to each vertex. * * @param positional Positional to compute position of. */ void computeVertexPositions (GPositional positional) { positional.computeSize(); int width = positional.getRectangle().width; int height = positional.getRectangle().height; int x, y; int positionHint = positional.getPositionHint(); if ((positionHint & GPosition.NORTH) != 0) { x = - (int) Math.floor (width / 2.0); y = - height; } else if ((positionHint & GPosition.SOUTH) != 0) { x = - (int) Math.floor (width / 2.0); y = 0; } else if ((positionHint & GPosition.WEST) != 0) { x = - width; y = - (int) Math.floor (height / 2.0); } else if ((positionHint & GPosition.EAST) != 0) { y = - (int) Math.floor (height / 2.0); x = 0; } else if ((positionHint & GPosition.NORTHWEST) != 0) { x = - width; y = - height; } else if ((positionHint & GPosition.NORTHEAST) != 0) { x = 0; y = - height; } else if ((positionHint & GPosition.SOUTHWEST) != 0) { x = - width; y = 0; } else if ((positionHint & GPosition.SOUTHEAST) != 0) { x = 0; y = 0; } else { // CENTER (or unset implying center) x = - (int) Math.floor (width / 2.0); y = - (int) Math.floor (height / 2.0); } positional.getRectangle().x = x; positional.getRectangle().y = y; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -