/** * 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; }