diff --git a/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/Circle.java b/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/Circle.java new file mode 100644 index 00000000..fa5236c4 --- /dev/null +++ b/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/Circle.java @@ -0,0 +1,78 @@ +package de.unistuttgart.informatik.fius.jvk.provided.shapes; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.lang.Math; +import de.unistuttgart.informatik.fius.icge.simulation.Position; + + +/** + * A finite length line shape. + */ +public class Circle implements Shape { + + private List points; + + /** + * Create a Circle, at the middle of the field. With the radius 1; + * + */ + public Circle() { + this(new Position(0, 0), 1); + } + + /** + * Create a Circle, at the middle of the field + * + * @param radius + * the radius of the circle + */ + public Circle(Integer radius) { + this(new Position(0, 0), radius); + } + + + /** + * Create a Circle + * + * @param middle + * the center of the circle + * @param radius + * the radius of the circle + */ + public Circle(Position middle, Integer radius) { + Integer deltaX = middle.getX(); + Integer deltaY = middle.getY(); + + List points = new ArrayList<>(); + List pointsAdd = new ArrayList<>(); + for(Integer x = 0; x < radius;x++){ + Double y = Math.sin(Math.acos(x.doubleValue()/radius))*radius; + points.add(new Position(x,(int)Math.round(y))); + } + for(Integer y = 0; y < radius;y++){ + Double x = Math.cos(Math.asin(y.doubleValue()/radius))*radius; + Position position = new Position((int)Math.round(x),y); + if(!points.contains(position)){ + points.add(position); + } + } + points.forEach(p -> pointsAdd.add(new Position(p.getX(), -1*p.getY()))); + pointsAdd.forEach(p -> {if(!points.contains(p))points.add(p);} ); + pointsAdd.clear(); + points.forEach(p -> pointsAdd.add(new Position(-1*p.getX(), p.getY()))); + pointsAdd.forEach(p -> {if(!points.contains(p))points.add(p);} ); + pointsAdd.clear(); + points.forEach(p->{ + pointsAdd.add(new Position(p.getX()+middle.getX(), p.getY()+middle.getY())); + }); + this.points=pointsAdd; + } + + @Override + public Iterator iterator() { + return this.points.iterator(); + } + +} diff --git a/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/FilledShape.java b/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/FilledShape.java new file mode 100644 index 00000000..a5bcf970 --- /dev/null +++ b/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/FilledShape.java @@ -0,0 +1,118 @@ +package de.unistuttgart.informatik.fius.jvk.provided.shapes; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.Stack; + +import de.unistuttgart.informatik.fius.icge.simulation.Position; + +/** + * A shape created by filling out an existing shape. + */ +public class FilledShape implements Shape { + + private Set points; + + /** + * Create a new shape by filling out the given shape. + * + * @param shape the input shape + */ + public FilledShape(Shape shape) { + Set points = new HashSet<>(); + + points.addAll(shape); + + if (points.isEmpty()) { + this.points = points; + return; + } + + // calc bounding box... + Integer x1 = Integer.MAX_VALUE; + Integer x2 = Integer.MIN_VALUE; + Integer y1 = Integer.MAX_VALUE; + Integer y2 = Integer.MIN_VALUE; + for (Position pos : points) { + if (pos.getX() < x1) { + x1 = pos.getX(); + } + if (pos.getX() > x2) { + x2 = pos.getX(); + } + if (pos.getY() < y1) { + y1 = pos.getY(); + } + if (pos.getY() > y2) { + y2 = pos.getY(); + } + } + + Set outside = new HashSet<>(); + for (Integer y = y1; y <= y2; y++) { + outside.add(new Position(x1-1, y)); + outside.add(new Position(x2+1, y)); + } + for (Integer x = x1; x <= x2; x++) { + outside.add(new Position(x, y1-1)); + outside.add(new Position(x, y2+1)); + } + + Set visited = new HashSet<>(); + Stack stack = new Stack<>(); + + // flood fill outside + stack.push(new Position(x1-1, y1-1)); + while (!stack.isEmpty()) { + Position current = stack.pop(); + if (visited.contains(current)) { + continue; + } + visited.add(current); + if (current.getX() < x1 - 1) continue; + if (current.getX() > x2 + 1) continue; + if (current.getY() < y1 - 1) continue; + if (current.getY() > y2 + 1) continue; + if (!points.contains(current)) { + outside.add(current); + + stack.push(new Position(current.getX(), current.getY()-1)); + stack.push(new Position(current.getX()-1, current.getY())); + stack.push(new Position(current.getX(), current.getY()+1)); + stack.push(new Position(current.getX()+1, current.getY())); + } + } + + + // flood fill inside + visited.clear(); + for (Position pos : points) { + stack.push(pos); + } + while (!stack.isEmpty()) { + Position current = stack.pop(); + if (visited.contains(current)) { + continue; + } + visited.add(current); + if (!outside.contains(current)) { + points.add(current); + + stack.push(new Position(current.getX(), current.getY()-1)); + stack.push(new Position(current.getX()-1, current.getY())); + stack.push(new Position(current.getX(), current.getY()+1)); + stack.push(new Position(current.getX()+1, current.getY())); + } + } + + this.points = points; + } + + @Override + public Iterator iterator() { + return this.points.iterator(); + } + +} diff --git a/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/Line.java b/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/Line.java index 1a42b7a3..a0fd82a7 100644 --- a/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/Line.java +++ b/project/src/main/java/de/unistuttgart/informatik/fius/jvk/provided/shapes/Line.java @@ -3,63 +3,51 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; - +import java.lang.Math; import de.unistuttgart.informatik.fius.icge.simulation.Position; + /** - * A finite length line shape that is always parallel to the coordinate axes. + * A finite length line shape. */ public class Line implements Shape { - + private List points; - + /** * Create a new line by specifying start and end position of the line. * - * @param start the start of the line - * @param end the end of the line; may not differ from the line start in both x and y direction + * @param start + * the start of the line + * @param end + * the end of the line; may not differ from the line start in both x and y direction */ public Line(Position start, Position end) { - Integer deltaX = start.getX() - end.getX(); - Integer deltaY = start.getY() - end.getY(); - - if (deltaX != 0 && deltaY != 0) { - throw new IllegalArgumentException("Only lines parallel to the grid are supported."); - } - + Integer deltaX = end.getX() - start.getX(); + Integer deltaY = end.getY() - start.getY(); + Double slope; //slope needs to have digits after the . ,so Float is used List points = new ArrayList<>(); - points.add(start); - - Position currentPos = start; - while (deltaX != 0 || deltaY != 0) { - if (deltaX > 0) { - currentPos = new Position(currentPos.getX() - 1, currentPos.getY()); - points.add(currentPos); - deltaX -= 1; - } - if (deltaX < 0) { - currentPos = new Position(currentPos.getX() + 1, currentPos.getY()); - points.add(currentPos); - deltaX += 1; + + if (Math.abs(deltaX) > Math.abs(deltaY)) { + slope = deltaY.doubleValue() / deltaX.doubleValue(); + for (Integer x = start.getX(); (deltaX > 0) ? x <= end.getX() : x >= end.getX(); x += ((deltaX > 0 ? 1 : -1))) { + Integer y = (int)Math.round(x.doubleValue() * slope+start.getY()); + points.add(new Position(x, y)); } - if (deltaY > 0) { - currentPos = new Position(currentPos.getX(), currentPos.getY() - 1); - points.add(currentPos); - deltaY -= 1; - } - if (deltaY < 0) { - currentPos = new Position(currentPos.getX(), currentPos.getY() + 1); - points.add(currentPos); - deltaY += 1; + } + else{ + slope = deltaX.doubleValue() / deltaY.doubleValue(); + for(Integer y = start.getY(); (deltaY > 0) ? y <= end.getY() : y >= end.getY(); y += ((deltaY > 0 ? 1 : -1))){ + Integer x = (int)Math.round(y.doubleValue() * slope +start.getX()); + points.add(new Position(x, y)); } } - this.points = points; } - + @Override public Iterator iterator() { return this.points.iterator(); } - -} \ No newline at end of file + +}