旋转坐标(Java 和几何)

Rotating Coordinates (Java and Geometry)

我正在使用 AWT canvas 作为基础开发 2D java 游戏引擎。这个游戏引擎的一部分是它需要有碰撞箱。不仅仅是内置的矩形(已经尝试过那个系统),我还需要我自己的 Hitbox class 因为我需要更多的功能。所以我做了一个,支持圆形和 4 边形的多边形碰撞盒。 hitboxclass的设置方式是用4个坐标点作为4个角顶点连接起来形成一个矩形。绘制连接点的线,这些线用于检测与其他碰撞盒的交点。但是我现在有一个问题:旋转。

box hitbox有两种可能,可以是4个坐标点,也可以是4个坐标点附加到一个gameobject上。不同之处在于前者只是基于 0,0 作为序数的 4 个坐标,而附加到游戏对象的坐标存储坐标中的偏移量而不是原始位置数据,因此 (-100,-100) 例如表示主机的位置游戏对象,但向左 100 像素,向上 100 像素。

在网上找到了绕原点旋转点的公式。由于基于 Gameobject 的碰撞盒以特定点为中心,我认为这将是尝试它的最佳选择。此代码运行每个刻度以更新玩家角色的命中框

            //creates a rectangle hitbox around this gameobject 
        int width = getWidth();
        int height = getHeight();
        Coordinate[] verts = new Coordinate[4]; //corners of hitbox. topLeft, topRight, bottomLeft, bottomRight
        verts[0] = new Coordinate(-width / 2, -height / 2);
        verts[1] = new Coordinate(width / 2, -height / 2);
        verts[2] = new Coordinate(-width / 2, height / 2);
        verts[3] = new Coordinate(width / 2, height / 2);
        //now go through each coordinate and adjust it for rotation
        for(Coordinate c : verts){
            if(!name.startsWith("Player"))return; //this is here so only the player character is tested
            double theta = Math.toRadians(rotation);
            c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
            c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));
        }
        getHitbox().vertices = verts;

对于视频质量不佳,我深表歉意,但这是上面的结果:https://www.youtube.com/watch?v=dF5k-Yb4hvE

所有相关的 class 都可以在这里找到:https://github.com/joey101937/2DTemplate/tree/master/src/Framework

编辑:期望的效果是框轮廓跟随字符成一圈,同时保持纵横比,如下所示:https://www.youtube.com/watch?v=HlvXQrfazhA。目前系统使用的是上面的代码,效果见上一个视频link。 我应该如何修改四个 2D 坐标以在围绕一个点的整个旋转过程中保持相对纵横比?

当前轮换系统如下:

其中 theta 是 raidians 中的旋转度数

你犯了经典错误:

    c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
    c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));

在第二行中,您使用 修改后的 c.x。记住 tempx = c.x 在计算之前使用它。

    tempx = c.x;
    c.x = (int)(tempx*Math.cos(theta)-c.y*Math.sin(theta));
    c.y = (int)(tempx*Math.sin(theta)+c.y*Math.cos(theta));

另一个问题:四舍五入 每次旋转后的坐标会在某些旋转后导致扭曲和收缩。明智的做法是将坐标存储在浮点数中并将它们四舍五入仅用于输出,或者记住起始值并按累积角度对它们应用旋转。