java - 旋转坐标(Java 和几何)

标签 java geometry awt trigonometry

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

盒子碰撞箱有两种可能性,它可以只是四个坐标点,或者它可以是附加到游戏对象的 4 个坐标点。区别在于前者只是基于 0,0 作为序数的 4 个坐标,而附加到游戏对象的存储的是坐标中的偏移量而不是原始位置数据,因此 (-100,-100) 例如表示主机的位置游戏对象向左 100 像素,向上 100 像素。

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

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

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

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

当前轮换系统如下:

  • x = x*Cos(theta) - y *Sin(theta)
  • y = x*Sin(theta) + y *Cos(theta)

其中 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));

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

关于java - 旋转坐标(Java 和几何),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53788765/

相关文章:

java - 如何告诉 NetBeans 我的 Tomcat "home"在哪里?

java - 如何在 Android Studio 中基于 HashMap 创建警报对话框?

geometry - 弧变换起点终点到起点角度终点角度

algorithm - 寻找适合一系列矩形的最大矩形的面积

algorithm - 任意凸多边形中具有固定纵横比的最大对齐矩形?

java - 递归算法的大O复杂度

java - 在 Java 应用程序中检测 Windows 注销事件

java - Repaint方法更新太慢

java - 如何在java中关闭这个窗口?

java - 绘画时缓冲图像闪烁