PShapeSVG contains() 函数在应用 scale() 时不起作用 [英] PShapeSVG contains() function doesn't work when scale() is applied

查看:50
本文介绍了PShapeSVG contains() 函数在应用 scale() 时不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As the title said, why doesn't it work if I scale the shape doing shape.scale(0.5)?

即使我做了 shape(0,0,200,200) 这意味着我绘制的形状不是原始尺寸,它也不起作用.这是错误还是我遗漏了什么?

It doesn't work even if I do shape(0,0,200,200) meaning I draw the shape not in the original dimensions. Is this a bug or I'm missing something?

推荐答案

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

It kind of is a bug, although I'm not sure how severe. As you found out from your test the contains() method doesn't work when transformations(translation/rotation/scale) are used.

我有两个有点老套的解决方法:

I've got two somewhat hacky workarounds:

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

第一个解决方案听起来有点工作和毫无意义的数据重复,更不用说处理旋转时的烦人以及堆叠"/复杂转换容易出错.

The first solution sounds like a bit of work and pointless duplication of data, not mention annoying when it comes to handling rotations and also error prone for 'stacked'/complex transformations.

第二个解决方法看起来有点麻烦,因为 contains() 应该可以正常工作,但它使用了 Processing 类,所以还不错.它是这样工作的:

The second workaround looks slightly hacky since contains() should've just worked, but it makes uses of Processing classes so it's not that bad. It works like this:

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

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

The svg comes from Examples > Basic > Shape > GetChild. You can open the sketch folder(Ctrl + K / CMD + K) to get "usa-wikipedia.svg" if you want to test the code as is:

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 实例,否则会出现这个警告:

I've noticed that the applyMatrix() method only works with the P3D and OPENGL renderers even thought I'm passing a PMatrix2D instance, otherwise this warning appears:

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

The 'cleaner' option is to modify the contains() method in the PShape class, then recompile Processing's core.jar and use the updated jar. If this is for a one-off small project I don't know if it's worth the trouble though, it might faster to have the slightly messier code from above than recompiling/updating core.jar.

这篇关于PShapeSVG contains() 函数在应用 scale() 时不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