【问题标题】:Apply rotation angle to coordinates around origin?将旋转角度应用于原点周围的坐标?
【发布时间】:2014-06-27 14:49:24
【问题描述】:

我正在开发一个绘图应用程序,用户可以在其中创建一个矩形、一排孔、一个孔网格和多边形。现在,我拥有移动这些对象的功能,方法是确定触摸点是否在对象的边界内,在 TouchMove 操作期间更新对象坐标,然后使用更新的坐标重新绘制对象(连同绘制的所有其他内容)。 我的下一步是实施轮换。到目前为止,我能够获得一个旋转角度,在绘制旋转对象时使用它来旋转画布,然后恢复画布以便绘制其他对象没有角度。这完美地工作。当我尝试移动/旋转旋转的对象时​​,问题就来了。我存储对象旋转,但我不更新它存储的坐标;因此,当我尝试确定用户是否触摸了旋转的对象时​​,它与用户在屏幕上看到的不匹配。 我需要的是能够修改对象坐标或触摸坐标以反映旋转。有没有办法做到这一点?我是不是搞错了?

这是我的代码的一些 sn-ps:

这会确定是否触摸了一个圆圈网格:

     //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;
         }


     }

}

这个 sn-p 是我确定角度的方式:

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();
    }

【问题讨论】:

  • 在这里查看我的答案stackoverflow.com/questions/21633545/…
  • @pskink 感谢您的回复,但这需要我重新开始。一切都绘制在一个位图上,该位图绘制在 SurfaceView 画布上。这样做是为了让用户可以平移/缩放具有预定大小的单个位图。我的用户的绘图空间必须大于屏幕,所以这个功能是必不可少的。我也不确定如何绘制动态大小的矩形和路径。您的示例使用可绘制对象。
  • 只需将 canvas.drawBitmap(Bitmap, Matrix, Paint) 替换为画布即可。 concat(Matrix) 并进行绘图...
  • @pskink 这就是我目前在 onDraw 方法中的内容:“canvas.concat(matrix); canvas.drawPath(drawPath, drawPaint); canvas.drawBitmap(canvasBitmap,0,0,canvasPaint); "我的问题是在这些图层位图上绘制圆圈、网格、矩形、箭头和绘画,然后将它们附加到我的主位图,然后能够处理取消绘制并将它们围绕主位图移动。这很容易做到吗?
  • 是的,应该不会很难

标签: java android coordinates android-canvas surfaceview


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多