将旋转角度应用于原点周围的坐标?

时间:2014-06-27 14:49:25

标签: java android coordinates android-canvas surfaceview

我正在使用绘图应用程序,用户可以在其中创建矩形,一排孔,一个孔网格和多边形。现在,我有通过确定触摸点是否在对象范围内,在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 个答案:

答案 0 :(得分:0)

@pskink的解决方案很棒。我需要进行一些调整才能使用我的代码,但这只花了大约一天时间。我不得不改变从直接在主画布上绘制到在自己的位图上绘制的所有内容。此位图具有在其上绘制的对象的尺寸。这些位图存储在位图图层的LinkedList中,并通过canvas.drawBitmap(位图,x,y,null)添加到主位图;

这是他的例子的链接:Android ImageView Scaling and translating issue

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