2012-09-08 43 views
0

正如標題所說,如果我縮放形狀shape.scale(0.5),爲什麼它不起作用?當應用scale()時,PShapeSVG contains()函數不起作用

即使我做shape(0,0,200,200)也不起作用,這意味着我不是在原始尺寸中繪製形狀。這是一個錯誤還是我錯過了什麼?

+0

我的解決方案適合您嗎?我也發佈了這個問題(http://code.google.com/p/processing/issues/detail?id=1242),以防萬一。 –

回答

0

這是一種錯誤,雖然我不確定有多嚴重。從您的測試中發現,當使用轉換(平移/旋轉/縮放)時,方法不起作用。

我有兩個稍微哈克的解決方法:

  1. 存儲頂點的一個單獨的陣列中,手動添加(偏移/平移)和乘法(縮放比例)的位置值,則如果point lies inside the polygon測試。
  2. 使用變換矩陣,它是從屏幕(典型處理)座標轉換爲變換後的SVG座標的逆向變換。

第一個解決方案聽起來像是一點工作和沒有意義的數據重複,當談到處理旋轉時並沒有提到惱人的問題,而且還出現了「堆積」/複雜變換的錯誤。

第二種解決方法看起來有點冒險,因爲contains()應該剛剛工作,但它使用了Processing類,所以它並沒有那麼糟糕。它的工作原理是這樣的:

  1. 創建你所適用的轉換矩陣,你需要在你的形狀變換(如翻譯(),旋轉(),規模()),並將其存儲
  2. 將此改造形狀
  3. 存儲此轉換矩陣的逆函數以將屏幕座標轉換爲svg座標(帶有轉換),並且這種方式contains()將起作用。

SVG的來自示例>基本>形狀> 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渲染甚至以爲我passing a 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. 

的「清潔」選項來修改PShape類的contains()方法,然後重新編譯處理的核心。 jar並使用更新的jar。如果這是一次性的小型項目,我不知道是否值得這麼麻煩,但從重新編譯/更新core.jar開始,稍微有些混亂的代碼可能會更快。

相關問題