Processing 如何在处理过程中手动将矩阵堆栈应用于坐标

Processing 如何在处理过程中手动将矩阵堆栈应用于坐标,processing,Processing,在处理过程中,当应用矩阵变换时,可以在画布上绘制,而不必担心x y坐标的“真实”位置 我认为,按照同样的逻辑,我可以使用ParentApplet.get(x,y,width,height)复制画布的一部分,它会自动移动x和y,但它不会,它使用坐标作为原始输入,而不应用矩阵堆栈 因此,我认为处理这个问题的最简单方法是手动将矩阵堆栈应用于我的x、y、width、height值,并将结果用作get()的输入。但是我找不到这样一个函数,它存在吗 编辑:根据要求,以下是我的问题示例 所以这里的目标是画一个

在处理过程中,当应用矩阵变换时,可以在画布上绘制,而不必担心x y坐标的“真实”位置

我认为,按照同样的逻辑,我可以使用ParentApplet.get(x,y,width,height)复制画布的一部分,它会自动移动x和y,但它不会,它使用坐标作为原始输入,而不应用矩阵堆栈

因此,我认为处理这个问题的最简单方法是手动将矩阵堆栈应用于我的x、y、width、height值,并将结果用作get()的输入。但是我找不到这样一个函数,它存在吗

编辑:根据要求,以下是我的问题示例

所以这里的目标是画一个简单的形状,复制并粘贴它。没有翻译,就没有问题:

void settings(){
    size(500, 500);
}

void draw() {
  background(255);
  
  // Fancy rectangle for visibility
  fill(255, 0 ,0);
  rect(0, 0, 100, 100);
  fill(0, 255, 0);
  rect(20, 20, 60, 60);
  
  // copy rectangle and paste it elsewhere
  PImage img = get(0, 0, 101, 101);
  image(img, 200, 200);
}

现在,如果我在绘制形状之前应用了平移矩阵,我希望可以使用相同的get()代码复制完全相同的图形:

void settings(){
    size(500, 500);
}

void draw() {
  background(255);
  pushMatrix();
  translate(10, 10);
  
  // Fancy rectangle for visibility
  fill(255, 0 ,0);
  rect(0, 0, 100, 100);
  fill(0, 255, 0);
  rect(20, 20, 60, 60);
  
  // copy rectangle and paste it elsewhere
  PImage img = get(0, 0, 101, 101);
  image(img, 200, 200);
  
  popMatrix();
}
但它不是这样工作的,get(0,0,…)不使用当前变换矩阵从原点(10,10)复制像素:


你能提供更多的细节吗。 可以使用操作坐标系,您还可以进一步手动乘法矩阵和向量

令人困惑的是,您正在调用
get(x,y,width,height)
,但没有显示如何渲染
PImage
部分。很难猜出你提到的矩阵堆栈。你能发布一个示例片段吗

如果以相同的x,y进行渲染,则调用
get()
时,应以相同的x,y偏移进行渲染:

size(640, 360);
noFill();
strokeWeight(9);

PImage placeholderForPGraphics = loadImage("https://processing.org/examples/moonwalk.jpg");
image(placeholderForPGraphics, 0, 0);

int x = 420;
int y = 120;
int w = 32;
int h = 48;
// visualise region of interest
rect(x, y, w, h);

// grab the section sub PImage
PImage section = placeholderForPGraphics.get(x, y, w, h);

//filter the section to make it really standout
section.filter(THRESHOLD);
// display section at same location
image(section, x, y);

关于矩阵堆栈,您可以调用它,如果您处于2D模式,它将返回a(否则为a)。这是当前矩阵堆栈在您所调用状态下的副本(之前的任何操作都将“烘焙”到此操作中)

例如:

PMatrix m = g.getMatrix();
printArray(m.get(new float[]{}));
g.printMatrix()
应该更容易打印到控制台,但如果需要操作实例,则需要调用
getMatrix()

其中
g
是您的PGraphics实例

然后,您可以根据自己的喜好对其进行操作:

m.translate(10, 20);
m.rotate(radians(30));
m.scale(1.5);
完成后,请记住调用
applyMatrix()
it:

g.applyMatrix(m);
尽管可能很琐碎,但我希望上述示例的修改版本能够说明这一想法:

