/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.posimo;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.Map;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.cucadiagram.LinkDecor;
import net.sourceforge.plantuml.cucadiagram.LinkStyle;
import net.sourceforge.plantuml.cucadiagram.LinkType;
import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UPolygon;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class PathDrawerInterface implements PathDrawer {
private final Rose rose;
private final ISkinParam param;
private final LinkType linkType;
public static PathDrawerInterface create(ISkinParam param, LinkType linkType) {
return new PathDrawerInterface(new Rose(), param, linkType);
}
private PathDrawerInterface(Rose rose, ISkinParam param, LinkType linkType) {
this.rose = rose;
this.param = param;
this.linkType = linkType;
}
public void drawPathBefore(UGraphic ug, Positionable start, Positionable end, Path path) {
// // final DotPath dotPath = path.getDotPath();
// // goDash(ug);
// // ug.draw(0, 0, dotPath);
// // noDash(ug);
}
private void noDash(UGraphic ug) {
// ug.getParam().resetStroke();
throw new UnsupportedOperationException();
}
private void goDash(UGraphic ug) {
// ug.getParam().setStroke(new UStroke(8, 8, 1.0));
throw new UnsupportedOperationException();
}
public void drawPathAfter(UGraphic ug, Positionable start, Positionable end, Path path) {
DotPath dotPath = path.getDotPath();
final Racorder racorder = new RacorderOrthogonal();
// final Racorder racorder = new RacorderInToCenter();
// final Racorder racorder = new RacorderFollowTangeante();
final Point2D endPath = dotPath.getEndPoint();
final DotPath in = racorder.getRacordIn(PositionableUtils.convert(end), dotPath.getEndTangeante());
// final Point2D inPoint = in.getFrontierIntersection(end);
final Point2D inPoint = in.getEndPoint();
// final double theta1_ = in.getEndAngle() + Math.PI / 2;
// Log.println("theta1_=" + theta1_ + " " + theta1_ * 180 /
// Math.PI);
final double theta1 = atan2(endPath, inPoint);
// Log.println("theta1=" + theta1 + " " + theta1 * 180 /
// Math.PI);
final Point2D middle1 = drawSymbol(ug, theta1, inPoint, linkType.getDecor1());
final Point2D startPath = dotPath.getStartPoint();
final DotPath out = racorder.getRacordOut(PositionableUtils.convert(start), dotPath.getStartTangeante());
// final Point2D outPoint = out.getFrontierIntersection(start);
final Point2D outPoint = out.getStartPoint();
// final double theta2_ = out.getStartAngle() - Math.PI / 2;
// Log.println("theta2_=" + theta2_ + " " + theta2_ * 180 /
// Math.PI);
final double theta2 = atan2(startPath, outPoint);
// Log.println("theta2=" + theta2 + " " + theta2 * 180 /
// Math.PI);
final Point2D middle2 = drawSymbol(ug, theta2, outPoint, linkType.getDecor2());
if (middle1 != null) {
final CubicCurve2D.Double after = getLine(endPath, middle1);
dotPath = dotPath.addAfter(after);
// dotPath = dotPath.addAfter(in);
}
if (middle2 != null) {
final CubicCurve2D.Double before = getLine(middle2, startPath);
dotPath = dotPath.addBefore(before);
// dotPath = dotPath.addBefore(out);
}
final LinkStyle style = linkType.getStyle();
// if (style == LinkStyle.__toremove_INTERFACE_PROVIDER || style == LinkStyle.__toremove_INTERFACE_USER) {
// final Decor decor = new DecorInterfaceProvider(style);
// final Map all = dotPath.somePoints();
// final Point2D p = getFarest(outPoint, inPoint, all.keySet());
//
// ug = ug.apply(new UChangeBackColor(rose.getHtmlColor(param, ColorParam.background)));
// ug = ug.apply(new UChangeColor(rose.getHtmlColor(param, ColorParam.classBorder)));
//
// decor.drawDecor(ug, p, all.get(p));
// }
throw new UnsupportedOperationException();
// ug = ug.apply(new UChangeColor(rose.getHtmlColor(param, ColorParam.classBorder)));
// if (linkType.isDashed()) {
// goDash(ug);
// }
// ug.draw(dotPath);
// if (linkType.isDashed()) {
// noDash(ug);
// }
}
private double atan2(final Point2D endPath, final Point2D inPoint) {
final double y = -endPath.getX() + inPoint.getX();
final double x = endPath.getY() - inPoint.getY();
final double angle = Math.atan2(y, x);
// Log.println("x=" + x + " y=" + y + " angle=" + angle + " " + angle * 180.0 / Math.PI);
return angle;
}
private Point2D drawSymbol(UGraphic ug, double theta, final Point2D position, LinkDecor decor) {
// if (1==1) {
// return null;
// }
// Point2D middle1 = null;
// // final double theta = Math.atan2(
// // -direction.getX() + position.getX(), direction.getY()
// // - position.getY());
// if (decor == LinkDecor.SQUARRE) {
// middle1 = drawSquare(ug, position.getX(), position.getY());
// } else if (decor == LinkDecor.EXTENDS) {
// middle1 = drawExtends(ug, position.getX(), position.getY(), theta);
// } else if (decor == LinkDecor.AGREGATION) {
// ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.background));
// ug.getParam().setColor(rose.getHtmlColor(param, ColorParam.classBorder));
// middle1 = drawDiamond(ug, position.getX(), position.getY(), theta);
// } else if (decor == LinkDecor.COMPOSITION) {
// ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.classBorder));
// ug.getParam().setColor(null);
// middle1 = drawDiamond(ug, position.getX(), position.getY(), theta);
// } else if (decor == LinkDecor.NONE) {
// middle1 = position;
// } else if (decor == LinkDecor.ARROW) {
// ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.classBorder));
// ug.getParam().setColor(rose.getHtmlColor(param, ColorParam.classBorder));
// middle1 = drawArrow(ug, position.getX(), position.getY(), theta);
// }
// return middle1;
throw new UnsupportedOperationException();
}
private CubicCurve2D.Double getLine(final Point2D p1, Point2D p2) {
return new CubicCurve2D.Double(p1.getX(), p1.getY(), p1.getX(), p1.getY(), p2.getX(), p2.getY(), p2.getX(),
p2.getY());
}
private static Point2D getFarest(Point2D p1, Point2D p2, Collection all) {
Point2D result = null;
double farest = 0;
for (Point2D p : all) {
if (result == null) {
result = p;
farest = p1.distanceSq(result) + p2.distanceSq(result);
continue;
}
final double candidat = p1.distanceSq(p) + p2.distanceSq(p);
if (candidat < farest) {
result = p;
farest = candidat;
}
}
if (result == null) {
throw new IllegalArgumentException();
}
return result;
}
private Point2D drawSquare(UGraphic ug, double centerX, double centerY) {
ug = ug.apply(new UChangeBackColor(rose.getHtmlColor(param, ColorParam.classBackground)));
ug = ug.apply(new UChangeColor(rose.getHtmlColor(param, ColorParam.classBorder)));
final double width = 10;
final double height = 10;
ug.apply(new UTranslate(centerX - width / 2, centerY - height / 2)).draw(new URectangle(width, height));
return new Point2D.Double(centerX, centerY);
}
Point2D drawExtends(UGraphic ug, double x, double y, double theta) {
ug = ug.apply(new UChangeBackColor(rose.getHtmlColor(param, ColorParam.background)));
ug = ug.apply(new UChangeColor(rose.getHtmlColor(param, ColorParam.classBorder)));
// final double theta = Math.atan2(-pathPoint.getX() + x,
// pathPoint.getY() - y);
final UPolygon triangle = new UPolygon();
triangle.addPoint(0, 1);
final double width = 18;
final double height = 26;
triangle.addPoint(-width / 2, height);
triangle.addPoint(width / 2, height);
triangle.rotate(theta);
ug.apply(new UTranslate(x, y)).draw(triangle);
final Point2D middle = BezierUtils.middle(triangle.getPoints().get(1), triangle.getPoints().get(2));
middle.setLocation(middle.getX() + x, middle.getY() + y);
return middle;
}
private Point2D drawDiamond(UGraphic ug, double x, double y, double theta) {
// final double theta = Math.atan2(-pathPoint.getX() + x,
// pathPoint.getY() - y);
final UPolygon triangle = new UPolygon();
triangle.addPoint(0, 0);
final double width = 10;
final double height = 14;
triangle.addPoint(-width / 2, height / 2);
triangle.addPoint(0, height);
triangle.addPoint(width / 2, height / 2);
triangle.rotate(theta);
ug.apply(new UTranslate(x, y)).draw(triangle);
final Point2D middle = triangle.getPoints().get(2);
middle.setLocation(middle.getX() + x, middle.getY() + y);
return middle;
}
private Point2D drawArrow(UGraphic ug, double x, double y, double theta) {
// final double theta = Math.atan2(-pathPoint.getX() + x,
// pathPoint.getY() - y);
final UPolygon triangle = new UPolygon();
triangle.addPoint(0, 0);
final double width = 12;
final double height = 10;
triangle.addPoint(-width / 2, height);
final double height2 = 4;
triangle.addPoint(0, height2);
triangle.addPoint(width / 2, height);
triangle.rotate(theta);
ug.apply(new UTranslate(x, y)).draw(triangle);
final Point2D middle = triangle.getPoints().get(2);
middle.setLocation(middle.getX() + x, middle.getY() + y);
return middle;
}
private Point2D nullIfContained(Point2D p, Positionable start, Positionable end) {
if (PositionableUtils.contains(start, p)) {
return null;
}
if (PositionableUtils.contains(end, p)) {
return null;
}
return p;
}
// private void drawPath(UGraphic ug, PointList points, Positionable start,
// Positionable end) {
// Decor decor = new DecorInterfaceProvider();
// Point2D last = null;
// final int nb = 10;
// final double t1 =
// points.getIntersectionDouble(PositionableUtils.convert(start));
// final double t2 =
// points.getIntersectionDouble(PositionableUtils.convert(end));
// for (int i = 0; i <= nb; i++) {
// final double d = t1 + (t2 - t1) * i / nb;
// final Point2D cur = nullIfContained(points.getPoint(d), start, end);
// if (last != null && cur != null) {
// ug.draw(last.getX(), last.getY(), new ULine(cur.getX() - last.getX(),
// cur.getY() - last.getY()));
// if (decor != null) {
// decor.drawLine(ug, last, cur);
// decor = null;
// }
// }
// last = cur;
// }
//
// for (Point2D p : points.getPoints()) {
// ug.draw(p.getX() - 1, p.getY() - 1, new UEllipse(2, 2));
// }
// }
}
Ads help maintain this website.