Redrawing Pimage with point() after rotate() creates weird pixel patterns

I try to mirror a PImage, using parts of the code found here: https://thecodingtrain.com/CodingChallenges/155-kaleidoscope-snowflake.html
The difference is, that i use point() to draw the single pixels of the picture. It seems that this creates weird patterns of black or white pixels in the resulting picture if i use the stroke weight 1. If i increase it to 4, these patterns go away, but the quality of the picture is not that sharp anymore…
Does anyone have a workaround for this problem? Seems like the pixels that the programm wants to draw are not exactly at the place the real pixels are. I think thats where these patterns come from.

maybe show some of your secret code ?

1 Like

I think this should be the essential part.
Only thing missing is the Mov class but all it does, is to move positions of b.pos.x and b.pos.y .

int angle = 360 / symmetry;
float strokeSize = 1;
PImage Mirrorme;
float xoff=0;
int picnr= 1090761;
float yoff=13;
Mov b;

void setup() {
size(600, 600);
strokeWeight(2);
b= new Mov();
}
void draw(){
Mirrorme = loadImage(“P”+picnr+".JPG");
Mirrorme.resize(550,550);
Mirrorme.loadPixels();
picnr+=1;
saveFrame(“Export-######.png”);
background(0,87);
b.updateposnvel();
b.changeacc();
traw();
xoff+=0.31;
yoff+=0.21;
}

void traw()
{
translate(width / 2, height / 2);
for(int xi=0;xi<340;xi++){
for(int yi=0;yi<540;yi++){
framecolor=Mirrorme.get(xi+int(b.pos.x)+200,yi+int(b.pos.y)+200);

for (int i = 0; i < symmetry; i++) {
rotate(radians(angle));
pushMatrix();
if(i%2==1){
scale(-1, 1);}
stroke(framecolor,180);
point(mx, my);
popMatrix();

}
}
}

}

Shouldn’t this be after pushMatrix() ?

I could put it after pushMatrix() and multiply angle with i, but i don´t see any difference.

hahaha, traw() that’s a funny name :slight_smile:
to be totally honest, I am scared of pushing pixels on a pixel per pixel basis as I always think it will take.a lot of cpu time…

since - afaik - image copying is limited to rectangular shapes, I would probably use a PShape with a texture.

(that’s what I used in my last project -> if you look closely the trees have a bark that slowly moves. each branch is a shape, that uses one picture. works fine with 100+ shapes performance wise, and since these shapes are calculated with absolute positions, I don’t need to transform the position of the textures. - Treeversity - Big Data Visualization )

If you use a single image create one (probably triangular) shape with texture, and if I am not mistaken using translate rotate should maintain the texture in place. in fact I think you need just a single shape, unless you want to mix different parts of the picture (or different pics) as you do in your image…

so, roughly:

  1. loadImage
  2. createShape
  3. beginShape() - texture(img) - vertex, vertex, vertex - endShape
  4. translate(width/2, height/2) - shape - rotate - shape - rotate

as an aside, if you do not have hundreds of pics, id preload all images into an array rather than loading a new one in every frame
or use a movie texture (or 2,3,4,…)
in my experience the frame rate drops significantly when a movie is scaled to fit something (significantly) so Id recommend scaling the movie files itself as soon as you know the required size. but then… scaling the movies while running your kaleidoscope might add another, interesting visual layer…

here is a simple example with one image only.

Of course, you could

  • just display the image (with image()),
  • here it is displayed with get() and point()

int symmetry = 12; 

//step
int angle = 360 / symmetry;

float strokeSize = 1;
PImage Mirrorme;
float xoff=0;
int picnr= 1090761;
float yoff=13;
//Mov b;

// --------------------------------------------------------------------------------------------

void setup() {
  size(1600, 900);
  strokeWeight(2);
  // b = new Mov();

  Mirrorme = loadImage("P"+"1"+".jpg");
  Mirrorme.resize(250, 250);
  Mirrorme.loadPixels();
}

void draw() {

  background(0, 87);

  traw();

  noLoop();
}

// --------------------------------------------------------------------------------------------

void traw() {


  for (int i = 0; i < symmetry; i++) {

    pushMatrix();
    translate(width / 2, height / 2);
    rotate(radians(angle*i));
    translate(Mirrorme.width / 4, Mirrorme.height / 4);

    for (int xi=0; xi<Mirrorme.width; xi++) {
      for (int yi=0; yi<Mirrorme.height; yi++) {

        color framecolor=color(189);

        //      framecolor=Mirrorme.get(xi+int(b.pos.x)+200, yi+int(b.pos.y)+200);
        framecolor=Mirrorme.get(xi, yi );



        if (i%2==1) {
          scale(-1, 1);
        }
        stroke(framecolor, 180);
        //        point(mx, my);
        point(xi, yi);
      }
    }
    popMatrix();
  }//outer for / #1
  //
}//func 
//