2D вращение вокруг точки с использованием Canvas и Path - PullRequest
1 голос
/ 07 сентября 2011

Проблема связана с формой Android Path.Это треугольник, который я использую в качестве стрелки, чтобы указывать на объекты на экране Canvas.Это для 2d игры.игрок в центре экрана, объекты вокруг него и вне экрана.

Эти стрелки должны вращаться вокруг центра экрана с радиусом, таким образом они вращаются по кругу вокруг игрока.Стрелки указывают на объекты, к которым игрок должен двигаться.

То, что у меня сейчас есть, несколько работает, но стрелки несутся по кругу с нелепой скоростью.Как ни странно, они указывают в правильном направлении, но они не остаются в нужной точке круга.(если стрелка указывает на северо-восток, стрелка должна быть в северо-восточной части круга и т. д.)

Я уверен, что это из-за математики.Я, вероятно, неправильно использую atan2.Или холст. Переводится неправильно.Или, может быть, я вообще не должен использовать atan2.Помогите!:)

Вот код:

    // set the shape of our radar blips
    oBlipPath.moveTo(0, -5);
    oBlipPath.lineTo(5, 0);
    oBlipPath.lineTo(0, 5);

    // Paint all the enemies and radar blips!
    for(int i=0; i<iNumEnemies; i++){
        if (oEnemies[i].draw(canvas, (int)worldX, (int)worldY)){

            //calculate the degree the object is from the center of the screen. 
            //(user is the player. this could be done easier using iWidth and iHeight probably)
            //we use a world coordinate system. worldY and worldX are subtracted
            fDegrees = (float)Math.toDegrees(Math.atan2((oEnemies[i].getEnemyCenterY()-worldY)-user.getShipCenterY(), (oEnemies[i].getEnemyCenterX()-worldX)-user.getShipCenterX()));

            canvas.save();

            //get to the center
            canvas.translate((iWidth / 2) , (iHeight / 2) );

            //move a little bit depending on direction (trying to make arrows appear around a circle)
            canvas.translate((float)(20 * Math.cos(fDegrees)), (float)(20* Math.sin(fDegrees)));

            //rotate canvas so arrows will rotate and point in the right direction
            canvas.rotate(fDegrees);

            //draw arrows
            canvas.drawPath(oBlipPath, oBlipPaint);
            canvas.restore();

        }
    }

Ответы [ 2 ]

1 голос
/ 08 сентября 2011

Ну, я делаю то, что хотел, но не знаю как. Я добавил несколько случайных чисел, пока все не появилось на экране так, как я хотел. Если кто-то хочет подсказать мне, как лучше это сделать, я весь в ушах.

код:

    // set the shape of our radar blips
    oBlipPath.moveTo(0, -5);
    oBlipPath.lineTo(6, 0);
    oBlipPath.lineTo(0, 5);


    oBlipMatrix.setRotate(45, 0, 0);
    oBlipPath.transform(oBlipMatrix);

    // Paint all the enemies and radar blips!
    for(int i=0; i<iNumEnemies; i++){
        oEnemies[i].draw(canvas, (int)worldX, (int)worldY);
        if (oEnemies[i].bActive){
            //calculate the degree the object is from the center of the screen. 
            //(user is the player. this could be done easier using iWidth and iHeight probably)
            //we use a world coordinate system. worldY and worldX are subtracted
            fDegrees = (float)Math.toDegrees(Math.atan2((oEnemies[i].getEnemyCenterY()-worldY)-(iHeight / 2), (oEnemies[i].getEnemyCenterX()-worldX)-(iWidth / 2)));

            canvas.save();

            //get to the center
            canvas.translate((iWidth / 2 + 50) , (iHeight / 2 + 50) );

            //move a little bit depending on direction (trying to make arrows appear around a circle)
            //canvas.translate((float)(20 * Math.cos(fDegrees)), (float)(20* Math.sin(fDegrees)));

            //rotate canvas so arrows will rotate and point in the right direction
            canvas.rotate(fDegrees-45, -50, -50);

            //draw arrows
            canvas.drawPath(oBlipPath, oBlipPaint);
            canvas.restore();
        }

    }

По какой-то причине я должен вычесть 45 градусов из поворота холста, но добавить 45 градусов к повороту матрицы формы контура. Это работает, но почему ?! :)

1 голос
/ 07 сентября 2011

Аффинные преобразования являются не коммутативными.Они обычно применяются в явном порядке последний-указанный-первый-примененный .В качестве альтернативы рассмотрим вариант rotate(), который вращается вокруг точки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...