在2D视图中上下移动/调整画布上的线条

时间:2018-02-08 18:34:02

标签: java android android-studio canvas

我正在使用Android应用程序进行备份相机模拟,需要绘制虚拟停车网格线(红色,黄色和绿色)。

要求:

  • 用户可以左右移动/调整停车线 (完成!!)。
  • 用户能够上下移动网格线的每一边(in 2D,如果我正确的话)就像这个视频link一样(我是谁? 试图找出

我想的是X应该是固定的,Y会根据用户输入而改变,无论是触摸还是按钮点击。
我是机器人的新手,我希望有人可以指引我走正确的道路。

在画布上绘制网格线的方法:

private void drawHorizontalLines(Canvas canvas){
    Paint paintGreen = new Paint();
    //Log.d(TAG, "Width = " + canvas.getClipBounds().width() + " Height = " + canvas.getClipBounds().height());
    //if(this.getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT)
    if(inCalibrationMode == false)
        getGridLines(canvas);
    {
        paintGreen.setStrokeWidth(10);
        //Log.d(TAG, ""+ Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)));
        //left side
        paintGreen.setColor(Color.RED );
        int topPoint = dangerousLineY;//height - (gridTopPoint*3)/10;
        int bottomPoint = gridBottomPoint;
        int letfPoint = gridLeftPoint;
        canvas.drawLine(letfPoint, bottomPoint, letfPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE))), topPoint, paintGreen);


        letfPoint = dangerousLineXLeft; //letfPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)));
        bottomPoint = topPoint;
        canvas.drawLine(letfPoint, bottomPoint, letfPoint + 100, bottomPoint, paintGreen);


        //letfPoint = letfPoint + 10;
        bottomPoint -= 30;
        letfPoint = letfPoint + (int) (30 * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)));
        topPoint = warningLineY;
        paintGreen.setColor(Color.YELLOW);
        canvas.drawLine(letfPoint, bottomPoint, letfPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5))), topPoint, paintGreen);

        letfPoint = letfPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)));
        bottomPoint = topPoint;
        canvas.drawLine(letfPoint, bottomPoint, letfPoint + 100, bottomPoint, paintGreen);

        bottomPoint -= 30;
        letfPoint = letfPoint + (int) (30 * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)));
        topPoint = safeLineY;
        paintGreen.setColor(Color.GREEN );
        canvas.drawLine(letfPoint, bottomPoint, letfPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 10))), topPoint, paintGreen);

        letfPoint = letfPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 10)));
        bottomPoint = topPoint;
        canvas.drawLine(letfPoint, bottomPoint, letfPoint + 100, bottomPoint, paintGreen);

        //right side
        paintGreen.setColor(Color.RED );
        topPoint = dangerousLineY;
        bottomPoint = gridBottomPoint;
        int rightPoint = gridRightPoint;
        canvas.drawLine(rightPoint, bottomPoint, rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE))), topPoint, paintGreen);

        rightPoint = dangerousLineXRight;
        bottomPoint = topPoint;
        canvas.drawLine(rightPoint, bottomPoint, rightPoint - 100, bottomPoint, paintGreen);


        bottomPoint -= 30;
        rightPoint = rightPoint - (int) (30 * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)));
        topPoint = warningLineY;
        paintGreen.setColor(Color.YELLOW);
        canvas.drawLine(rightPoint, bottomPoint, rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5))), topPoint, paintGreen);

        rightPoint = rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)));
        bottomPoint = topPoint;
        canvas.drawLine(rightPoint, bottomPoint, rightPoint - 100, bottomPoint, paintGreen);

        bottomPoint -= 30;
        rightPoint = rightPoint - (int) (30 * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)));
        topPoint = safeLineY;
        paintGreen.setColor(Color.GREEN);
        canvas.drawLine(rightPoint, bottomPoint, rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 10))), topPoint, paintGreen);

        rightPoint = rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 10)));
        bottomPoint = topPoint;
        canvas.drawLine(rightPoint, bottomPoint, rightPoint - 100, bottomPoint, paintGreen);


            setLayerType(LAYER_TYPE_SOFTWARE, blue);
        }
    }
}

onTouchEvent左右移动网格

    @Override
