2016-05-11 21:31:47 +00:00
|
|
|
/* ========================================================================
|
|
|
|
* PlantUML : a free UML diagram generator
|
|
|
|
* ========================================================================
|
|
|
|
*
|
2019-01-16 18:34:41 +00:00
|
|
|
* (C) Copyright 2009-2020, Arnaud Roques
|
2016-05-11 21:31:47 +00:00
|
|
|
*
|
|
|
|
* Project Info: http://plantuml.com
|
|
|
|
*
|
2017-03-15 19:13:31 +00:00
|
|
|
* 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
|
|
|
|
*
|
2016-05-11 21:31:47 +00:00
|
|
|
* 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.activitydiagram3.ftile;
|
|
|
|
|
|
|
|
import java.awt.geom.Line2D;
|
|
|
|
import java.awt.geom.Point2D;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import net.sourceforge.plantuml.Direction;
|
|
|
|
import net.sourceforge.plantuml.cucadiagram.LinkStyle;
|
|
|
|
import net.sourceforge.plantuml.graphic.HtmlColorAndStyle;
|
2018-06-12 20:50:45 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.MinMax;
|
2016-05-11 21:31:47 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
|
|
|
|
import net.sourceforge.plantuml.ugraphic.UChangeColor;
|
|
|
|
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
|
|
|
import net.sourceforge.plantuml.ugraphic.ULine;
|
|
|
|
import net.sourceforge.plantuml.ugraphic.UPolygon;
|
|
|
|
import net.sourceforge.plantuml.ugraphic.UStroke;
|
|
|
|
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
2020-03-18 10:50:02 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
2019-04-21 20:40:01 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.comp.CompressionMode;
|
2016-05-11 21:31:47 +00:00
|
|
|
|
|
|
|
public class Worm implements Iterable<Point2D.Double> {
|
|
|
|
|
|
|
|
private final List<Point2D.Double> points = new ArrayList<Point2D.Double>();
|
|
|
|
|
2016-12-14 21:01:03 +00:00
|
|
|
public boolean isPureHorizontal() {
|
|
|
|
return points.size() == 2 && points.get(0).getY() == points.get(1).getY();
|
|
|
|
}
|
|
|
|
|
2019-04-21 20:40:01 +00:00
|
|
|
private boolean ignoreForCompression;
|
|
|
|
|
2020-03-18 10:50:02 +00:00
|
|
|
public final void setIgnoreForCompression() {
|
|
|
|
this.ignoreForCompression = true;
|
2019-04-21 20:40:01 +00:00
|
|
|
}
|
|
|
|
|
2019-03-01 22:16:29 +00:00
|
|
|
public void drawInternalOneColor(UPolygon startDecoration, UGraphic ug, HtmlColorAndStyle color, double stroke,
|
|
|
|
Direction emphasizeDirection, UPolygon endDecoration) {
|
2020-03-18 10:50:02 +00:00
|
|
|
final HColor color2 = color.getColor();
|
2016-05-11 21:31:47 +00:00
|
|
|
if (color2 == null) {
|
|
|
|
throw new IllegalArgumentException();
|
|
|
|
}
|
|
|
|
final LinkStyle style = color.getStyle();
|
2017-10-07 09:46:53 +00:00
|
|
|
if (style.isInvisible()) {
|
2016-05-11 21:31:47 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
ug = ug.apply(new UChangeColor(color2));
|
|
|
|
ug = ug.apply(new UChangeBackColor(color2));
|
2017-10-07 09:46:53 +00:00
|
|
|
if (style.isNormal()) {
|
2016-05-11 21:31:47 +00:00
|
|
|
ug = ug.apply(new UStroke(stroke));
|
|
|
|
} else {
|
2017-10-07 09:46:53 +00:00
|
|
|
ug = ug.apply(style.goThickness(stroke).getStroke3());
|
2016-05-11 21:31:47 +00:00
|
|
|
}
|
|
|
|
boolean drawn = false;
|
|
|
|
for (int i = 0; i < points.size() - 1; i++) {
|
|
|
|
final java.awt.geom.Point2D.Double p1 = points.get(i);
|
|
|
|
final java.awt.geom.Point2D.Double p2 = points.get(i + 1);
|
|
|
|
final Line2D line = new Line2D.Double(p1, p2);
|
|
|
|
if (drawn == false && emphasizeDirection != null && Direction.fromVector(p1, p2) == emphasizeDirection) {
|
|
|
|
drawLine(ug, line, emphasizeDirection);
|
|
|
|
drawn = true;
|
|
|
|
} else {
|
|
|
|
drawLine(ug, line, null);
|
|
|
|
}
|
|
|
|
}
|
2019-03-01 22:16:29 +00:00
|
|
|
if (startDecoration != null) {
|
|
|
|
ug = ug.apply(new UStroke(1.5));
|
|
|
|
final Point2D start = points.get(0);
|
2019-04-21 20:40:01 +00:00
|
|
|
if (ignoreForCompression) {
|
|
|
|
startDecoration.setIgnoreForCompression(CompressionMode.ON_X);
|
|
|
|
}
|
2019-03-01 22:16:29 +00:00
|
|
|
ug.apply(new UTranslate(start)).apply(new UStroke()).draw(startDecoration);
|
|
|
|
}
|
2016-05-11 21:31:47 +00:00
|
|
|
if (endDecoration != null) {
|
|
|
|
ug = ug.apply(new UStroke(1.5));
|
|
|
|
final Point2D end = points.get(points.size() - 1);
|
2019-04-21 20:40:01 +00:00
|
|
|
if (ignoreForCompression) {
|
|
|
|
endDecoration.setIgnoreForCompression(CompressionMode.ON_X);
|
|
|
|
}
|
2016-05-11 21:31:47 +00:00
|
|
|
ug.apply(new UTranslate(end)).apply(new UStroke()).draw(endDecoration);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void drawLine(UGraphic ug, Line2D line, Direction direction) {
|
|
|
|
drawLine(ug, line.getX1(), line.getY1(), line.getX2(), line.getY2(), direction);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void drawLine(UGraphic ug, double x1, double y1, double x2, double y2, Direction direction) {
|
|
|
|
ug = ug.apply(new UTranslate(x1, y1));
|
|
|
|
if (direction != null) {
|
|
|
|
ug.apply(new UTranslate((x2 - x1) / 2, (y2 - y1) / 2)).draw(Arrows.asTo(direction));
|
|
|
|
}
|
|
|
|
ug.draw(new ULine(x2 - x1, y2 - y1));
|
|
|
|
}
|
|
|
|
|
|
|
|
public Worm move(double dx, double dy) {
|
|
|
|
final Worm result = new Worm();
|
|
|
|
for (Point2D pt : points) {
|
|
|
|
result.addPoint(pt.getX() + dx, pt.getY() + dy);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-07-25 19:25:28 +00:00
|
|
|
public Worm moveFirstPoint(UTranslate move) {
|
|
|
|
final double dx = move.getDx();
|
|
|
|
final double dy = move.getDy();
|
|
|
|
if (dx != 0 && dy != 0) {
|
|
|
|
throw new IllegalArgumentException("move=" + move);
|
|
|
|
}
|
|
|
|
final Worm result = new Worm();
|
|
|
|
double x0 = this.points.get(0).getX();
|
|
|
|
double y0 = this.points.get(0).getY();
|
|
|
|
double x1 = this.points.get(1).getX();
|
|
|
|
double y1 = this.points.get(1).getY();
|
|
|
|
|
|
|
|
if (dx != 0 && x0 == x1) {
|
|
|
|
x1 += dx;
|
|
|
|
}
|
|
|
|
if (dy != 0 && y0 == y1) {
|
|
|
|
y1 += dy;
|
|
|
|
}
|
|
|
|
x0 += dx;
|
|
|
|
y0 += dy;
|
|
|
|
|
|
|
|
result.addPoint(x0, y0);
|
|
|
|
result.addPoint(x1, y1);
|
|
|
|
for (int i = 2; i < this.points.size(); i++) {
|
|
|
|
result.addPoint(this.points.get(i));
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Worm moveLastPoint(UTranslate move) {
|
|
|
|
final double dx = move.getDx();
|
|
|
|
final double dy = move.getDy();
|
|
|
|
if (dx != 0 && dy != 0) {
|
|
|
|
throw new IllegalArgumentException("move=" + move);
|
|
|
|
}
|
|
|
|
final Worm result = new Worm();
|
|
|
|
double x8 = this.points.get(this.points.size() - 2).getX();
|
|
|
|
double y8 = this.points.get(this.points.size() - 2).getY();
|
|
|
|
double x9 = this.points.get(this.points.size() - 1).getX();
|
|
|
|
double y9 = this.points.get(this.points.size() - 1).getY();
|
|
|
|
|
|
|
|
if (dx != 0 && x8 == x9) {
|
|
|
|
x8 += dx;
|
|
|
|
}
|
|
|
|
if (dy != 0 && y8 == y9) {
|
|
|
|
y8 += dy;
|
|
|
|
}
|
|
|
|
x9 += dx;
|
|
|
|
y9 += dy;
|
|
|
|
|
|
|
|
for (int i = 0; i < this.points.size() - 2; i++) {
|
|
|
|
result.addPoint(this.points.get(i));
|
|
|
|
}
|
|
|
|
result.addPoint(x8, y8);
|
|
|
|
result.addPoint(x9, y9);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-05-11 21:31:47 +00:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
final StringBuilder result = new StringBuilder();
|
|
|
|
for (int i = 0; i < points.size() - 1; i++) {
|
|
|
|
result.append(getDirectionAtPoint(i) + " ");
|
|
|
|
}
|
|
|
|
return result + points.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addPoint(double x, double y) {
|
2019-05-24 19:59:31 +00:00
|
|
|
if (points.size() > 0) {
|
|
|
|
final Point2D last = getLast();
|
|
|
|
if (last.getX() == x && last.getY() == y) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2016-05-11 21:31:47 +00:00
|
|
|
this.points.add(new Point2D.Double(x, y));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addPoint(Point2D pt) {
|
|
|
|
this.addPoint(pt.getX(), pt.getY());
|
|
|
|
}
|
|
|
|
|
|
|
|
public Worm translate(UTranslate translate) {
|
|
|
|
return move(translate.getDx(), translate.getDy());
|
|
|
|
}
|
|
|
|
|
|
|
|
SnakeDirection getDirection() {
|
|
|
|
if (points.size() < 2) {
|
|
|
|
throw new IllegalStateException();
|
|
|
|
}
|
|
|
|
return SnakeDirection.getDirection(points.get(0), points.get(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
String getDirectionsCode() {
|
|
|
|
final StringBuilder result = new StringBuilder();
|
|
|
|
for (int i = 0; i < points.size() - 1; i++) {
|
|
|
|
final Direction direction = Direction.fromVector(points.get(i), points.get(i + 1));
|
|
|
|
result.append(direction.getShortCode());
|
|
|
|
}
|
|
|
|
return result.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
private List<Direction> getPatternAt(int i) {
|
|
|
|
return Arrays.asList(getDirectionAtPoint(i), getDirectionAtPoint(i + 1), getDirectionAtPoint(i + 2),
|
|
|
|
getDirectionAtPoint(i + 3));
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isForwardAndBackwardAt(int i) {
|
|
|
|
return getDirectionAtPoint(i) == getDirectionAtPoint(i + 1).getInv();
|
|
|
|
}
|
|
|
|
|
|
|
|
private Direction getDirectionAtPoint(int i) {
|
|
|
|
return Direction.fromVector(points.get(i), points.get(i + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
public Iterator<Point2D.Double> iterator() {
|
|
|
|
return Collections.unmodifiableCollection(points).iterator();
|
|
|
|
}
|
|
|
|
|
2018-06-12 20:50:45 +00:00
|
|
|
public boolean doesHorizontalCross(MinMax area) {
|
|
|
|
for (int i = 0; i < points.size() - 1; i++) {
|
|
|
|
final Point2D.Double pt1 = get(i);
|
|
|
|
final Point2D.Double pt2 = get(i + 1);
|
|
|
|
if (pt1.getY() == pt2.getY() && area.doesHorizontalCross(pt1, pt2)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-05-11 21:31:47 +00:00
|
|
|
public int size() {
|
|
|
|
return this.points.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Point2D.Double get(int i) {
|
|
|
|
return this.points.get(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addAll(Worm other) {
|
|
|
|
this.points.addAll(other.points);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void remove(int i) {
|
|
|
|
this.points.remove(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void add(int i, Point2D.Double pt) {
|
|
|
|
this.points.add(i, pt);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Point2D getFirst() {
|
|
|
|
return points.get(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Point2D getLast() {
|
|
|
|
return points.get(points.size() - 1);
|
|
|
|
}
|
|
|
|
|
2016-08-25 20:45:37 +00:00
|
|
|
public Worm merge(Worm other, MergeStrategy merge) {
|
2016-05-11 21:31:47 +00:00
|
|
|
if (Snake.same(this.getLast(), other.getFirst()) == false) {
|
|
|
|
throw new IllegalArgumentException();
|
|
|
|
}
|
|
|
|
final Worm result = new Worm();
|
|
|
|
result.points.addAll(this.points);
|
|
|
|
result.points.addAll(other.points);
|
2016-08-25 20:45:37 +00:00
|
|
|
result.mergeMe(merge);
|
2016-05-11 21:31:47 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-08-25 20:45:37 +00:00
|
|
|
private void mergeMe(MergeStrategy merge) {
|
2016-05-11 21:31:47 +00:00
|
|
|
boolean change = false;
|
|
|
|
do {
|
|
|
|
change = false;
|
|
|
|
change = change || removeNullVector();
|
|
|
|
change = change || removeRedondantDirection();
|
|
|
|
change = change || removePattern1();
|
|
|
|
change = change || removePattern2();
|
|
|
|
change = change || removePattern3();
|
|
|
|
change = change || removePattern4();
|
|
|
|
change = change || removePattern5();
|
|
|
|
change = change || removePattern6();
|
|
|
|
change = change || removePattern7();
|
2016-08-25 20:45:37 +00:00
|
|
|
if (merge == MergeStrategy.FULL) {
|
|
|
|
change = change || removePattern8();
|
|
|
|
}
|
2016-05-11 21:31:47 +00:00
|
|
|
} while (change);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removeNullVector() {
|
|
|
|
for (int i = 0; i < points.size() - 1; i++) {
|
|
|
|
final Direction dir = getDirectionAtPoint(i);
|
|
|
|
if (dir == null) {
|
|
|
|
points.remove(i);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removeRedondantDirection() {
|
|
|
|
for (int i = 0; i < points.size() - 2; i++) {
|
|
|
|
final Direction dir1 = getDirectionAtPoint(i);
|
|
|
|
final Direction dir2 = getDirectionAtPoint(i + 1);
|
|
|
|
if (dir1 == dir2) {
|
|
|
|
points.remove(i + 1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removePattern1() {
|
|
|
|
for (int i = 0; i < points.size() - 5; i++) {
|
|
|
|
final List<Direction> patternAt = getPatternAt(i);
|
|
|
|
if (Arrays.asList(Direction.DOWN, Direction.LEFT, Direction.DOWN, Direction.RIGHT).equals(patternAt)
|
|
|
|
|| Arrays.asList(Direction.DOWN, Direction.RIGHT, Direction.DOWN, Direction.LEFT).equals(patternAt)) {
|
|
|
|
final Point2D.Double newPoint = new Point2D.Double(points.get(i + 1).x, points.get(i + 3).y);
|
|
|
|
points.remove(i + 3);
|
|
|
|
points.remove(i + 2);
|
|
|
|
points.remove(i + 1);
|
|
|
|
points.add(i + 1, newPoint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removePattern7() {
|
|
|
|
if (points.size() > 4) {
|
|
|
|
final int i = 0;
|
|
|
|
final List<Direction> patternAt = getPatternAt(i);
|
|
|
|
if (Arrays.asList(Direction.RIGHT, Direction.DOWN, Direction.LEFT, Direction.DOWN).equals(patternAt)
|
|
|
|
&& points.get(i + 3).x > points.get(i).x) {
|
|
|
|
final Point2D.Double newPoint = new Point2D.Double(points.get(i + 3).x, points.get(i).y);
|
|
|
|
points.remove(i + 2);
|
|
|
|
points.remove(i + 1);
|
|
|
|
points.add(i + 1, newPoint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removePattern2() {
|
|
|
|
for (int i = 0; i < points.size() - 5; i++) {
|
|
|
|
final List<Direction> patternAt = getPatternAt(i);
|
|
|
|
if (Arrays.asList(Direction.RIGHT, Direction.DOWN, Direction.RIGHT, Direction.UP).equals(patternAt)
|
|
|
|
|| Arrays.asList(Direction.LEFT, Direction.DOWN, Direction.LEFT, Direction.UP).equals(patternAt)) {
|
|
|
|
final Point2D.Double newPoint = new Point2D.Double(points.get(i + 3).x, points.get(i + 1).y);
|
|
|
|
points.remove(i + 3);
|
|
|
|
points.remove(i + 2);
|
|
|
|
points.remove(i + 1);
|
|
|
|
points.add(i + 1, newPoint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removePattern3() {
|
|
|
|
for (int i = 0; i < points.size() - 4; i++) {
|
|
|
|
final List<Direction> patternAt = getPatternAt(i);
|
|
|
|
if (Arrays.asList(Direction.DOWN, Direction.RIGHT, Direction.DOWN, Direction.RIGHT).equals(patternAt)
|
|
|
|
|| Arrays.asList(Direction.DOWN, Direction.LEFT, Direction.DOWN, Direction.LEFT).equals(patternAt)) {
|
|
|
|
final Point2D.Double newPoint = new Point2D.Double(points.get(i + 1).x, points.get(i + 3).y);
|
|
|
|
points.remove(i + 3);
|
|
|
|
points.remove(i + 2);
|
|
|
|
points.remove(i + 1);
|
|
|
|
points.add(i + 1, newPoint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removePattern4() {
|
|
|
|
final int i = points.size() - 5;
|
|
|
|
if (i >= 0) {
|
|
|
|
final List<Direction> patternAt = getPatternAt(i);
|
|
|
|
if (Arrays.asList(Direction.DOWN, Direction.LEFT, Direction.DOWN, Direction.RIGHT).equals(patternAt)) {
|
|
|
|
final Point2D.Double p1 = points.get(i + 1);
|
|
|
|
final Point2D.Double p4 = points.get(i + 4);
|
|
|
|
if (p4.x > p1.x) {
|
|
|
|
final Point2D.Double newPoint = new Point2D.Double(points.get(i + 1).x, points.get(i + 3).y);
|
|
|
|
points.remove(i + 3);
|
|
|
|
points.remove(i + 2);
|
|
|
|
points.remove(i + 1);
|
|
|
|
points.add(i + 1, newPoint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removePattern5() {
|
|
|
|
final int i = points.size() - 5;
|
|
|
|
if (i >= 0) {
|
|
|
|
final List<Direction> patternAt = getPatternAt(i);
|
|
|
|
if (Arrays.asList(Direction.DOWN, Direction.RIGHT, Direction.DOWN, Direction.LEFT).equals(patternAt)) {
|
|
|
|
final Point2D.Double p1 = points.get(i + 1);
|
|
|
|
final Point2D.Double p4 = points.get(i + 4);
|
|
|
|
if (p4.x + 4 < p1.x) {
|
|
|
|
final Point2D.Double newPoint = new Point2D.Double(points.get(i + 1).x, points.get(i + 3).y);
|
|
|
|
points.remove(i + 3);
|
|
|
|
points.remove(i + 2);
|
|
|
|
points.remove(i + 1);
|
|
|
|
points.add(i + 1, newPoint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removePattern6() {
|
|
|
|
for (int i = 0; i < points.size() - 2; i++) {
|
|
|
|
if (isForwardAndBackwardAt(i)) {
|
|
|
|
points.remove(i + 1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-25 20:45:37 +00:00
|
|
|
private boolean removePattern8() {
|
|
|
|
for (int i = 0; i < points.size() - 4; i++) {
|
|
|
|
final List<Direction> patternAt = getPatternAt(i);
|
|
|
|
if (Arrays.asList(Direction.LEFT, Direction.DOWN, Direction.LEFT, Direction.DOWN).equals(patternAt)
|
|
|
|
|| Arrays.asList(Direction.RIGHT, Direction.DOWN, Direction.RIGHT, Direction.DOWN)
|
|
|
|
.equals(patternAt)) {
|
|
|
|
final Point2D.Double newPoint = new Point2D.Double(points.get(i + 3).x, points.get(i + 1).y);
|
|
|
|
points.remove(i + 3);
|
|
|
|
points.remove(i + 2);
|
|
|
|
points.remove(i + 1);
|
|
|
|
points.add(i + 1, newPoint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-05-11 21:31:47 +00:00
|
|
|
}
|