/** * Compute the position of a sprite if it is not attached. * * @param sprite The sprite. * @param pos Where to stored the computed position, if null, the position is created. * @param units The units the computed position must be given into. * @return The same instance as pos, or a new one if pos was null. */ protected Point2D.Double getSpritePositionFree( GraphicSprite sprite, Point2D.Double pos, Units units) { if (pos == null) pos = new Point2D.Double(); if (sprite.getUnits() == units) { pos.x = sprite.getX(); pos.y = sprite.getY(); } else if (units == Units.GU && sprite.getUnits() == Units.PX) { pos.x = sprite.getX(); pos.y = sprite.getY(); xT.transform(pos, pos); } else if (units == Units.PX && sprite.getUnits() == Units.GU) { pos.x = sprite.getX(); pos.y = sprite.getY(); Tx.transform(pos, pos); } else if (units == Units.GU && sprite.getUnits() == Units.PERCENTS) { pos.x = metrics.lo.x + (sprite.getX() / 100f) * metrics.graphWidthGU(); pos.y = metrics.lo.y + (sprite.getY() / 100f) * metrics.graphHeightGU(); } else if (units == Units.PX && sprite.getUnits() == Units.PERCENTS) { pos.x = (sprite.getX() / 100f) * metrics.viewport[2]; pos.y = (sprite.getY() / 100f) * metrics.viewport[3]; } else { throw new RuntimeException("Unhandled yet sprite positioning."); } return pos; }
/** * Is the given sprite visible in the given area. * * @param sprite The sprite to check. * @param X1 The min abscissa of the area. * @param Y1 The min ordinate of the area. * @param X2 The max abscissa of the area. * @param Y2 The max ordinate of the area. * @return True if the node lies in the given area. */ protected boolean isSpriteIn(GraphicSprite sprite, double X1, double Y1, double X2, double Y2) { if (sprite.isAttachedToNode() && nodeInvisible.contains(sprite.getNodeAttachment().getId())) { return false; } else if (sprite.isAttachedToEdge() && !isEdgeVisible(sprite.getEdgeAttachment())) { return false; } else { Values size = sprite.getStyle().getSize(); double w2 = metrics.lengthToPx(size, 0) / 2; double h2 = size.size() > 1 ? metrics.lengthToPx(size, 1) / 2 : w2; Point2D.Double src = spritePositionPx(sprite); // new Point2D.Double( // sprite.getX(), // sprite.getY() ); // Tx.transform( src, src ); double x1 = src.x - w2; double x2 = src.x + w2; double y1 = src.y - h2; double y2 = src.y + h2; if (x2 < X1) return false; if (y2 < Y1) return false; if (x1 > X2) return false; if (y1 > Y2) return false; return true; } }
/** * Check if a sprite contains the given point (x,y). * * @param elt The sprite. * @param x The point abscissa. * @param y The point ordinate. * @return True if (x,y) is in the given element. */ protected boolean spriteContains(GraphicElement elt, double x, double y) { Values size = elt.getStyle().getSize(); double w2 = metrics.lengthToPx(size, 0) / 2; double h2 = size.size() > 1 ? metrics.lengthToPx(size, 1) / 2 : w2; Point2D.Double dst = spritePositionPx((GraphicSprite) elt); // new // Point2D.Double( // elt.getX(), // elt.getY() // ); // Point2D.Double dst = new Point2D.Double(); // Tx.transform( src, dst ); dst.x -= metrics.viewport[0]; dst.y -= metrics.viewport[1]; double x1 = dst.x - w2; double x2 = dst.x + w2; double y1 = dst.y - h2; double y2 = dst.y + h2; if (x < x1) return false; if (y < y1) return false; if (x > x2) return false; if (y > y2) return false; return true; }
/** * Compute the position of a sprite if attached to an edge. * * @param sprite The sprite. * @param pos Where to stored the computed position, if null, the position is created. * @param units The units the computed position must be given into. * @return The same instance as pos, or a new one if pos was null. */ protected Point2D.Double getSpritePositionEdge( GraphicSprite sprite, Point2D.Double pos, Units units) { if (pos == null) pos = new Point2D.Double(); GraphicEdge edge = sprite.getEdgeAttachment(); if (edge.isCurve()) { double ctrl[] = edge.getControlPoints(); Point2 p0 = new Point2(edge.from.getX(), edge.from.getY()); Point2 p1 = new Point2(ctrl[0], ctrl[1]); Point2 p2 = new Point2(ctrl[1], ctrl[2]); Point2 p3 = new Point2(edge.to.getX(), edge.to.getY()); Vector2 perp = CubicCurve.perpendicular(p0, p1, p2, p3, sprite.getX()); double y = metrics.lengthToGu(sprite.getY(), sprite.getUnits()); perp.normalize(); perp.scalarMult(y); pos.x = CubicCurve.eval(p0.x, p1.x, p2.x, p3.x, sprite.getX()) - perp.data[0]; pos.y = CubicCurve.eval(p0.y, p1.y, p2.y, p3.y, sprite.getX()) - perp.data[1]; } else { double x = ((GraphicNode) edge.getSourceNode()).x; double y = ((GraphicNode) edge.getSourceNode()).y; double dx = ((GraphicNode) edge.getTargetNode()).x - x; double dy = ((GraphicNode) edge.getTargetNode()).y - y; double d = sprite.getX(); // Percent on the edge. double o = metrics.lengthToGu(sprite.getY(), sprite.getUnits()); // Offset from the position given by percent, perpendicular to the // edge. d = d > 1 ? 1 : d; d = d < 0 ? 0 : d; x += dx * d; y += dy * d; d = (double) Math.sqrt(dx * dx + dy * dy); dx /= d; dy /= d; x += -dy * o; y += dx * o; pos.x = x; pos.y = y; if (units == Units.PX) { Tx.transform(pos, pos); } } return pos; }
/** * Is the given node visible in the given area. * * @param node The node to check. * @param X1 The min abscissa of the area. * @param Y1 The min ordinate of the area. * @param X2 The max abscissa of the area. * @param Y2 The max ordinate of the area. * @return True if the node lies in the given area. */ protected boolean isNodeIn(GraphicNode node, double X1, double Y1, double X2, double Y2) { Values size = node.getStyle().getSize(); double w2 = metrics.lengthToPx(size, 0) / 2; double h2 = size.size() > 1 ? metrics.lengthToPx(size, 1) / 2 : w2; Point2D.Double src = new Point2D.Double(node.getX(), node.getY()); boolean vis = true; Tx.transform(src, src); double x1 = src.x - w2; double x2 = src.x + w2; double y1 = src.y - h2; double y2 = src.y + h2; if (x2 < X1) vis = false; else if (y2 < Y1) vis = false; else if (x1 > X2) vis = false; else if (y1 > Y2) vis = false; return vis; }
/** * Compute a transformation matrix that pass from graph units (user space) to pixel units (device * space) so that the whole graph is visible. * * @param g2 The Swing graphics. */ protected void autoFitView(Graphics2D g2) { double sx, sy; double tx, ty; double padXgu = getPaddingXgu() * 2; double padYgu = getPaddingYgu() * 2; double padXpx = getPaddingXpx() * 2; double padYpx = getPaddingYpx() * 2; sx = (metrics.viewport[2] - padXpx) / (metrics.size.data[0] + padXgu); // Ratio // along // X sy = (metrics.viewport[3] - padYpx) / (metrics.size.data[1] + padYgu); // Ratio // along // Y tx = metrics.lo.x + (metrics.size.data[0] / 2); // Centre of graph in X ty = metrics.lo.y + (metrics.size.data[1] / 2); // Centre of graph in Y if (sx <= 0) { sx = (metrics.viewport[2] - Math.min(metrics.viewport[2] - 1, padXpx)) / (metrics.size.data[0] + padXgu); } if (sy <= 0) { sy = (metrics.viewport[3] - Math.min(metrics.viewport[3] - 1, padYpx)) / (metrics.size.data[1] + padYgu); } if (sx > sy) // The least ratio. sx = sy; else sy = sx; g2.translate(metrics.viewport[2] / 2, metrics.viewport[3] / 2); if (rotation != 0) g2.rotate(rotation / (180 / Math.PI)); g2.scale(sx, -sy); g2.translate(-tx, -ty); Tx = g2.getTransform(); xT = new AffineTransform(Tx); try { xT.invert(); } catch (NoninvertibleTransformException e) { logger.warning("Cannot inverse gu2px matrix."); } zoom = 1; center.set(tx, ty, 0); metrics.setRatioPx2Gu(sx); metrics.loVisible.copy(metrics.lo); metrics.hiVisible.copy(metrics.hi); }
/** * Compute a transformation that pass from graph units (user space) to a pixel units (device * space) so that the view (zoom and centre) requested by the user is produced. * * @param g2 The Swing graphics. */ protected void userView(Graphics2D g2) { double sx, sy; double tx, ty; double padXgu = getPaddingXgu() * 2; double padYgu = getPaddingYgu() * 2; double padXpx = getPaddingXpx() * 2; double padYpx = getPaddingYpx() * 2; double gw = gviewport != null ? gviewport[2] - gviewport[0] : metrics.size.data[0]; double gh = gviewport != null ? gviewport[3] - gviewport[1] : metrics.size.data[1]; sx = (metrics.viewport[2] - padXpx) / ((gw + padXgu) * zoom); sy = (metrics.viewport[3] - padYpx) / ((gh + padYgu) * zoom); tx = center.x; ty = center.y; if (sx > sy) // The least ratio. sx = sy; else sy = sx; g2.translate((metrics.viewport[2] / 2), (metrics.viewport[3] / 2)); if (rotation != 0) g2.rotate(rotation / (180 / Math.PI)); g2.scale(sx, -sy); g2.translate(-tx, -ty); Tx = g2.getTransform(); xT = new AffineTransform(Tx); try { xT.invert(); } catch (NoninvertibleTransformException e) { logger.log(Level.WARNING, "Cannot inverse gu2px matrix.", e); } metrics.setRatioPx2Gu(sx); double w2 = (metrics.viewport[2] / sx) / 2; double h2 = (metrics.viewport[3] / sx) / 2; metrics.loVisible.set(center.x - w2, center.y - h2); metrics.hiVisible.set(center.x + w2, center.y + h2); }
/** * Set the output view port size in pixels. * * @param viewportWidth The width in pixels of the view port. * @param viewportHeight The width in pixels of the view port. */ public void setViewport( double viewportX, double viewportY, double viewportWidth, double viewportHeight) { metrics.setViewport(viewportX, viewportY, viewportWidth, viewportHeight); }
/* * (non-Javadoc) * * @see org.graphstream.ui.swingViewer.util.Camera#setBounds(double, double, * double, double, double, double) */ public void setBounds( double minx, double miny, double minz, double maxx, double maxy, double maxz) { metrics.setBounds(minx, miny, minz, maxx, maxy, maxz); }