blob: 34ba3d57c70a65e98cfe8e31f8ca55ab1d96bdf5 [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2013, 2013 SAP AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP AG - initial API, implementation and documentation
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.fmc.blockdiagram.editor.algorithm.node;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.fmc.blockdiagram.editor.util.FMCUtil;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.MultiText;
import org.eclipse.graphiti.mm.algorithms.Polygon;
import org.eclipse.graphiti.mm.algorithms.styles.Point;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Shape;
/**
* This abstract class implements all methods common to L-shaped polygons.
*
* 43 xx 0xx5x 1xxx2
*
* @author Benjamin Schmeling
* @author Heiko Witteborg
*
*/
public abstract class AbstractLPolygonAlgorithm extends
AbstractPolygonAlgorithm implements LPolygonAlgorithm {
// ----------------------------------------
// ----------- (L)Polygon Impl ------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.PolygonAlgorithm#getInitialPoints(int,
* int, int, int)
*/
public List<Point> getInitialPoints(int x, int y, int width, int height) {
int outerCornerSize = hasRoundedCorners() ? L_PART_DEFAULT_SIZE / 2 : 0;
int innerCornerSize = hasRoundedCorners() ? outerCornerSize * 2 / 3 : 0;
List<Point> points = new ArrayList<Point>();
/* 0 */points.add(ga.createPoint(x, y + height - L_PART_DEFAULT_SIZE,
outerCornerSize, outerCornerSize));
/* 1 */points.add(ga.createPoint(x, y + height, outerCornerSize,
outerCornerSize));
/* 2 */points.add(ga.createPoint(x + width, y + height,
outerCornerSize, outerCornerSize));
/* 3 */points.add(ga.createPoint(x + width, y, outerCornerSize,
outerCornerSize));
/* 4 */points.add(ga.createPoint(x + width - L_PART_DEFAULT_SIZE, y,
outerCornerSize, outerCornerSize));
/* 5 */points.add(ga.createPoint(x + width - L_PART_DEFAULT_SIZE, y
+ height - L_PART_DEFAULT_SIZE, innerCornerSize,
innerCornerSize));
return points;
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.graphicsalgorithms.LPolygonAlgorithm#
* getBottomPartSize(org.eclipse.graphiti.mm.algorithms.Polygon)
*/
public int getBottomPartSize(Polygon polygon) {
EList<Point> points = polygon.getPoints();
if (isFlattened(polygon))
return Math.abs(points.get(1).getX() - points.get(5).getX());
else
return Math.abs(points.get(1).getY() - points.get(5).getY());
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.graphicsalgorithms.LPolygonAlgorithm#
* getRightPartSize(org.eclipse.graphiti.mm.algorithms.Polygon)
*/
public int getRightPartSize(Polygon polygon) {
EList<Point> points = polygon.getPoints();
if (isFlattened(polygon))
return Math.abs(points.get(3).getY() - points.get(4).getY());
else
return Math.abs(points.get(3).getX() - points.get(4).getX());
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.graphicsalgorithms.LPolygonAlgorithm#
* resizeBottomPart(org.eclipse.graphiti.mm.algorithms.Polygon, int)
*/
public void resizeBottomPart(Polygon polygon, int size) {
if (size < LPolygonAlgorithm.L_PART_MINIMUM_SIZE) {
size = LPolygonAlgorithm.L_PART_MINIMUM_SIZE;
}
int oldSize = getBottomPartSize(polygon);
int sizeDif = isFlipped(polygon) ? oldSize - size : size - oldSize;
EList<Point> points = polygon.getPoints();
if (sizeDif != 0) {
switch (getAngle(polygon)) {
case 90:
points.get(0).setX(points.get(0).getX() + sizeDif);
points.get(5).setX(points.get(5).getX() + sizeDif);
break;
case 180:
points.get(0).setY(points.get(0).getY() + sizeDif);
points.get(5).setY(points.get(5).getY() + sizeDif);
break;
case 270:
points.get(0).setX(points.get(0).getX() - sizeDif);
points.get(5).setX(points.get(5).getX() - sizeDif);
break;
default:
points.get(0).setY(points.get(0).getY() - sizeDif);
points.get(5).setY(points.get(5).getY() - sizeDif);
}
// adapt corner roundings if storage
if (hasRoundedCorners()) {
int cornerSize = getBottomPartLeftCornerSize(polygon);
int innerCornerSize = getBottomPartRightCornerSize(polygon);
points.get(0).setBefore(cornerSize);
points.get(0).setAfter(cornerSize);
points.get(1).setBefore(cornerSize);
points.get(1).setAfter(cornerSize);
points.get(2).setBefore(innerCornerSize);
points.get(5).setAfter(innerCornerSize);
}
}
EList<GraphicsAlgorithm> graphicsAlgorithmChildren = polygon
.getGraphicsAlgorithmChildren();
for (int i = 0; i < graphicsAlgorithmChildren.size(); i++) {
// Resize bottom part of polygon children
if (graphicsAlgorithmChildren.get(i) instanceof Polygon)
this.resizeBottomPart(
(Polygon) graphicsAlgorithmChildren.get(i), size);
// Update relative anchors when the ga modification is done
if (i == graphicsAlgorithmChildren.size() - 1)
createBoxAnchorSet(this.getContainerShape(polygon));
}
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.graphicsalgorithms.LPolygonAlgorithm#
* resizeRightPart(org.eclipse.graphiti.mm.algorithms.Polygon, int)
*/
public void resizeRightPart(Polygon polygon, int size) {
if (size < LPolygonAlgorithm.L_PART_MINIMUM_SIZE) {
size = LPolygonAlgorithm.L_PART_MINIMUM_SIZE;
}
int oldSize = getRightPartSize(polygon);
int sizeDif = size - oldSize;
EList<Point> points = polygon.getPoints();
if (sizeDif != 0) {
switch (getAngle(polygon)) {
case 90:
points.get(4).setY(points.get(4).getY() - sizeDif);
points.get(5).setY(points.get(5).getY() - sizeDif);
break;
case 180:
points.get(4).setX(points.get(4).getX() + sizeDif);
points.get(5).setX(points.get(5).getX() + sizeDif);
break;
case 270:
points.get(4).setY(points.get(4).getY() + sizeDif);
points.get(5).setY(points.get(5).getY() + sizeDif);
break;
default:
points.get(4).setX(points.get(4).getX() - sizeDif);
points.get(5).setX(points.get(5).getX() - sizeDif);
}
// adapt corner roundings if polygon has rounded corners
if (hasRoundedCorners()) {
int cornerSize = getRightPartTopCornerSize(polygon);
int innerCornerSize = getRightPartBottomCornerSize(polygon);
points.get(3).setBefore(cornerSize);
points.get(3).setAfter(cornerSize);
points.get(4).setBefore(cornerSize);
points.get(4).setAfter(cornerSize);
points.get(5).setBefore(innerCornerSize);
points.get(2).setAfter(innerCornerSize);
}
}
relocateText(polygon);
EList<GraphicsAlgorithm> graphicsAlgorithmChildren = polygon
.getGraphicsAlgorithmChildren();
for (int i = 0; i < graphicsAlgorithmChildren.size(); i++) {
// Resize right part of polygon children
if (graphicsAlgorithmChildren.get(i) instanceof Polygon)
this.resizeRightPart(
(Polygon) graphicsAlgorithmChildren.get(i), size);
// Update relative anchors when the ga modification is done
if (i == graphicsAlgorithmChildren.size() - 1)
createBoxAnchorSet(this.getContainerShape(polygon));
}
}
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.LPolygonAlgorithm#getRightPartTopCornerSize
* (org.eclipse.graphiti.mm.algorithms.Polygon)
*/
public int getRightPartTopCornerSize(Polygon polygon) {
return getRightPartSize(polygon) / 2;
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.node.LPolygonAlgorithm#
* getBottomPartLeftCornerSize(org.eclipse.graphiti.mm.algorithms.Polygon)
*/
public int getBottomPartLeftCornerSize(Polygon polygon) {
return getBottomPartSize(polygon) / 2;
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.node.LPolygonAlgorithm#
* getRightPartBottomCornerSize(org.eclipse.graphiti.mm.algorithms.Polygon)
*/
public int getRightPartBottomCornerSize(Polygon polygon) {
return getRightPartTopCornerSize(polygon);
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.node.LPolygonAlgorithm#
* getBottomPartRightCornerSize(org.eclipse.graphiti.mm.algorithms.Polygon)
*/
public int getBottomPartRightCornerSize(Polygon polygon) {
return getBottomPartLeftCornerSize(polygon);
}
// ----------------------------------------
// ----------- Rotatable Node -------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.RotatableNode#getAngle(org.eclipse.graphiti
* .mm.algorithms.GraphicsAlgorithm)
*/
public int getAngle(GraphicsAlgorithm graphicsAlgorithm) {
Polygon polygon = (Polygon) graphicsAlgorithm;
EList<Point> points = polygon.getPoints();
Point point1 = points.get(1);
Point point2 = points.get(2);
if (point2.getY() == point1.getY()) {
return (point2.getX() > point1.getX()) ? 0 : 180;
} else {
return (point2.getY() > point1.getY()) ? 90 : 270;
}
}
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.RotatableNode#isFlipped(org.eclipse.
* graphiti.mm.algorithms.GraphicsAlgorithm)
*/
public boolean isFlipped(GraphicsAlgorithm graphicsAlgorithm) {
Polygon polygon = (Polygon) graphicsAlgorithm;
EList<Point> points = polygon.getPoints();
Point point2 = points.get(2);
Point point3 = points.get(3);
switch (getAngle(polygon)) {
case 90:
return (point2.getX() < point3.getX()) ? false : true;
case 180:
return (point2.getY() < point3.getY()) ? false : true;
case 270:
return (point2.getX() > point3.getX()) ? false : true;
default:
return (point2.getY() > point3.getY()) ? false : true;
}
}
/**
* Is the angle of the L polygon 90 or 270?
*
* @param polygon
* @return True, if angle is 90 or 270
*/
protected boolean isFlattened(Polygon polygon) {
double oldAngle = getAngle(polygon);
return (oldAngle % 180) == 90;
}
// ----------------------------------------
// ----------- Resizable Node -------------
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.polygon.AbstractPolygonAlgorithm#resize(org
* .eclipse.graphiti.mm.algorithms.GraphicsAlgorithm, int, int, int, int)
*/
public void resize(GraphicsAlgorithm algorithm, int x, int y, int width,
int height) {
Polygon polygon = (Polygon) algorithm;
int angle = getAngle(polygon);
int[] resizeX;
int[] resizeY;
if (isFlipped(polygon)) {
switch (angle) {
case 90:
resizeX = new int[4];
resizeX[0] = 0;
resizeX[1] = 1;
resizeX[2] = 2;
resizeX[3] = 5;
resizeY = new int[4];
resizeY[0] = 2;
resizeY[1] = 3;
resizeY[2] = 4;
resizeY[3] = 5;
break;
case 180:
resizeX = new int[2];
resizeX[0] = 0;
resizeX[1] = 1;
resizeY = new int[4];
resizeY[0] = 0;
resizeY[1] = 1;
resizeY[2] = 2;
resizeY[3] = 5;
break;
case 270:
resizeX = new int[2];
resizeX[0] = 3;
resizeX[1] = 4;
resizeY = new int[2];
resizeY[0] = 0;
resizeY[1] = 1;
break;
default:
resizeX = new int[4];
resizeX[0] = 2;
resizeX[1] = 3;
resizeX[2] = 4;
resizeX[3] = 5;
resizeY = new int[2];
resizeY[0] = 3;
resizeY[1] = 4;
}
} else {
switch (angle) {
case 90:
resizeX = new int[2];
resizeX[0] = 3;
resizeX[1] = 4;
resizeY = new int[4];
resizeY[0] = 2;
resizeY[1] = 3;
resizeY[2] = 4;
resizeY[3] = 5;
break;
case 180:
resizeX = new int[2];
resizeX[0] = 0;
resizeX[1] = 1;
resizeY = new int[2];
resizeY[0] = 3;
resizeY[1] = 4;
break;
case 270:
resizeX = new int[4];
resizeX[0] = 0;
resizeX[1] = 1;
resizeX[2] = 2;
resizeX[3] = 5;
resizeY = new int[2];
resizeY[0] = 0;
resizeY[1] = 1;
break;
default:
resizeX = new int[4];
resizeX[0] = 2;
resizeX[1] = 3;
resizeX[2] = 4;
resizeX[3] = 5;
resizeY = new int[4];
resizeY[0] = 0;
resizeY[1] = 1;
resizeY[2] = 2;
resizeY[3] = 5;
}
}
int oldHeight = polygon.getHeight();
int oldWidth = polygon.getWidth();
int heightDif = height - oldHeight;
int widthDif = width - oldWidth;
EList<Point> points = polygon.getPoints();
for (int i = 0; i < resizeX.length; i++) {
points.get(resizeX[i]).setX(
points.get(resizeX[i]).getX() + widthDif);
}
for (int i = 0; i < resizeY.length; i++) {
points.get(resizeY[i]).setY(
points.get(resizeY[i]).getY() + heightDif);
}
// adapt corner roundings if polygon has rounded corners
if (hasRoundedCorners()) {
int rightCornerSize = getRightPartTopCornerSize(polygon);
int rightInnerBottomCornerSize = getRightPartBottomCornerSize(polygon);
int bottomCornerSize = getBottomPartLeftCornerSize(polygon);
int bottomInnerRightCornerSize = getBottomPartRightCornerSize(polygon);
points.get(0).setBefore(bottomCornerSize);
points.get(0).setAfter(bottomCornerSize);
points.get(1).setBefore(bottomCornerSize);
points.get(1).setAfter(bottomCornerSize);
points.get(2).setBefore(bottomInnerRightCornerSize);
points.get(2).setAfter(rightInnerBottomCornerSize);
points.get(3).setBefore(rightCornerSize);
points.get(3).setAfter(rightCornerSize);
points.get(4).setBefore(rightCornerSize);
points.get(4).setAfter(rightCornerSize);
points.get(5).setBefore(rightInnerBottomCornerSize);
points.get(5).setAfter(bottomInnerRightCornerSize);
}
ga.setLocationAndSize(polygon, x, y, width, height);
relocateText(polygon);
// adapt first level container (relative anchors + invisible shape)
ContainerShape container = this.getContainerShape(polygon);
createBoxAnchorSet(container);
synchronizeFirstLevelShape(container);
}
// ----------------------------------------
// ----------- Named Node -----------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.NamedNode#relocateText(org.eclipse.graphiti
* .mm.algorithms.GraphicsAlgorithm)
*/
public void relocateText(GraphicsAlgorithm graphicsAlgorithm) {
MultiText text = this.getText(graphicsAlgorithm);
if (text != null) {
int multipleOffset = 0;
if (this.isMultipleInstances(this
.getContainerShape(graphicsAlgorithm))) {
multipleOffset = MULTI_INSTANCE_GAP;
}
int angle = getAngle(graphicsAlgorithm);
int textContainingPartSize;
boolean isOnTop;
textContainingPartSize = (angle == 0 || angle == 180) ? getBottomPartSize((Polygon) graphicsAlgorithm)
: getRightPartSize((Polygon) graphicsAlgorithm);
if (isFlipped(graphicsAlgorithm)) {
isOnTop = (angle == 0 || angle == 270) ? true : false;
} else {
isOnTop = (angle == 180 || angle == 270) ? true : false;
}
int x = super.textMargin;
int width = graphicsAlgorithm.getWidth() - 2 * super.textMargin
- multipleOffset;
int y = (isOnTop ? super.textMargin : graphicsAlgorithm.getHeight()
- textContainingPartSize + super.textMargin)
+ multipleOffset;
int height = textContainingPartSize - 2 * super.textMargin
- multipleOffset;
ga.setLocationAndSize(text, x, y, width, height);
}
}
// ----------------------------------------
// ----------- Anchored Node --------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.AbstractNode#addBoxAnchorSet(org.eclipse
* .graphiti.mm.pictograms.ContainerShape)
*/
protected void addBoxAnchorSet(Shape shape) {
GraphicsAlgorithm firstLevelPolygon = shape.getGraphicsAlgorithm();
Polygon secondLevelPolygon = (Polygon) firstLevelPolygon
.getGraphicsAlgorithmChildren().get(0);
// Sides of the polygon:
// 3
// ---
// | |
// 4 | |
// 5 | | 2
// ------- |
// 0 | |
// -----------
// 1
int numSides = 6;
int lineWidth = getDefaultLineWidth();
Point[] point = new Point[numSides];
for (int i = 0; i < point.length; i++) {
point[i] = secondLevelPolygon.getPoints().get(i);
}
// Offset in case of a multi instance shape (adapt anchors when drawing
// background part)
double offsetMultiInstance = 0.0d;
if (firstLevelPolygon.getWidth() != secondLevelPolygon.getWidth()) {
// Remove anchors created when drawing the main part
FMCUtil.removeObsoleteAnchors(shape);
offsetMultiInstance = MULTI_INSTANCE_GAP;
}
// Length of the sides (not taking into account rounded corners)
int[] length = new int[numSides];
length[0] = getBottomPartSize(secondLevelPolygon) + lineWidth;
length[1] = Math.abs(isFlattened(secondLevelPolygon) ? point[1].getY()
- point[2].getY() : point[1].getX() - point[2].getX());
length[2] = Math.abs(isFlattened(secondLevelPolygon) ? point[2].getX()
- point[3].getX() : point[2].getY() - point[3].getY());
length[3] = getRightPartSize(secondLevelPolygon) + lineWidth;
length[4] = length[2] - length[0];
length[5] = length[1] - length[3];
// Length of the sides that should contain anchors
int[] anchoredLength = new int[numSides];
for (int i = 0; i < numSides; i++)
anchoredLength[i] = Math.max(length[i] - point[i].getAfter()
- point[(i + 1) % numSides].getBefore(),
DEFAULT_ANCHOR_DIAMETER);
// Number of anchors of the sides
int[] numAnchors = new int[numSides];
// Gaps between the anchor starting points of the sides (in x and y
// direction)
double[][] gaps = new double[numSides][2];
for (int i = 0; i < gaps.length; i++)
for (int j = 0; j < gaps[i].length; j++)
gaps[i][j] = 0.0d;
// Offsets of the starting points of the sides (in x and y direction)
double[][] offset = new double[numSides][2];
switch (getAngle(secondLevelPolygon)) {
case 90:
if (isFlipped(secondLevelPolygon)) {
// specify relative starting points of polygon line segments
offset[0][1] = 0.0d;
offset[0][0] = length[4] + offsetMultiInstance;
offset[1][1] = 0.0d;
offset[1][0] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[2][1] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[2][0] = 0.0d;
offset[3][1] = length[5] + offsetMultiInstance;
offset[3][0] = 0.0d;
offset[4][1] = length[5];
offset[4][0] = offsetMultiInstance;
offset[5][1] = offsetMultiInstance;
offset[5][0] = length[4];
// adjust length of segments due to overlapping of multi
// instances
length[4] = length[4] - (int) offsetMultiInstance;
} else {
// specify relative starting points of polygon line segments
offset[0][1] = 0.0d;
offset[0][0] = offsetMultiInstance;
offset[1][1] = offsetMultiInstance;
offset[1][0] = 0.0d;
offset[2][1] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[2][0] = 0.0d;
offset[3][1] = length[5];
offset[3][0] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[4][1] = length[5];
offset[4][0] = length[0] + offsetMultiInstance;
offset[5][1] = 0.0d;
offset[5][0] = length[0] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
}
break;
case 180:
if (isFlipped(secondLevelPolygon)) {
// specify relative starting points of polygon line segments
offset[0][1] = length[4];
offset[0][0] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[1][1] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[1][0] = 0.0d;
offset[2][1] = offsetMultiInstance;
offset[2][0] = 0.0d;
offset[3][1] = 0.0d;
offset[3][0] = offsetMultiInstance;
offset[4][1] = 0.0d;
offset[4][0] = length[3] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[5][1] = length[4];
offset[5][0] = length[3] + offsetMultiInstance;
} else {
// specify relative starting points of polygon line segments
offset[0][1] = 0.0d;
offset[0][0] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[1][1] = 0.0d;
offset[1][0] = offsetMultiInstance;
offset[2][1] = offsetMultiInstance;
offset[2][0] = 0.0d;
offset[3][1] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[3][0] = 0.0d;
offset[4][1] = length[0] + offsetMultiInstance;
offset[4][0] = length[3] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[5][1] = length[0] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[5][0] = length[3] + offsetMultiInstance;
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[4].getAfter())
anchoredLength[4] = anchoredLength[4]
- (int) (offsetMultiInstance - point[5].getBefore());
}
break;
case 270:
if (isFlipped(secondLevelPolygon)) {
// specify relative starting points of polygon line segments
offset[0][1] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[0][0] = 0.0d;
offset[1][1] = offsetMultiInstance;
offset[1][0] = 0.0d;
offset[2][1] = 0.0d;
offset[2][0] = offsetMultiInstance;
offset[3][1] = 0.0d;
offset[3][0] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[4][1] = length[3] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[4][0] = length[0] + offsetMultiInstance;
offset[5][1] = length[3] + offsetMultiInstance;
offset[5][0] = length[0] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[4].getAfter())
anchoredLength[4] = anchoredLength[4]
- (int) (offsetMultiInstance - point[5].getBefore());
if (offsetMultiInstance > point[5].getAfter())
anchoredLength[5] = anchoredLength[5]
- (int) (offsetMultiInstance - point[5].getAfter());
} else {
// specify relative starting points of polygon line segments
offset[0][1] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[0][0] = length[4];
offset[1][1] = 0.0d;
offset[1][0] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[2][1] = 0.0d;
offset[2][0] = offsetMultiInstance;
offset[3][1] = offsetMultiInstance;
offset[3][0] = 0.0d;
offset[4][1] = length[3] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[4][0] = 0.0d;
offset[5][1] = length[3] + offsetMultiInstance;
offset[5][0] = length[4];
}
break;
default: // rotation = 0
if (isFlipped(secondLevelPolygon)) {
// specify relative starting points of polygon line segments
offset[0][1] = offsetMultiInstance;
offset[0][0] = 0.0d;
offset[1][1] = 0.0d;
offset[1][0] = offsetMultiInstance;
offset[2][1] = 0.0d;
offset[2][0] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[3][1] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[3][0] = length[5];
offset[4][1] = length[0] + offsetMultiInstance;
offset[4][0] = length[5];
offset[5][1] = length[0] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[5][0] = 0.0d;
} else {
// specify relative starting points of polygon line segments
offset[0][1] = length[4] + offsetMultiInstance;
offset[0][0] = 0.0d;
offset[1][1] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[1][0] = 0.0d;
offset[2][1] = 0.0d;
offset[2][0] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[3][1] = 0.0d;
offset[3][0] = length[5] + offsetMultiInstance;
offset[4][1] = offsetMultiInstance;
offset[4][0] = length[5];
offset[5][1] = length[4];
offset[5][0] = offsetMultiInstance;
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[5].getAfter())
anchoredLength[5] = anchoredLength[5]
- (int) (offsetMultiInstance - point[5].getAfter());
}
}
// adjust offsets according to rounded corners
for (int i = 0; i < numSides; i++) {
if (point[i].getX() == point[(i + 1) % numSides].getX()) { // vertical
// side
offset[i][1] = offset[i][1]
+ (point[i].getY() < point[(i + 1) % numSides].getY() ? (point[i]
.getAfter() > 0 ? point[i].getAfter()
- ((double) DEFAULT_ANCHOR_DIAMETER) / 2 : 0.0d)
: (point[(i + 1) % numSides].getBefore() > 0 ? point[(i + 1)
% numSides].getBefore()
- ((double) DEFAULT_ANCHOR_DIAMETER)
/ 2
: 0.0d));
} else { // horizontal side
offset[i][0] = offset[i][0]
+ (point[i].getX() < point[(i + 1) % numSides].getX() ? (point[i]
.getAfter() > 0 ? point[i].getAfter()
- ((double) DEFAULT_ANCHOR_DIAMETER) / 2 : 0.0d)
: (point[(i + 1) % numSides].getBefore() > 0 ? point[(i + 1)
% numSides].getBefore()
- ((double) DEFAULT_ANCHOR_DIAMETER)
/ 2
: 0.0d));
}
}
// Calculate number of anchors per side
for (int i = 0; i < numSides; i++)
numAnchors[i] = anchoredLength[i] / DEFAULT_ANCHOR_GAP;
// Calculate gaps between the starting points of the anchors for each
// side
int direction = 0;
for (int i = 0; i < numSides; i++) {
direction = isFlattened(secondLevelPolygon) ? (i % 2)
: ((i + 1) % 2);
gaps[i][direction] = ((double) anchoredLength[i]) / numAnchors[i];
}
// Create relative box anchors
for (int i = 0; i < numSides; i++)
for (int j = 0; j < numAnchors[i]; j++)
createBoxAnchor(shape, (offset[i][0] + j * gaps[i][0])
/ firstLevelPolygon.getWidth(), (offset[i][1] + j
* gaps[i][1])
/ firstLevelPolygon.getHeight(),
AnchoredNode.DEFAULT_ANCHOR_GAP,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER);
}
}