# Pixel flow teleporting test object

**URL:** <https://discourse.processing.org/t/pixel-flow-teleporting-test-object/18395>\
**Category:** Libraries\
**Created:** [March 5, 2020, 12:07am UTC](https://discourse.processing.org/t/pixel-flow-teleporting-test-object/18395 "2020-03-05T00:07:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![BongoTurtle](https://avatars.discourse-cdn.com/v4/letter/b/df788c/32.png) [@BongoTurtle](https://discourse.processing.org/u/BongoTurtle)\
**Post date:** [March 5, 2020, 12:07am UTC](https://discourse.processing.org/t/pixel-flow-teleporting-test-object/18395/1 "2020-03-05T00:07:11Z")

</div>

Can someone tell me why sometimes it looks like the circle will teleport?

```auto
import com.thomasdiewald.pixelflow.java.DwPixelFlow;
import com.thomasdiewald.pixelflow.java.dwgl.DwGLTexture;
import com.thomasdiewald.pixelflow.java.fluid.DwFluid2D;
import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;
import processing.core.*;
import processing.opengl.PGraphics2D;
 
DwPixelFlow context;  
DwFluid2D fluid;  
PGraphics2D pg_fluid;
  
PVector pos = new PVector(300,300);  
  
  void setup() {
    size(600, 600, P2D);
       
    context = new DwPixelFlow(this);
    
    fluid = new DwFluid2D(context, width, height, 1);
    
    fluid.param.dissipation_velocity = .5f;
    fluid.param.dissipation_density = 1f;

    fluid.addCallback_FluiData(new DwFluid2D.FluidData(){
      public void update(DwFluid2D fluid) {
        if(mousePressed){
          float px = mouseX;
          float py = height-mouseY;
          float vx = (mouseX - pmouseX) * +15;
          float vy = (mouseY - pmouseY) * -15;
          fluid.addVelocity(px, py, 14, vx, vy);
          fluid.addDensity (px, py, 20, 0.0f, 0.4f, 1.0f, 1.0f);
          fluid.addDensity (px, py, 8, 1.0f, 1.0f, 1.0f, 1.0f);
        }       
      }
    });

    pg_fluid = (PGraphics2D) createGraphics(width, height, P2D);

  }
  
  
  DwGLTexture tex_vel_small;
  float[] data_vel;

  void draw() {    
    fluid.update();
        
    if(tex_vel_small == null){
      tex_vel_small = fluid.tex_velocity.src.createEmtpyCopy();
      tex_vel_small.resize(context, width, height);
    }
    
    DwFilter.get(context).copy.apply(fluid.tex_velocity.src, tex_vel_small);
    
    context.begin();
    data_vel = tex_vel_small.getFloatTextureData(data_vel);
    context.end();
    
    for(int gy = 0; gy < height; gy++){
      for(int gx = 0; gx < width; gx++){       

        int gid_fluid = (height - 1 - gy) * tex_vel_small.w + gx;
        float vel_x = data_vel[gid_fluid * 2 + 0];
        float vel_y = data_vel[gid_fluid * 2 + 1];
        if(gy == round(pos.y) && gx == round(pos.x)){
         pos.x += vel_x;
         pos.y += -vel_y;
        }
      }
    }
    
    pg_fluid.beginDraw();
    pg_fluid.background(0);
    pg_fluid.endDraw();
    fluid.renderFluidTextures(pg_fluid, 0);

    image(pg_fluid, 0, 0);
    ellipse(pos.x,pos.y,10,10);
  }
  

```

---

<div class="post-metadata">

**Author:** ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)\
**Post date:** [March 5, 2020, 4:45am UTC](https://discourse.processing.org/t/pixel-flow-teleporting-test-object/18395/2 "2020-03-05T04:45:49Z")

</div>

Don’t know what you mean by teleporting, but I like the sketch’s result.😉

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [March 7, 2020, 8:02pm UTC](https://discourse.processing.org/t/pixel-flow-teleporting-test-object/18395/3 "2020-03-07T20:02:00Z")

</div>

Your problem occurs where you update `pos`. Try adding `println` logging to see the actual values that you are adding to `pos`.

```auto
  for (int gy = 0; gy < height; gy++) {
    for (int gx = 0; gx < width; gx++) {       
      int gid_fluid = (height - 1 - gy) * tex_vel_small.w + gx;
      float vel_x = data_vel[gid_fluid * 2 + 0];
      float vel_y = data_vel[gid_fluid * 2 + 1];
      if (gy == round(pos.y) && gx == round(pos.x)) {
        pos.x += vel_x;
        pos.y += -vel_y;
        if (abs(vel_x) > 1 || abs(vel_y) > 1) {
          println(frameCount, vel_x, -vel_y);
        }
      }
    }
  }

```

From you code it looks like you think that this if statement will a) only match once, and b) be a relatively small value. As you can see, this isn’t what is happening, On frame 32 `pos` is updated 7 times – and some of those updates individually are 14 pixels, so it jumps over 30 pixels.

> 27 -1.2929688 0.16247559  
> 28 -1.3359375 0.091796875  
> 29 -1.15625 5.493164E-4  
> 32 -0.28125 1.3925781  
> 32 -0.22729492 2.1660156  
> 32 -0.1977539 3.2734375  
> 32 -0.6201172 5.4375  
> 32 -2.9589844 10.3515625  
> 32 -14.828125 14.2734375  
> 32 -12.5 -2.0800781  
> 33 -10.4140625 14.65625

A key issue here is that you are checking `pos` in loop while you are changing it. So you can check a pixel, then bump pos to another pixel, then check that pixel, then bump pos to another pixel, then check that pixel, then bump pos to another pixel, then check that pixel…

Here is one way around that –

```auto
  PVector newpos = pos.copy();
  for (int gy = 0; gy < height; gy++) {
    for (int gx = 0; gx < width; gx++) {       
      if (gy == round(pos.y) && gx == round(pos.x)) {
        int gid_fluid = (height - 1 - gy) * tex_vel_small.w + gx;
        float vel_x = data_vel[gid_fluid * 2 + 0];
        float vel_y = data_vel[gid_fluid * 2 + 1];
        newpos.x += vel_x;
        newpos.y += -vel_y;
        if (abs(vel_x) > 1 || abs(vel_y) > 1) {
          println(frameCount, vel_x, -vel_y);
        }
      }
    }
  }
  pos = newpos;

```

another way if you only want to check one pixel is don’t loop at all – just look up the pixel that you want with no loops:

```auto
  int gx = round(pos.x));
  int gy = round(pos.y);
  int gid_fluid = (height - 1 - gy) * tex_vel_small.w + gx;
  float vel_x = data_vel[gid_fluid * 2 + 0];
  float vel_y = data_vel[gid_fluid * 2 + 1];
  pos.x += vel_x;
  pos.y += -vel_y;
  if (abs(vel_x) > 1 || abs(vel_y) > 1) {
    println(frameCount, vel_x, -vel_y);
  }

```

Now that you aren’t multi-updating, if you still don’t like how jumpy things are consider either altering the total velocity energy of your fluid – or setting a hard limit on how far the ellipse can move in a frame. For example:

```auto
vel_x = constrain(vel_x, -vel_max, vel_max);
vel_y = constrain(vel_y, -vel_max, vel_max);

```

Yet another option is to use easing with `PVector.lerp()`.
