0

正如标题所说,如果我缩放形状,为什么它不起作用shape.scale(0.5)

shape(0,0,200,200)即使我的意思是我绘制的形状不是原始尺寸,它也不起作用。这是一个错误还是我错过了什么?

4

1 回答 1

0

这是一个错误,虽然我不确定有多严重。正如您从测试中发现的那样,contains()当使用转换(平移/旋转/缩放)时,该方法不起作用。

我有两个有点 hacky 的解决方法:

  1. 存储一个单独的顶点数组,手动添加(偏移/平移)和乘法(缩放)位置值,然后测试该点是否位于多边形内
  2. 使用转换矩阵,从屏幕(典型处理)坐标转换为转换后的 SVG 坐标是相反的。

第一个解决方案听起来有点工作和毫无意义的数据重复,更不用说在处理旋转时很烦人,而且对于“堆叠”/复杂的转换也容易出错。

第二种解决方法看起来有点笨拙,因为 contains() 应该刚刚工作,但它使用了处理类,所以它还不错。它是这样工作的:

  1. 创建一个转换矩阵,将所需的转换应用于形状(例如 translate()、rotate()、scale())并存储它
  2. 将此变换应用于形状
  3. 存储此转换矩阵的逆矩阵以将屏幕坐标转换为 svg 坐标(带有转换),这样 contains() 将起作用。

svg 来自Examples > Basic > Shape > GetChild。如果要按原样测试代码,可以打开草图文件夹(Ctrl + K / CMD + K )以获取“usa-wikipedia.svg”:

import processing.opengl.*;

PShape ohio;
PMatrix2D coordSysSvgInv;//svg coordinate system inversed

void setup() {
  size(1200, 480,OPENGL);//the catch is, even though we use PMatrix2D, PShape's applyMatrix() only seems to work with the P3D or OpenGL renderer
  PShape usa = loadShape("usa-wikipedia.svg");
  ohio = (PShape)usa.getChild("OH");

  PMatrix2D transform = new PMatrix2D();    //apply transforms(position,rotation,scale) to this matrix
  transform.scale(2);                       //be aware that the order of operation matters!
  transform.translate(-800,-300);           //this matrix can be used to convert from screen coordinats to SVG coordinates
  coordSysSvgInv = transform.get(); //clone the svg to screen transformation matrix
  coordSysSvgInv.invert();          //simply invert it to get the screen to svg

  ohio.applyMatrix(transform);              //apply this transformation matrix to the SVG
}

void draw() {
  //update
  PVector mouseInSVG = screenToSVG(mouseX,mouseY);
  boolean isOver = ohio.contains(mouseInSVG.x,mouseInSVG.y);
  //draw
  background(255);
  ohio.disableStyle();
  fill(isOver ? color(0,192,0) : color(255,127,0));
  shape(ohio);
}
PVector screenToSVG(float x,float y){
  PVector result = new PVector();//create a new PVector to store transformed vector
  coordSysSvgInv.mult(new PVector(x,y),result);//transform PVector by multiplying it to the inverse svg coord. sys.
  return result;
}

我注意到applyMatrix()方法仅适用于P3DOPENGL渲染器,即使我正在传递 PMatrix2D实例,否则会出现此警告:

applyMatrix() with x, y, and z coordinates can only be used with a renderer that supports 3D, such as P3D or OPENGL. Use a version without a z-coordinate instead.

'cleaner' 选项是修改PShape 类中的contains()方法,然后重新编译 Processing 的 core.jar 并使用更新后的 jar。如果这是一个一次性的小项目,我不知道它是否值得麻烦,从上面获得稍微混乱的代码可能比重新编译/更新 core.jar 更快。

于 2012-09-10T11:21:22.840 回答