public boolean onTouchEvent(MotionEvent event) {
    if (isInCalibrationMode()) {
        float eventX = event.getX();
        float eventY = event.getY();

        Log.d(TAG, "-------------------------" + eventX + ":" + eventY);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //first check if we fall into the range of distance line
                Log.d(TAG, "" + eventX + ":" + eventY);
                if (inCalibrationMode == true) {
                    Log.d(TAG, "*" + safeLineXLeft + ":" + safeLineXRight + ":" + safeLineY);
                        if (
                            Math.abs(eventX - gridLeftPoint) <= DISTANCE_MOVE_RANGE && Math.abs(eventY - gridBottomPoint) <= DISTANCE_MOVE_RANGE
                            ) {
                        //move left side
                        moveGrid = MOVE_GRID_LEFT;
                    } else if (
                            Math.abs(eventX - gridRightPoint) <= DISTANCE_MOVE_RANGE && Math.abs(eventY - gridBottomPoint) <= DISTANCE_MOVE_RANGE) {
                        //move right side
                        moveGrid = MOVE_GRID_RIGHT;
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                Log.d(TAG, "TOUCH MOVE");
                if (moveGrid == MOVE_GRID_LEFT) {
                    gridLeftPoint = (int) eventX;

                } else if (moveGrid == MOVE_GRID_RIGHT) {
                    gridRightPoint = (int) eventX;
                } else if (moveGrid == MOVE_GRID_DANGEROUS) {
                    dangerousLineY = (int) eventY;

                } else if (moveGrid == MOVE_GRID_WARNING) {
                    warningLineY = (int) eventY;

                } else if (moveGrid == MOVE_GRID_SAFE) {
                    safeLineY = (int) eventY;
                }

                updateDistancePoints(); //update distance points when moving 

                break;
            case MotionEvent.ACTION_UP:
                // Log.d(TAG, "TOUCH UP");
                //path.lineTo(eventX, eventY);
                //slearScreen = true;

                moveGrid = MOVE_GRID_NONE;
                //Toast.makeText(getContext(), "test", Toast.LENGTH_SHORT).show(); 
                break;

            default:
                return false;
        }

        // Schedules a repaint.
        if (inCalibrationMode == true)
            invalidate();
        return true;
    }

    return false;
}

更新网格距离点

//update distance points method
private void updateDistancePoints(){
    //gridTopPoint = height/2+10;


    dangerousLineXLeft = gridLeftPoint + (int) ((gridBottomPoint - dangerousLineY) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)));
    dangerousLineXRight = gridRightPoint - (int) ((gridBottomPoint - dangerousLineY) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)));


    warningLineXLeft = gridLeftPoint +
            (int) ((gridBottomPoint - (dangerousLineY - 30)) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)))  +
            (int) (((dangerousLineY - 30) - warningLineY) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE+5)));

    warningLineXRight = gridRightPoint -
            (int) ((gridBottomPoint - (dangerousLineY - 30)) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)))  -
            (int) (((dangerousLineY - 30) - warningLineY) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE+5)))+200; //test Samira


    safeLineXLeft = gridLeftPoint +
            (int) ((gridBottomPoint - (dangerousLineY - 30)) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)))  +
            (int) (((dangerousLineY - 30) - warningLineY) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE+5))) +
            (int) (((warningLineY) - safeLineY) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE+10)));

    safeLineXRight = gridRightPoint -
            (int) ((gridBottomPoint - dangerousLineY - 30) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)))  -
            (int) (((dangerousLineY - 30) - warningLineY) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE+5))) -
            (int) (( warningLineY - safeLineY) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE+10)));

}

谢谢

1 个答案:

答案 0 :(得分:0)

我可以按如下方式旋转线:

1-找到每条线的中心/旋转点(Xm,Ym)
Xm =(startX + stopX)/ 2;
Xy =(startY + stopY)/ 2;
2-计算新点以绘制线

x=a*cos⁡(θ)-b*sin(θ)-Xm*cos⁡(θ)+Ym*sin⁡(θ)+Xm
y=a*sin⁡(θ)+b*cos(θ)-Xm*sin⁡(θ)-Ym*cos⁡(θ)+Ym

(a,b)旧点。

3-使用上述旋转角度和公式编写一个绘制线条的函数

