import java.util.ArrayList;
public class Geom {
public static void apply(Operation o, Element e) {
o.operate(e);
}
public static void visit(Visitor vr, Visitable vb) {
vb.accept(vr);
}
public static void iterate(Operation o, Iterable c) {
Iterator it = c.getIterator();
while (it.hasNext()) {
o.operate(it.next());
}
}
public static void convertToSvg(Element e) {
System.out.println("<svg version=\"1.1\" baseProfile=\"full\" xmlns=\"http://www.w3.org/2000/svg\">");
e.accept(new ConvertToSvg());
System.out.println("</svg>");
}
public static void main(String[] args) {
Line l1 = new Line(0, 0, 50, 50, "red");
Circle c1 = new Circle(25, 25, 10, "blue");
Container ct = new Container("green");
ct.addElement(l1);
ct.addElement(c1);
convertToSvg(ct);
}
}
/* Interfaces */
interface Visitable {
public void accept(Visitor v);
}
interface Visitor {
public void visitLine(Line l);
public void visitCircle(Circle c);
public void visitContainerIn(Container ct);
public void visitContainerOut(Container ct);
}
/* Elements */
abstract class Element {
private static int counter = 0;
protected final int id;
protected String colour;
public Element(String c) {
this.id = counter++;
this.colour = c;
}
public void changeColour(String c) {
this.colour = c;
}
abstract public String toStringIndent(String offset);
abstract public void zoom(int z);
abstract public String toString();
abstract public String toSVG();
}
class Line extends Element {
protected int x1, y1;
protected int x2, y2;
public Line(int x1, int y1, int x2, int y2, String c) {
super(c);
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public String toString() {
return "Line " + this.id + " " + this.colour;
}
public String toStringIndent(String offset) {
return offset + this.toString() + "\n";
}
public void zoom(int z) {
this.x1 *= z;
this.y1 *= z;
this.x2 *= z;
this.y2 *= z;
}
public String toSVG() {
return
"<line x1=\"" + this.x1
+ "\" x2=\"" + this.x2
+ "\" y1=\"" + this.y1
+ "\" y2=\"" + this.y2
+ "\" stroke=\"" + this.colour
+ "\"/>";
}
}
class Circle extends Element {
protected int x, y;
protected int r;
public Circle(int x, int y, int r, String c) {
super(c);
this.x = x;
this.y = y;
this.r = r;
}
public String toString() {
return "Circle " + this.id + " " + this.colour;
}
public String toStringIndent(String offset) {
return offset + this.toString() + "\n";
}
public void zoom(int z) {
this.x *= z;
this.y *= z;
this.r *= z;
}
public String toSVG() {
return
"<circle cx=\"" + this.x
+ "\" cy=\"" + this.y
+ "\" r=\"" + this.r
+ "\" stroke=\"" + this.colour
+ "\"/>";
}
}
class Container extends Element {
private ArrayList<Element> elements;
public Container(String c) {
super(c);
this.elements = new ArrayList<Element>();
}
public void addElement(Element e) {
elements.add(e);
}
public String toString() {
String res = "Container " + ct.id + " " + ct.colour + " [";
for (Element elt: this.elements) {
res += elt.toString() + ", ";
}
res += "]";
return res;
}
public String toStringIndent(String offset) {
String res = offset + "Container " + ct.id + " " + ct.colour + "\n";
for (Element elt: this.elements) {
res += elt.toStringIndent(offset + " ");
}
return res;
}
public void zoom(int z) {}
public String toSVG() {
String res = "<g fill=\"" + ct.colour + "\">";
for (Element elt: this.elements) {
res += elt.toSVG();
}
res += "</g>";
return res;
}
}
/* Operations */
abstract class Operation implements Visitor {
abstract public void operate(Element e);
}
class Print extends Operation {
public void operate(Element e) {
System.out.println("Element " + e.id + " " + e.colour);
}
public void operateLine(Line l) {
System.out.println("Line " + l.id + " " + l.colour);
}
public void operateCircle(Circle c) {
System.out.println("Circle " + c.id + " " + c.colour);
}
public void visitLine(Line l) {
System.out.println("Line " + l.id + " " + l.colour);
}
public void visitCircle(Circle c) {
System.out.println("Circle " + c.id + " " + c.colour);
}
public void visitContainerIn(Container ct) {
System.out.println("Container " + ct.id + " " + ct.colour);
}
public void visitContainerOut(Container ct) {}
}
class ChangeColour extends Operation {
private String colour;
public ChangeColour(String c) {
colour = c;
}
public void operate(Element e) {
e.colour = colour;
}
public void visitLine(Line l) { operate(l); }
public void visitCircle(Circle c) { operate(c); }
public void visitContainerIn(Container ct) { operate(ct); }
public void visitContainerOut(Container ct) {}
}
class Translate extends Operation {
private int dx, dy;
public Translate(int dx, int dy) {
dx = dx; dy = dy;
}
public void operate(Element e) {
if (e instanceof Line) {
Line l = (Line)e;
l.x1 += dx; l.y1 += dy;
l.x2 += dx; l.y2 += dy;
} else {
Circle c = (Circle)e;
c.x += dx; c.y += dy;
}
}
public void visitLine(Line l) {
l.x1 += dx; l.y1 += dy;
l.x2 += dx; l.y2 += dy;
}
public void visitCircle(Circle c) {
c.x += dx; c.y += dy;
}
public void visitContainerIn(Container ct) {}
public void visitContainerOut(Container ct) {}
}
class Zoom extends Operation {
private int z;
public Zoom(int z) {
z = z;
}
public void operate(Element e) {
e.zoom(z);
}
public void visitLine(Line l) {
l.x1 *= z; l.y1 *= z;
l.x2 *= z; l.y2 *= z;
}
public void visitCircle(Circle c) {
c.x *= z; c.y *= z;
c.r *= z;
}
public void visitContainerIn(Container ct) {}
public void visitContainerOut(Container ct) {}
}
class ConvertToSvg extends Operation {
public void operate(Element e) {}
public void visitLine(Line l) {
System.out.println("<line x1=\"" + l.x1 + "\" x2=\"" + l.x2 +
"\" y1=\"" + l.y1 + "\" y2=\"" + l.y2 +
"\" stroke=\"" + l.colour + "\"/>");
}
public void visitCircle(Circle c) {
System.out.println("<circle cx=\"" + c.x + "\" cy=\"" + c.y +
"\" r=\"" + c.r +
"\" stroke=\"" + c.colour + "\"/>");
}
public void visitContainerIn(Container ct) {
System.out.println("<g fill=\"" + ct.colour + "\">");
}
public void visitContainerOut(Container ct) {
System.out.println("</g>");
}
}