9-Point mesh warping

I’m trying to figure out how to go about warping a mesh using 9 handles (marked in red). I can already deform the mesh by moving the corners but it’s the intermediary handles I’m really struggling with. I need this to work with a mesh of basically any number of vertices, although it’s always an odd number of rows and cols (to ensure proper middle points) and the number of rows and cols are always the same. Ideally, if you pulled the top-middle handle down, the top row of verts would form a U-shape, not a V-shape.

Capture

I’ve experimented with defining the edges of the quad as bezier curves and interpolating between them all towards the middle, but that seems like the most overkill solution to this problem (and it didn’t really work all that well anyway)

Thanks!

@jakedubber I implemented this for the GL Video library, the code for which should be easily reusable:

There is actually two implementation - the VideoMapping example is using WarpPerspective and PerspectiveTransform classes, which don’t have any external dependencies.

And we also got a different implementation donated, which soley uses shaders to accomplish the same: VideoMappingWithShader.

Hth

Gohai, cheers for the reply :slight_smile: From what I can see, those examples only let you drag the four corners around. I’ve already achieved this in my sketch - I’m looking to be able to drag nine fixed points around to deform the mesh.

Perhaps I missed something? :confused:

Please show your code.

Kf

int i = 0;
for (int x = 0; x<subd; x++)
{
  for (int y = 0; y<subd; y++)
  {
    // get normalised vector
    PVector p = new PVector(normPos(x), normPos(y));

    // interpolate top edge x coordinate
    PVector x1 = PVector.lerp(handles.get(0).pos, handles.get(2).pos, p.x);

    // interpolate bottom edge x coordinate
    PVector x2 = PVector.lerp(handles.get(1).pos, handles.get(3).pos, p.x);

    // interpolate y position
    p = PVector.lerp(x1, x2, p.y);

    //Apply the transformation
    verts.get(i).x = p.x;
    verts.get(i).y = p.y;

    i++;
  }
}

PVector normPos(PVector i)
{
  float x = map(i.x, 0, quad.subd-1, 0, 1);
  float y = map(i.y, 0, quad.subd-1, 0, 1);
  PVector p = new PVector(x, y);
  return p;
}

That’s the bulk of what’s handling the mesh deforming. It takes the positions of four handles (0 - TL, 1 - BL, 2 - TR, 3 - BR) and fills an ArrayList of PVectors. Obviously, this doesn’t include drawing the mesh nor does it have any logic for dragging corners around with the mouse, that’s all implemented elsewhere in the code and not something I have an issue with.

I didn’t end up figuring out exactly what I was looking for, but I did find this which was incredibly useful: https://www.openprocessing.org/sketch/65475

1 Like