private void drawLinesRotate(Canvas canvas) {

    Paint paint = new Paint();
    paint.setStrokeWidth(10);

    //rotation angle
    SharedPreferences Angleprefs = this.getContext().getSharedPreferences("prefAngles", Context.MODE_PRIVATE);
    double angle = Angleprefs.getFloat("angle", 0);
    double rotateAngle = Math.toRadians(angle); //rotate angle has to be in radians
//rotation point on the left
        SharedPreferences prefs = this.getContext().getSharedPreferences("prefRotate", Context.MODE_PRIVATE);
        float cX_Left = prefs.getFloat("centerPointLeftX", 0);
        float cY_Left = prefs.getFloat("centerPointLeftY", 0);
        //*******left side********* 
        //RED line
        paint.setColor(Color.RED);
        int topPoint = dangerousLineY;
        int bottomPoint = gridBottomPoint;
        int leftPoint = gridLeftPoint;
    int newX1 = (int) (Math.cos(rotateAngle) * ((float) leftPoint) - Math.sin(rotateAngle) * (float) bottomPoint - cX_Left * Math.cos(rotateAngle) + cY_Left * Math.sin(rotateAngle) + cX_Left);
    int newY1 = (int) (Math.sin(rotateAngle) * leftPoint + bottomPoint * Math.cos(rotateAngle) - cX_Left * Math.sin(rotateAngle) - cY_Left * Math.cos(rotateAngle) + cY_Left);
    int newX2 = (int) (Math.cos(rotateAngle) * (leftPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)))) - Math.sin(rotateAngle) * topPoint -
            cX_Left * Math.cos(rotateAngle) + cY_Left * Math.sin(rotateAngle) + cX_Left);
    int newY2 = (int) (Math.sin(rotateAngle) * (leftPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)))) + Math.cos(rotateAngle) * topPoint -
            cX_Left * Math.sin(rotateAngle) - cY_Left * Math.cos(rotateAngle) + cY_Left);
    canvas.drawLine(newX1, newY1, newX2, newY2, paint);

    leftPoint = dangerousLineXLeft;
    bottomPoint = topPoint;
    //horizontal line
    canvas.drawLine(newX2, newY2, newX2 + 100, newY2, paint);
//        //YELLOW line
    bottomPoint -= 30;
    leftPoint = leftPoint + (int) (30 * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)));
    topPoint = warningLineY;
    paint.setColor(Color.YELLOW);

    newX1 = (int) (Math.cos(rotateAngle) * ((float) leftPoint) - Math.sin(rotateAngle) * (float) bottomPoint - cX_Left * Math.cos(rotateAngle) + cY_Left * Math.sin(rotateAngle) + cX_Left);
    newY1 = (int) (Math.sin(rotateAngle) * leftPoint + bottomPoint * Math.cos(rotateAngle) - cX_Left * Math.sin(rotateAngle) - cY_Left * Math.cos(rotateAngle) + cY_Left);
    newX2 = (int) (Math.cos(rotateAngle) * (leftPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)))) - Math.sin(rotateAngle) * topPoint -
            cX_Left * Math.cos(rotateAngle) + cY_Left * Math.sin(rotateAngle) + cX_Left);
    newY2 = (int) (Math.sin(rotateAngle) * (leftPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)))) + Math.cos(rotateAngle) * topPoint -
            cX_Left * Math.sin(rotateAngle) - cY_Left * Math.cos(rotateAngle) + cY_Left);
    canvas.drawLine(newX1, newY1, newX2, newY2, paint);
    leftPoint = leftPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)));
    bottomPoint = topPoint;
    canvas.drawLine(newX2, newY2, newX2 + 100, newY2, paint);
