Loading...
Logo
Processing Forum
I have a polygon which I am duplicating x number of times according to arbitrary rule. Ideally, I would just like to have an ArrayList with each element being a function pointer to the transform I want to apply. Unfortunately, from what I can tell trying and failing to figure it on my own, java's implementation is not that straight forward. I gather I need to use anonymous classes but I'm not sure how to get it to work.

Here's some pseudo code:

void setup() {
  size(400,400);
 
  // define a polygon
  PVector[] verts = { new PVector(0,0),new PVector(50,0),new PVector(25,50)};
 
  // I have my transforms as strings, but ideally, they would be function definitions
  ArrayList xform = new ArrayList();
  xform.add("translate(50,50)");
  xform.add("combo(-100,0,PI*.333)");
  xform.add("scale(2,1)");
 
  // draw my original triagle
  drawIt(verts);

  //apply the first transform and draw
  xform.get(0); // this would apply the transform
  drawIt(verts);

  //apply the second transform and draw
  xform.get(1);
  drawIt(verts);

  //apply the third transform and draw
  xform.get(2);
  drawIt(verts);
}

void drawIt(PVector[] prim) {
  beginShape();
  vertex(prim[0].x,prim[0].y);
  vertex(prim[1].x,prim[1].y);
  vertex(prim[2].x,prim[2].y);
  endShape(CLOSE);
  resetMatrix();
}

void combo(float x, float y, float rot){
  translate(x,y);
  rotate(rot);
}

Replies(3)

interfaces.

define an interface. then define all your transformations as classes which implement this interface.

ok, some code. probably not 100 percent best practice but it seemed to work

transforms is my list of transformations
Transform1, Transform2 etc are the classes that define these. all implement Polygon transform(Polygon), a method that takes a polygon, does something to it, and returns the modified version (they don't do much except set the value within the Polygon in this example)
Copy code
  1. ArrayList transforms = new ArrayList();
  2. Polygon p;  // the data

  3. void setup() {
  4.   // add three transformations
  5.   transforms.add(new Transform1());
  6.   transforms.add(new Transform2());
  7.   transforms.add(new Transform3());
  8.  
  9.   p = new Polygon();
  10.  
  11.   // apply any of the transforms to the polygon
  12.   // you need to cast this as transforms doesn't know what it contains
  13.   p = ((Transform)(transforms.get(1))).transform(p);
  14.   println("P: " + p.v);
  15. }

  16. void draw() {
  17. }
Copy code
  1. // all the transforms must define this method
  2. interface Transform {
  3.   Polygon transform(Polygon p);
  4. }

  5. class Transform1 implements Transform {
  6.   Polygon transform(Polygon p) {
  7.     p.v = 1;
  8.     println("transform1");
  9.     return p;
  10.   }
  11. }

  12. class Transform2 implements Transform {
  13.   Polygon transform(Polygon p) {
  14.     p.v = 2;
  15.     println("transform2");
  16.     return p;
  17.   }
  18. }

  19. class Transform3 implements Transform {
  20.   Polygon transform(Polygon p) {
  21.     p.v = 3;
  22.     println("transform3");
  23.     return p;
  24.   }
  25. }

  26. // polygon class
  27. class Polygon {
  28.   int v;
  29.   Polygon() {
  30.     v = 0;
  31.   }
  32. }
(edit: actually, there's no need to return the object you pass in, all those methods could be void Transform(Polygon). makes the code shorter, more like yours)
Thanks a lot for this. It's just what I need... For future reference, I tested it with a regular array and it works just fine, too. Now, just curious to know if there are any ways to define the Transform1,2 and 3 classes inline.

Copy code
  1. Transform[] transforms;
  2. Polygon p;  // the data

  3. void setup() {
  4.   // add three transformations
  5.   transforms = new Transform[]{new Transform1(),new Transform2(),new Transform3()};

  6.   p = new Polygon();

  7.   // apply any of the transforms to the polygon
  8.   p = transforms[1].transform(p);
  9.   println("P: " + p.v);
  10. }

probably possible to use anonymous classes. but i think it just looks like a mess

http://docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm
String[] filelist = f.list(new FilenameFilter() {
  public boolean accept(File f, String s) { return s.endsWith(".java"); }
});
ick! those transforms are going to be more complex anyway, will need a constructor that takes the variables, the translate(50,50) in your original example, say. probably worth having them as real, separate classes.