Map texture onto PATH shape

Hi @Frinkel ,

Please link to the previous thread for context (and the image file).

It depends on which graphics renderer you’re committing to. If you use the default JAVA2D you can use underlying AWT classes and methods to accomplish what you’ve described, both for contains and the mask.

cap

import processing.awt.PGraphicsJava2D;
import java.awt.geom.Path2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.Point;

PGraphicsJava2D graphics;
Image img;
Path2D.Float path = new Path2D.Float();

void settings() {
  size(400, 400, JAVA2D);
}

void setup() {
  graphics = (PGraphicsJava2D)getGraphics();

  float whalf = graphics.width / 2;
  float hhalf = graphics.height / 2;
  float s = 175.0f;
  float t = s * 0.552125f;

  path.moveTo(whalf + s, hhalf);
  path.curveTo(whalf + s, hhalf + t, whalf + t, hhalf + s, whalf, hhalf + s);
  path.curveTo(whalf - t, hhalf + s, whalf - s, hhalf + t, whalf - s, hhalf);
  path.curveTo(whalf - s, hhalf - t, whalf - t, hhalf - s, whalf, hhalf - s);
  path.curveTo(whalf + t, hhalf - s, whalf + s, hhalf - t, whalf + s, hhalf);
  path.closePath();

  // In case file test.jpeg is misplaced.
  //PImage pimg = createImage(512, 512, ARGB);
  //checker(0xff7f00ff, 0xff007fff, 8, 8, pimg);
  
  PImage pimg = loadImage("test.jpeg");
  pimg.resize(pimg.width/2, pimg.height/2);
  img = convertPImageToNative(pimg);
}

void draw() {
  blendMode(BLEND);
  background(0xff202020);
  graphics.g2.setClip(path);
  graphics.g2.drawImage(img, 0, 0, null);
  graphics.g2.setClip(null);

  Point point = new Point(mouseX, mouseY);
  boolean inside = path.contains(point);
  if (inside) {
    stroke(0xffffff00);
    strokeWeight(20);
    point(mouseX, mouseY);
  }
}

public static Image convertPImageToNative(PImage pimg) {

  int pw = pimg.pixelWidth;
  int ph = pimg.pixelHeight;
  pimg.loadPixels();
  BufferedImage imgNtv = new BufferedImage(pw, ph, pimg.format
    == PConstants.RGB ? BufferedImage.TYPE_INT_RGB
    : BufferedImage.TYPE_INT_ARGB);
  imgNtv.getRaster().setDataElements(0, 0, pw, ph, pimg.pixels);
  return imgNtv;
}

public static PImage checker(int a, int b, int cols,
  int rows, PImage target ) {

  target.loadPixels();

  int w = target.pixelWidth;
  int h = target.pixelHeight;
  int pd = target.pixelDensity;

  int limit = 2 * pd;
  int vcols = cols < 2 ? 2 : cols > w / limit ? w / limit : cols;
  int vrows = rows < 2 ? 2 : rows > h / limit ? h / limit : rows;

  int[] px = target.pixels;
  int len = px.length;

  int wch = w / vcols;
  int hchw = w * h / vrows;

  for ( int i = 0; i < len; ++i ) {
    px[i] = ( i % w / wch + i / hchw ) % 2 == 0 ? a : b;
  }

  target.format = PConstants.ARGB;
  target.updatePixels();
  return target;
}

For P2D, you could try reverse engineering the contains method

and then write a fragment shader to get a mask.

Best,
Jeremy

1 Like