/********************************************** * AOSD 10 Submission Files * * Pict.java : * * All the Pict related classes and * * functions * * * *********************************************/ import edu.neu.ccs.demeterf.Traversal; import edu.neu.ccs.demeterf.TU; import edu.neu.ccs.demeterf.TP; import edu.neu.ccs.demeterf.control.Fields; import java.io.FileOutputStream; import java.io.PrintStream; public abstract class Pict{ static Pict kspiral(int k){ return khelp(k,0,360/k); } static Pict khelp(int k, int ang, int inc){ if(k <= 1)return spiral(0,ang); return new Overlay(spiral(0,ang), khelp(k-1,ang+inc,inc)); } static Pict spiral(int r, int ang){ double rads = Math.PI*ang/180.0; Pict curr = new Offset((int)(Math.cos(rads)*r), (int)(Math.sin(rads)*r), new Circle(6)); if(r >= 800)return curr; return new Overlay(curr, spiral(r+3, (ang+5)%360)); } static void write(String what, String file) throws Exception{ PrintStream p = new PrintStream(new FileOutputStream(file)); p.print(what); p.close(); } public static void main2(String[] args){ Pict p = new Offset(1,2,new Offset(1,2,new Offset(1,2,new Offset(1,2,new Circle(15))))); System.out.println(" Start: "+p.toStr()); System.out.println(" Compr: "+new InlineParCompress(new Compress()) .traverse(p).toStr()); /*System.out.println(" Compr: "+new Traversal(new Compress()) .<Pict>traverse(p).toStr());*/ } public static void main(String[] args) throws Exception{ Pict[] pp = { //new Overlay(new Offset(-21,0,new Circle(20)), // new Offset(21,0,new Square(40))), design(120) }; //System.out.println(" Pict: "+new ToString().toStr(pp[0])); InlineParToSVG svg = new InlineParToSVG(new ToSVG()); int i = 1; for(Pict p:pp) write(SVG.image(400,400,svg.traverse(p, new Ctx(200, 200))), "file-"+(i++)+".svg"); } static Pict design(int r){ Pict curr = new Circle(r); if(r <= 2)return curr; return //new Overlay(curr, new Overlay(new Overlay(new Offset(r,0,design(2*r/5)), new Offset(0,r,design(2*r/5))), new Overlay(new Offset(-r,0,design(2*r/5)), new Offset(0,-r,design(2*r/5)))); } /* Visitor */ public static abstract class Vis<X>{ int visit(int i){ return i; } abstract X visit(Circle c); abstract X visit(Square s); abstract X visit(Offset o); abstract X visit(Overlay o); } abstract <X> X accept(Vis<X> v); abstract int size(); abstract String toStr(); boolean isOffset(){ return false; } abstract int circles(); abstract String toSVG(Ctx ctx); abstract Pict scale(int i); abstract Pict circ2sqr(); abstract Pict flip(); abstract Pict compress(); } class Circle extends Pict{ int rad; Circle(int r){ rad = r; } String toStr(){ return "Circle("+rad+")"; } <X> X accept(Vis<X> v){ return v.visit(this); } int size(){ return 1; } int circles(){ return 1; } String toSVG(Ctx ctx){ return SVG.circle(ctx.x, ctx.y, rad); } Pict scale(int i){ return new Circle(i*rad); } Pict circ2sqr(){ return new Square(rad*2); } Pict flip(){ return this; } Pict compress(){ return this; } } class Square extends Pict{ int size; Square(int s){ size = s; } String toStr(){ return "Square("+size+")"; } <X> X accept(Vis<X> v){ return v.visit(this); } int size(){ return 1; } int circles(){ return 0; } String toSVG(Ctx ctx){ return SVG.square(ctx.x, ctx.y, size); } Pict scale(int i){ return new Square(i*size); } Pict circ2sqr(){ return this; } Pict flip(){ return this; } Pict compress(){ return this; } } class Offset extends Pict{ int dx, dy; Pict inner; Offset(int x, int y, Pict in){ dx = x; dy = y; inner = in; } String toStr(){ return "Offset("+ dx+","+ dy+","+ inner.toStr()+")"; } <X> X accept(Vis<X> v){ return v.visit(this); } int size(){ return 1+inner.size(); } boolean isOffset(){ return true; } int circles(){ return inner.circles(); } String toSVG(Ctx ctx){ return inner.toSVG(ctx.move(this)); } Pict scale(int i){ return new Offset(dx*i,dy*i,inner.scale(i)); } Pict circ2sqr(){ return new Offset(dx,dy,inner.circ2sqr()); } Pict flip(){ return new Offset(dx,dy,inner.flip()); } Pict compress(){ Pict in = inner.compress(); if(in.isOffset()){ Offset inn = ((Offset)in); return new Offset(dx+inn.dx,dy+inn.dy,inn.inner); } return new Offset(dx,dy,in); } } class Overlay extends Pict{ Pict top, bot; Overlay(Pict t, Pict b){ top = t; bot = b; } String toStr(){ return "Overlay("+ top.toStr()+","+ bot.toStr()+ ")"; } <X> X accept(Vis<X> v){ return v.visit(this); } int size(){ return 1+top.size()+bot.size(); } int circles(){ return top.circles()+bot.circles(); } String toSVG(Ctx ctx){ return top.toSVG(ctx)+bot.toSVG(ctx); } Pict scale(int i){ return new Overlay(top.scale(i),bot.scale(i)); } Pict circ2sqr(){ return new Overlay(top.circ2sqr(),bot.circ2sqr()); } Pict flip(){ return new Overlay(bot.flip(),top.flip()); } Pict compress(){ return new Overlay(bot.compress(),top.compress()); } } class ID extends edu.neu.ccs.demeterf.ID{ int combine(int i){ return i; } String combine(String s){ return s; } } class CircsTU extends StaticTU<Integer>{ public Integer combine(){ return 0; } public Integer fold(Integer a, Integer b){ return a+b; } Integer combine(Circle c){ return 1; } } class ToSVG extends ID{ Ctx update(Offset off, Fields.any f, Ctx c) { return c.move(off); } String combine(Circle c, int r, Ctx ctx) { return SVG.circle(ctx.x, ctx.y, r); } String combine(Square s, int sz, Ctx ctx) { return SVG.square(ctx.x, ctx.y, sz); } String combine(Offset o, int dx, int dy, String shp){ return shp; } String combine(Overlay o, String t, String b){ return t+b; } } class Scale extends StaticTP{ int fact; Scale(int f){ fact = f; } public int combine(int i){ return i*fact; } } class Circ2Sqr extends StaticTP{ public Pict combine(Circle c) { return new Square(c.rad*2); } } class Flip extends StaticTP{ public Overlay combine(Overlay o, Pict t, Pict b) { return new Overlay(b, t); } } class Compress extends StaticTP{ public Offset combine(Offset o, int x, int y, Offset in) { return new Offset(x+in.dx, y+in.dy, in.inner); } } class ToStringVis extends Pict.Vis<String>{ int visit(int i){ return i; } String visit(Circle c){ return "Circle("+c.rad+")"; } String visit(Square s){ return "Square("+s.size+")"; } String visit(Offset o) { return "Overlay("+o.dx+","+o.dy+","+o.inner.accept(this)+")"; } String visit(Overlay o) { return o.top.accept(this)+","+o.bot.accept(this)+")"; } } class CircsVis extends Pict.Vis<Integer>{ int visit(int i){ return 0; } Integer visit(Circle c){ return 1; } Integer visit(Square s){ return 0; } Integer visit(Offset o) { return o.inner.accept(this); } Integer visit(Overlay o) { return o.top.accept(this)+o.bot.accept(this); } } class ToSVGVis extends Pict.Vis<String>{ Ctx ctx; ToSVGVis(Ctx c){ ctx = c; } int visit(int i){ return i; } String visit(Circle c){ return SVG.circle(ctx.x,ctx.y,c.rad); } String visit(Square s){ return SVG.square(ctx.x,ctx.y,s.size); } String visit(Offset o) { return o.inner.accept(new ToSVGVis(ctx.move(o))); } String visit(Overlay o) { return o.top.accept(this)+o.bot.accept(this); } } class ScaleVis extends Pict.Vis<Pict>{ int scale; ScaleVis(int s){ scale = s; } int visit(int i){ return i*scale; } Pict visit(Circle c){ return new Circle(visit(c.rad)); } Pict visit(Square s){ return new Square(visit(s.size)); } Pict visit(Offset o){ return new Offset(visit(o.dx),visit(o.dy),o.inner.accept(this)); } Pict visit(Overlay o){ return new Overlay(o.top.accept(this),o.bot.accept(this)); } } class Circ2SqrVis extends Pict.Vis<Pict>{ Pict visit(Circle c){ return new Circle(visit(c.rad)); } Pict visit(Square s){ return new Square(visit(s.size)); } Pict visit(Offset o){ return new Offset(visit(o.dx),visit(o.dy),o.inner.accept(this)); } Pict visit(Overlay o){ return new Overlay(o.top.accept(this),o.bot.accept(this)); } } class FlipVis extends Pict.Vis<Pict>{ Pict visit(Circle c){ return new Circle(c.rad); } Pict visit(Square s){ return new Square(s.size); } Pict visit(Offset o){ return new Offset(visit(o.dx),visit(o.dy),o.inner.accept(this)); } Pict visit(Overlay o){ return new Overlay(o.top.accept(this),o.bot.accept(this)); } } class ComprVis extends Pict.Vis<Pict>{ Pict visit(Circle c){ return new Circle(c.rad); } Pict visit(Square s){ return new Square(s.size); } Pict visit(Offset o){ final int dx = visit(o.dx), dy = visit(o.dy); final Pict in = o.inner.accept(this); return in.accept(new Pict.Vis<Pict>(){ Pict visit(Circle c){ return new Offset(dx,dy,c); } Pict visit(Square s){ return new Offset(dx,dy,s); } Pict visit(Overlay o){ return new Offset(dx,dy,o); } Pict visit(Offset o){ return new Offset(dx+o.dx,dy+o.dy,o.inner); } }); } Pict visit(Overlay o){ return new Overlay(o.top.accept(this),o.bot.accept(this)); } } class Ctx{ int x, y; Ctx(int xx, int yy){ x = xx; y = yy; } Ctx move(Offset o){ return move(o.dx,o.dy); } Ctx move(int dx, int dy){ return new Ctx(x+dx,y+dy); } } class SVG{ static String head(int w, int h){ return "<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'\n"+ "'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>"+ "<svg xmlns='http://www.w3.org/2000/svg' version='1.1' "+ "width='"+w+"' height='"+h+"'>"+ "<rect x='1' y='1' width='"+(w-2)+"' height='"+(h-2)+"'"+ " fill-opacity='0' stroke='black'"+ "/>\n"; } static String foot(){ return "</svg>\n"; } static String end(String clr){ return " stroke='"+clr+"' stroke-opacity='0.5'"+ " fill='white' fill-opacity='1' />\n"; } static String dcolor = "black"; static String circle(int x, int y, int r){ return circle(x,y,dcolor,r); } static String circle(int x, int y, String clr, int r){ return (" <circle cx='"+x+"' cy='"+y+ "' r='"+r+"'"+end(clr)); } static String square(int x, int y, int s){ return square(x,y,dcolor,s); } static String square(int x, int y, String clr, int s){ return rect(x,y,clr,s,s); } static String rect(int x, int y, int w, int h) { return rect(x,y,dcolor,w,h); } static String rect(int x, int y, String clr, int w, int h){ return (" <rect x='"+(x-w/2)+"' y='"+(y-h/2)+ "' width='"+w+"' height='"+h+"'"+end(clr)); } static String image(int w, int h, String bdy){ return head(w,h)+bdy+foot(); } }