【问题标题】:Rotating all rectangle corners旋转所有矩形角
【发布时间】:2015-05-04 17:39:36
【问题描述】:

我正在开发一款你是宇宙飞船的游戏。这艘宇宙飞船必须能够旋转。矩形有两个数组x[]y[],包含矩形的所有角位置。但是当我应用旋转公式时,我得到了一个相当奇怪的旋转。为了解释它,它看起来像是在旋转屏幕的左下角。

为了制作这些角阵列,我采用 x 位置、y 位置、宽度和高度。

角阵列的制作

public Vertex2f(float x, float y, float w, float h){
    this.x[0] = x; 
    this.y[0] = y;

    this.x[1] = x+w;
    this.y[1] = y;

    this.x[2] = x+w;
    this.y[2] = y+h;

    this.x[3] = x;
    this.y[3] = y+h;
}

我的旋转功能

public void rotate(float angle){
    this.rotation = angle;

    double cos = Math.cos(rotation);
    double sin = Math.sin(rotation);

    for(int i = 0; i < x.length; i++){
        x[i] = (float)(cos * x[i] - sin * y[i]);
        y[i] = (float)(sin * x[i] + cos * y[i]);

    }

}

如果它有助于我在 java 中使用 LWJGL/OpenGL 来处理所有图形,并使用 Slick2d 加载和初始化我正在使用的精灵。

【问题讨论】:

    标签: java math rotation lwjgl


    【解决方案1】:

    试试这个:

    public void rotate(float angle){
        this.rotation = angle;
    
        double cos = Math.cos(rotation);
        double sin = Math.sin(rotation);
    
        double xOffset = (x[0]+x[2])/2;
        double yOffset = (y[0]+y[2])/2;
    
        for(int i = 0; i < 3; i++){
            x[i] = (float)(cos * (x[i]-xOffset) - sin * (y[i]-yOffset)) + xOffset;
            y[i] = (float)(sin * (x[i]-xOffset) + cos * (y[i]-yOffset)) + yOffset;
    
        }
    
    }
    

    您必须围绕矩形的中心旋转。否则中心在 x=0 和 y=0

    编辑:

    public void rotate(float angle){
        this.rotation = angle;
    
        double cos = Math.cos(rotation);
        double sin = Math.sin(rotation);
    
        double xOffset = (x[0]+x[2])/2;
        double yOffset = (y[0]+y[2])/2;
    
        for(int i = 0; i < 3; i++){
            double newX = (float)(cos * (x[i]-xOffset) - sin * (y[i]-yOffset)) + xOffset;
            double newY = (float)(sin * (x[i]-xOffset) + cos * (y[i]-yOffset)) + yOffset;
    
            x[i] = newX;
            y[i] = newY;
        }
    }
    

    other thread

    【讨论】:

    • 这更好,但只是跳过了自己
    • 需要缓冲新的x[i],所以不影响y[i]计算
    【解决方案2】:

    公式的问题

        x[i] = (float)(cos * x[i] - sin * y[i]);
        y[i] = (float)(sin * x[i] + cos * y[i]);
    

    除了缺少旋转中心之外,您在第一个公式中更改了x[i],但希望在第二个公式中使用原始值。因此,您需要使用局部变量lx, ly,如

        float lx = x[i] - xcenter;
        float ly = y[i] - ycenter;
        x[i] = xcenter + (float)(cos * lx - sin * ly);
        y[i] = ycenter + (float)(sin * lx + cos * ly);
    

    如果对象已经以rotation 的角度旋转,则此代码将角度angle 添加到总旋转角度。相反,如果给定参数angle 是新的总旋转角度,则需要使用角度差计算sincos 值。也就是说,例如,开始该过程,

    public void rotate(float angle){
    
    
        double cos = Math.cos(angle - rotation);
        double sin = Math.sin(angle - rotation);
    
        this.rotation = angle;
    

    【讨论】:

    • 看起来船只是在 x 轴上旋转/缩放和翻转
    • 这个代码,作为原始的每个意图,将作为参数给出的角度添加到现有的旋转中。比例应该保持不变,不应该有(镜像)翻转。如果要将给定角度设为新的绝对角度,请设置angle = angle - rotation; rotation = rotation + angle; sin=Math.sin(angle); cos=Math.cos(angle)。或者将局部坐标和全局坐标分开。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多