0

タイトルが言ったように、シェイプをスケーリングするとうまくいかないのはなぜshape.scale(0.5)ですか?

shape(0,0,200,200)本来の寸法ではない形状を描いてもうまくいきません。これはバグですか、それとも何か不足していますか?

4

1 に答える 1

0

どれほど深刻かはわかりませんが、これは一種のバグです。テストからわかったようcontains()に、変換(平行移動/回転/スケール)が使用されている場合、このメソッドは機能しません。

私には2つのややハッキーな回避策があります:

  1. 頂点の個別の配列を格納し、位置の値を手動で追加(オフセット/変換)および乗算(スケーリング)してから、ポイントがポリゴンの内側にあるかどうかをテストします。
  2. 変換行列を使用すると、画面(通常の処理)座標から変換されたSVG座標に変換するのは逆になります。

最初の解決策は、少しの作業とデータの無意味な重複のように聞こえます。回転の処理に関して煩わしいことは言うまでもなく、「スタック」/複雑な変換でエラーが発生しやすくなります。

2番目の回避策は、contains()が機能するはずだったため、少しハッキーに見えますが、Processingクラスを使用するため、それほど悪くはありません。それはこのように動作します:

  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()メソッドは、PMatrix2Dインスタンスを渡したP3Dとしても、レンダラーとOPENGLレンダラーでのみ機能することに気付きました。そうでない場合、次の警告が表示されます。

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を使用することです。これが1回限りの小さなプロジェクトの場合、問題が発生する価値があるかどうかはわかりませんが、core.jarを再コンパイル/更新するよりも、上から少し厄介なコードを使用する方が速い場合があります。

于 2012-09-10T11:21:22.840 に答える