size(640, 360);
noFill();
strokeWeight(9);
// get the current transformation matrix
PMatrix m = g.getMatrix();
// print to console
println("before");
g.printMatrix();
// modify it
m.translate(160, 90);
m.scale(0.5);
// apply it
g.applyMatrix(m);
// print applied matrix
println("after");
g.printMatrix();


PImage placeholderForPGraphics = loadImage("https://processing.org/examples/moonwalk.jpg");
image(placeholderForPGraphics, 0, 0);

int x = 420;
int y = 120;
int w = 32;
int h = 48;
// visualise region of interest
rect(x, y, w, h);

// grab the section sub PImage
PImage section = placeholderForPGraphics.get(x, y, w, h);

//filter the section to make it really standout
section.filter(THRESHOLD);
// display section at same location
image(section, x, y);
下面是另一个使用矩阵变换将basic转换为
PGraphics
的示例:

void setup(){
  size(360, 360);
  
  // draw something manipulating the coordinate system
  PGraphics pg = createGraphics(360, 360);
  pg.beginDraw();
  pg.background(0);
  pg.noFill();
  pg.stroke(255, 128);
  pg.strokeWeight(4.5);
  pg.rectMode(CENTER);
  pg.translate(180,180);
  for(int i = 0 ; i < 72; i++){
    pg.rotate(radians(5));
    pg.scale(0.95);
    //pg.rect(0, 0, 320, 320, 32, 32, 32, 32);
    polygon(6, 180, pg);
  }
  pg.endDraw();
  
  // render PGraphics
  image(pg, 0, 0);
  
  }

下面是在孤立坐标空间中重新应用最后一个变换矩阵的最后一次迭代(使用push/pop矩阵调用):

更新 以下是关于如何计算而不是硬编码转换值的更多示例:

void settings(){
    size(500, 500);
}

void setup() {
  background(255);
  pushMatrix();
  translate(10, 10);
  // Fancy rectangle for visibility
  fill(255, 0 ,0);
  rect(0, 0, 100, 100);
  fill(0, 255, 0);
  rect(20, 20, 60, 60);
  // local to global coordinate conversion using PMatrix
  // g is the global PGraphics instance every PApplet (sketch) uses
  PMatrix m = g.getMatrix();
  printArray(m.get(null));
  // the point in local coordinate system
  PVector local = new PVector(0,0);
  // multiply local point by transformation matrix to get global point
  // we pass in null to get a new PVector instance: you can make this more efficient by allocating a single PVector ad re-using it instead of this basic demo
  PVector global = m.mult(local,null);
  // copy rectangle and paste it elsewhere
  println("local",local,"->global",global);
  PImage img = get((int)global.x, (int)global.y, 101, 101);
  image(img, 200, 200);
  
  popMatrix();
}
要根据变换矩阵计算向量的位置,只需将向量乘以该矩阵即可。非常粗略地说,push/pop矩阵会发生什么(每个push/pop堆栈都使用一个变换矩阵,然后在全局坐标系上相乘)。(注意关于效率/预分配矩阵和向量的评论)

这将在代码方面更加冗长,如果您使用大量嵌套转换,可能需要进行一些规划,但是您可以更好地控制选择使用哪些转换

