首页 > 解决方案 > Rotating Coordinates (Java and Geometry)

问题描述

I am working on a 2D java game engine using AWT canvas as a basis. Part of this game engine is that it needs to have hitboxes with collision. Not just the built in rectangles (tried that system already) but I need my own Hitbox class because I need more functionality. So I made one, supports circular and 4-sided polygon shaped hitboxes. The way the hitbox class is setup is that it uses four coordinate points to serve as the 4 corner vertices that connect to form a rectangle. Lines are draw connecting the points and these are the lines that are used to detect intersections with other hitboxes. But I now have a problem: rotation.

There are two possibilities for a box hitbox, it can just be four coordinate points, or it can be 4 coordinate points attached to a gameobject. The difference is that the former is just 4 coordinates based on 0,0 as the ordin while the attached to gameobject stores offsets in the coordinates rather than raw location data, so (-100,-100) for example represents the location of the host gameobject but 100 pixels to the left, and 100 pixels up.

Online I found a formula for rotating points about the origin. Since Gameobject based hitboxes were centered around a particular point, I figured that would be the best option to try it on. This code runs each tick to update a player character's hitbox

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

I appologize for poor video quality but this is what the results of the above are: https://www.youtube.com/watch?v=dF5k-Yb4hvE

All related classes are found here: https://github.com/joey101937/2DTemplate/tree/master/src/Framework

edit: The desired effect is for the box outline to follow the character in a circle while maintaining aspect ratio as seen here: https://www.youtube.com/watch?v=HlvXQrfazhA . The current system uses the code above, the effect of which can be seen above in the previous video link. How should I modify the four 2D coordinates to maintain relative aspect ratio throughout a rotation about a point?

current rotation system is the following:

where theta is degree of rotation in raidians

标签: javageometryawttrigonometry

解决方案


你犯了经典错误:

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

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


推荐阅读