//        //GREEN line
        bottomPoint -= 30;
        leftPoint = leftPoint + (int) (30 * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)));
        topPoint = safeLineY;
        paint.setColor(Color.GREEN);

    newX1 = (int) (Math.cos(rotateAngle) * ((float) leftPoint) - Math.sin(rotateAngle) * (float) bottomPoint - cX_Left * Math.cos(rotateAngle) + cY_Left * Math.sin(rotateAngle) + cX_Left);
    newY1 = (int) (Math.sin(rotateAngle) * leftPoint + bottomPoint * Math.cos(rotateAngle) - cX_Left * Math.sin(rotateAngle) - cY_Left * Math.cos(rotateAngle) + cY_Left);
    newX2 = (int) (Math.cos(rotateAngle) * (leftPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 10)))) - Math.sin(rotateAngle) * topPoint -
            cX_Left * Math.cos(rotateAngle) + cY_Left * Math.sin(rotateAngle) + cX_Left);
    newY2 = (int) (Math.sin(rotateAngle) * (leftPoint + (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 10)))) + Math.cos(rotateAngle) * topPoint -
            cX_Left * Math.sin(rotateAngle) - cY_Left * Math.cos(rotateAngle) + cY_Left);
    canvas.drawLine(newX1, newY1, newX2, newY2, paint);
    canvas.drawLine(newX2, newY2, newX2 + 100, newY2, paint);

    //*******right side*********
    //rotation point on the right
    float cX_Right = prefs.getFloat("centerPointRightX", 0);
    float cY_Right = prefs.getFloat("centerPointRightY", 0);
    angle *= -1; //right side angle should be (-)
    rotateAngle = Math.toRadians(angle);
    //RED line
    paint.setColor(Color.RED);
    topPoint = dangerousLineY;
    bottomPoint = gridBottomPoint;
    int rightPoint = gridRightPoint;


    newX1 = (int) (Math.cos(rotateAngle) * ((float) rightPoint) - Math.sin(rotateAngle) * (float) bottomPoint - cX_Right * Math.cos(rotateAngle) + cY_Right * Math.sin(rotateAngle) + cX_Right);
    newY1 = (int) (Math.sin(rotateAngle) * rightPoint + bottomPoint * Math.cos(rotateAngle) - cX_Right * Math.sin(rotateAngle) - cY_Right * Math.cos(rotateAngle) + cY_Right);
    newX2 = (int) (Math.cos(rotateAngle) * (rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)))) - Math.sin(rotateAngle) * topPoint -
            cX_Right * Math.cos(rotateAngle) + cY_Right * Math.sin(rotateAngle) + cX_Right);
    newY2 = (int) (Math.sin(rotateAngle) * (rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)))) + Math.cos(rotateAngle) * topPoint -
            cX_Right * Math.sin(rotateAngle) - cY_Right * Math.cos(rotateAngle) + cY_Right);
    canvas.drawLine(newX1, newY1, newX2, newY2, paint); //vertical line

    //horizontal line
    rightPoint = dangerousLineXRight;
    bottomPoint = topPoint;
    canvas.drawLine(newX2, newY2, newX2 - 100, newY2, paint);

    //YELLOW line
    bottomPoint -= 30;
    rightPoint = rightPoint - (int) (30 * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE)));
    topPoint = warningLineY;
    paint.setColor(Color.YELLOW);
    newX1 = (int) (Math.cos(rotateAngle) * ((float) rightPoint) - Math.sin(rotateAngle) * (float) bottomPoint - cX_Right * Math.cos(rotateAngle) + cY_Right * Math.sin(rotateAngle) + cX_Right);
    newY1 = (int) (Math.sin(rotateAngle) * rightPoint + bottomPoint * Math.cos(rotateAngle) - cX_Right * Math.sin(rotateAngle) - cY_Right * Math.cos(rotateAngle) + cY_Right);
    newX2 = (int) (Math.cos(rotateAngle) * (rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)))) - Math.sin(rotateAngle) * topPoint -
            cX_Right * Math.cos(rotateAngle) + cY_Right * Math.sin(rotateAngle) + cX_Right);
    newY2 = (int) (Math.sin(rotateAngle) * (rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)))) + Math.cos(rotateAngle) * topPoint -
            cX_Right * Math.sin(rotateAngle) - cY_Right * Math.cos(rotateAngle) + cY_Right);
    canvas.drawLine(newX1, newY1, newX2, newY2, paint); //vertical line
    //horizontal line
    rightPoint = rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)));
    bottomPoint = topPoint;
    canvas.drawLine(newX2, newY2, newX2 - 100, newY2, paint);

    //GREEN line
    bottomPoint -= 30;
    rightPoint = rightPoint - (int) (30 * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 5)));
    topPoint = safeLineY;
    paint.setColor(Color.GREEN);
    newX1 = (int) (Math.cos(rotateAngle) * ((float) rightPoint) - Math.sin(rotateAngle) * (float) bottomPoint - cX_Right * Math.cos(rotateAngle) + cY_Right * Math.sin(rotateAngle) + cX_Right);
    newY1 = (int) (Math.sin(rotateAngle) * rightPoint + bottomPoint * Math.cos(rotateAngle) - cX_Right * Math.sin(rotateAngle) - cY_Right * Math.cos(rotateAngle) + cY_Right);
    newX2 = (int) (Math.cos(rotateAngle) * (rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 10)))) - Math.sin(rotateAngle) * topPoint -
            cX_Right * Math.cos(rotateAngle) + cY_Right * Math.sin(rotateAngle) + cX_Right);
    newY2 = (int) (Math.sin(rotateAngle) * (rightPoint - (int) ((bottomPoint - topPoint) * Math.tan(Math.toRadians(DISTANCE_GRID_ANGLE + 10)))) + Math.cos(rotateAngle) * topPoint -
            cX_Right * Math.sin(rotateAngle) - cY_Right * Math.cos(rotateAngle) + cY_Right);
    canvas.drawLine(newX1, newY1, newX2, newY2, paint); //vertical line
    //horizontal line
    canvas.drawLine(newX2, newY2, newX2 - 100, newY2, paint);
}

按钮点击(有2个按钮)增加/减少旋转角度并将其保存在SharedPreferences中。还必须保存旋转点,因为我还左右移动线。在onDraw(Canvas canvas)上调用此方法。为了更好地可视化我绘制的线条,请参阅附带的屏幕截图。

enter image description here 我相信那里有更好的解决方案,但这对我有用。
希望能帮到别人。

相关问题