2014-06-27 58 views
0

我正在繪製應用程序,用戶可以在其中創建矩形,一排孔,孔網格和多邊形。現在我可以通過確定觸摸點是否在對象邊界內,在TouchMove動作期間更新對象座標,然後使用更新後的座標重新繪製對象(以及繪製的所有內容)來移動這些對象。 我的下一步是執行旋轉。到目前爲止,我可以獲得一個旋轉角度,在繪製旋轉的對象時​​使用它來旋轉畫布,然後恢復畫布,以便其他對象不帶角度地繪製。這工作完美。當我嘗試移動/旋轉旋轉的對象時​​,問題就出現了。我存儲對象旋轉,但我不更新它的存儲座標;因此,當我嘗試確定用戶是否觸摸了旋轉的對象時​​,它與用戶在屏幕上看到的內容不匹配。 我需要的是能夠修改對象座標或觸摸座標以反映旋轉。有沒有辦法做到這一點?我是否全部錯了?將旋轉角度應用於原點周圍的座標?

下面是我的一些代碼片段:

這決定了圓的電網已被觸摸:

 //retrieve touch coordinates. Adjust for matrix transformations 
float currX=(event.getX()-matrixValues[2])/matrixValues[0]; 
float currY=(event.getY()-matrixValues[5])/matrixValues[4]; 
//... skip other code for snippet 
else if(drawObject.getDrawAction()=="array") 
{ 
    ArrayList <DrawAction> redrawArray=drawObject.getDrawArray(); 
    if(drawMode=="remove") 
    { 
     //determine which hole in grid was touched. "Remove" it 
     for(int y=0; y<redrawArray.size();y++) 
     { 
      DrawAction arrayAction=redrawArray.get(y); 
      if(currX>(arrayAction.getDrawX()-arrayAction.getDrawRadius()) && currX<(arrayAction.getDrawX()+arrayAction.getDrawRadius()) && currY<(arrayAction.getDrawY()+arrayAction.getDrawRadius()) && currY>(arrayAction.getDrawY()-arrayAction.getDrawRadius())) 
      { 
       arrayAction.setRemoved(true); 
       //add undo object for this action 
       DrawAction undoRemove= new DrawAction("remove", arrayAction); 
       undoList.add(undoRemove); 
       //redraw objects with updated status 
       redrawObjects(false); 

       break outerloop; 

      } 
     } 
    } 
    else 
    { 
     //determine all coordinates within the grid. If we are within the grid, then we want to move the whole grid 
     float holeRadius=redrawArray.get(0).getDrawRadius(); 
     float lowestX=redrawArray.get(0).getDrawX()-holeRadius; 
     float lowestY=redrawArray.get(0).getDrawY()-holeRadius; 
     float highestX=redrawArray.get(redrawArray.size()-1).getDrawX()+holeRadius; 
     float highestY=redrawArray.get(redrawArray.size()-1).getDrawY()+holeRadius; 


     if(currX>lowestX && currX<highestX && currY>lowestY && currY<highestY) 
     { 
      touchObject=drawObject; 
      //store coordinates for new coordinate calculations 
      touchedX=currX; 
      touchedY=currY;      

      break outerloop; 
     } 


    } 

}

這個片段是怎麼確定的角度:

touchObject.setRotationAngle((float) getDegreesFromTouchEvent(currX, currY)); 
touchObject.setRotated(true); 

這是返回角度的函數:

//determine rotation from touch event and screen dimensions 
    private double getDegreesFromTouchEvent(float x, float y){ 
     double delta_x = x - (screenWidth) /2; 
     double delta_y = (screenHeight) /2 - y; 
     double radians = Math.atan2(delta_y, delta_x); 

     return (-1)*Math.toDegrees(radians); 
    } 

這裏的地方我重繪移動/旋轉後的一切:

//redraw everything 
    for(int x=0; x<undoList.size();x++) 
    { 
     //retrieve next object to draw 
     DrawAction drawObject=undoList.get(x); 
     //retrieve object's brush width/paint color 
     this.setBrushSize(drawObject.getBrushWidth()); 
     drawPaint.setColor(drawObject.getPaintColor()); 

     //save state of canvas. This is so we can rotate it, draw, and then rotate back to its original state 
     drawCanvas.save(); 

     //if this object has been rotated, then we need to rotate the canvas before drawing it 
     if(drawObject.isRotated()) 
     { 
      drawCanvas.rotate(drawObject.getRotationAngle(),drawObject.getCenterX(),drawObject.getCenterY()); 
     } 

     if(drawObject.getDrawAction()=="circle" && !drawObject.isRemoved()) 
     { 
      drawCanvas.drawCircle(drawObject.getDrawX(), drawObject.getDrawY(), drawObject.getDrawRadius(),drawPaint); 
     } 
     if(drawObject.getDrawAction()=="rectangle") 
     { 
      if(!drawObject.isRemoved()) 
      { 
       drawCanvas.drawRect(drawObject.getDrawLeft(), drawObject.getDrawTop(), drawObject.getDrawRight(), drawObject.getDrawBottom(),drawObject.getDrawPaint()); 
       drawCanvas.drawCircle(drawObject.getCenterX(), drawObject.getCenterY(), 2, drawObject.getDrawPaint()); 
      }     
     } 
     if(drawObject.getDrawAction()=="text" || drawObject.getDrawAction()=="delay") 
     { 
      drawCanvas.drawText(drawObject.getDrawtext(), drawObject.getDrawX(), drawObject.getDrawY(), drawObject.getDrawPaint()); 
     }  
     if(drawObject.getDrawAction()=="array") 
     { 
      ArrayList <DrawAction> redrawArray=drawObject.getDrawArray(); 
      for(int y=0; y<redrawArray.size();y++) 
      { 
       DrawAction arrayAction=redrawArray.get(y); 
       if(!arrayAction.isRemoved()) 
       { 
        drawCanvas.drawCircle(arrayAction.getDrawX(), arrayAction.getDrawY(), arrayAction.getDrawRadius(),drawPaint); 
       }     
      } 

     } 
     if(drawObject.getDrawAction()=="path") 
     { 
      drawCanvas.drawPath(drawObject.getDrawPath(), drawPaint);    
     } 
     //restore canvas to original state 
     drawCanvas.restore(); 
    } 
+1

在這裏看到我的回答http://stackoverflow.com/questions/21633545/android-imageview-scaling-and-translating-問題 – pskink

+0

@pskink感謝您的回覆,但這需要我重新開始。一切都在繪製在SurfaceView畫布上的單個位圖上繪製。這樣做是爲了讓用戶可以平移/縮放具有預定大小的單個位圖。我的用戶的繪圖空間必須比屏幕大,所以這個功能是必不可少的。我也不確定如何繪製動態大小的矩形和路徑。你的例子使用drawables。 –

+1

只需用canvas將canvas.drawBitmap(Bitmap,Matrix,Paint)替換即可。 concat(矩陣),並做你的繪圖... – pskink

回答

0

@ pskink的解決方案是巨大的。我們花了一些時間來調整代碼,但只花了一天時間。我不得不改變從直接在主畫布上繪製到繪製在它自己的位圖上的所有內容。該位圖具有在其上繪製的對象的尺寸。這些位圖存儲在位圖層的LinkedList中,並通過canvas.drawBitmap(bitmap,x,y,null)添加到主位圖中。

這裏是他的例子鏈接:Android ImageView Scaling and translating issue

和他的來源:https://github.com/pskink/android-gesture-detectors