一个更简单的解决方案可能是切换到允许您使用的
P3D
OpenGL渲染器来进行此转换。(同时签出
modelX()
/
modelY()


请记住,您想要获取一个仅应用了平移的矩形。由于
get()
不会考虑旋转/缩放,因此对于更复杂的情况,您可能需要将局部坐标转换为全局坐标,不仅是左上角的点,而且是右下角的点,并带有偏移。我们的想法是计算转换框周围的较大边界框(不旋转),这样当您调用
get()
时,将返回整个感兴趣的区域(而不仅仅是剪裁的部分)。

您可以提供更多细节吗。 可以使用操作坐标系,您还可以进一步手动乘法矩阵和向量

令人困惑的是,您正在调用
get(x,y,width,height)
,但没有显示如何渲染
PImage
部分。很难猜出你提到的矩阵堆栈。你能发布一个示例片段吗

如果以相同的x,y进行渲染,则调用
get()
时,应以相同的x,y偏移进行渲染:

size(640, 360);
noFill();
strokeWeight(9);

PImage placeholderForPGraphics = loadImage("https://processing.org/examples/moonwalk.jpg");
image(placeholderForPGraphics, 0, 0);

int x = 420;
int y = 120;
int w = 32;
int h = 48;
// visualise region of interest
rect(x, y, w, h);

// grab the section sub PImage
PImage section = placeholderForPGraphics.get(x, y, w, h);

//filter the section to make it really standout
section.filter(THRESHOLD);
// display section at same location
image(section, x, y);

关于矩阵堆栈,您可以调用它,如果您处于2D模式,它将返回a(否则为a)。这是当前矩阵堆栈在您所调用状态下的副本(之前的任何操作都将“烘焙”到此操作中)

例如:

PMatrix m = g.getMatrix();
printArray(m.get(new float[]{}));
g.printMatrix()
应该更容易打印到控制台,但如果需要操作实例,则需要调用
getMatrix()

其中
g
是您的PGraphics实例

然后,您可以根据自己的喜好对其进行操作:

m.translate(10, 20);
m.rotate(radians(30));
m.scale(1.5);
完成后,请记住调用
applyMatrix()
it:

g.applyMatrix(m);
尽管可能很琐碎,但我希望上述示例的修改版本能够说明这一想法:

size(640, 360);
noFill();
strokeWeight(9);
// get the current transformation matrix
PMatrix m = g.getMatrix();
// print to console
println("before");
g.printMatrix();
// modify it
m.translate(160, 90);
m.scale(0.5);
// apply it
g.applyMatrix(m);
// print applied matrix
println("after");
g.printMatrix();


PImage placeholderForPGraphics = loadImage("https://processing.org/examples/moonwalk.jpg");
image(placeholderForPGraphics, 0, 0);

int x = 420;
int y = 120;
int w = 32;
int h = 48;
// visualise region of interest
rect(x, y, w, h);

// grab the section sub PImage
PImage section = placeholderForPGraphics.get(x, y, w, h);

//filter the section to make it really standout
section.filter(THRESHOLD);
// display section at same location
image(section, x, y);
下面是另一个使用矩阵变换将basic转换为
PGraphics
的示例:

void setup(){
  size(360, 360);
  
  // draw something manipulating the coordinate system
  PGraphics pg = createGraphics(360, 360);
  pg.beginDraw();
  pg.background(0);
  pg.noFill();
  pg.stroke(255, 128);
  pg.strokeWeight(4.5);
  pg.rectMode(CENTER);
  pg.translate(180,180);
  for(int i = 0 ; i < 72; i++){
    pg.rotate(radians(5));
    pg.scale(0.95);
    //pg.rect(0, 0, 320, 320, 32, 32, 32, 32);
    polygon(6, 180, pg);
  }
  pg.endDraw();
  
  // render PGraphics
  image(pg, 0, 0);
  
  }

下面是在孤立坐标空间中重新应用最后一个变换矩阵的最后一次迭代(使用push/pop矩阵调用):

更新 以下是关于如何计算而不是硬编码转换值的更多示例:

void settings(){
    size(500, 500);
}

void setup() {
  background(255);
  pushMatrix();
  translate(10, 10);
  // Fancy rectangle for visibility
  fill(255, 0 ,0);
  rect(0, 0, 100, 100);
  fill(0, 255, 0);
  rect(20, 20, 60, 60);
  // local to global coordinate conversion using PMatrix
  // g is the global PGraphics instance every PApplet (sketch) uses
  PMatrix m = g.getMatrix();
  printArray(m.get(null));
  // the point in local coordinate system
  PVector local = new PVector(0,0);
  // multiply local point by transformation matrix to get global point
  // we pass in null to get a new PVector instance: you can make this more efficient by allocating a single PVector ad re-using it instead of this basic demo
  PVector global = m.mult(local,null);
  // copy rectangle and paste it elsewhere
  println("local",local,"->global",global);
  PImage img = get((int)global.x, (int)global.y, 101, 101);
  image(img, 200, 200);
  
  popMatrix();
}
要根据变换矩阵计算向量的位置,只需将向量乘以该矩阵即可。非常粗略地说,push/pop矩阵会发生什么(每个push/pop堆栈使用一个转换矩阵,然后在glo上相乘)