在运行时旋转俄罗斯方块 [英] Rotate tetris blocks at runtime

查看:198
本文介绍了在运行时旋转俄罗斯方块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类 tetronimo (一个tetris块),它有四个 QRect 类型(名为<$ c $第一,第二第三, code>分别)。我使用 build_tetronimo_L 类型绘制每个 tetronimo 函数。

这些构建tetronimo在某个方向,但是在tetris中你应该能够旋转tetronimo的,我试图旋转tetronimo通过旋转tetronimo的每个单独的正方形。

我发现下面的公式适用于特定正方形的每个(x,y)坐标。
$ b


newx = cos(角度)* oldx - sin(角度)* oldy

newy = sin(角度)* oldx + cos(角度)* oldy


现在, QRect 类型的Qt,似乎只有一个 setCoords 函数,它采用左上角的(x,y)坐标 em>和右下方



我在这里有一个例子(它似乎没有产生正确的结果)旋转我的tetronimo中的前两个方块。



任何人都可以告诉我,我应该如何正确旋转这些方块,使用运行时间旋转计算?

  void tetromino :: rotate(double angle)//以度为单位的角度
{
std :: map< std :: string,rect_coords> coords = get_coordinates();
//第一个广场
rect_coords first_coords = coords [first];

//左上角x和y
int newx_first_tl =(cos(to_radians(angle))* first_coords.top_left_x) - (sin(to_radians(angle))* first_coords.top_left_y);
int newy_first_tl =(sin(to_radians(angle))* first_coords.top_left_x)+(cos(to_radians(angle))* first_coords.top_left_y);

//右下角x和y
int newx_first_bl =(cos(to_radians(angle))* first_coords.bottom_right_x) - (sin(to_radians(angle))* first_coords.bottom_right_y);
int newy_first_bl =(cos(to_radians(angle))* first_coords.bottom_right_x)+(sin(to_radians(angle))* first_coords.bottom_right_y);

//更改坐标
first-> setCoords(newx_first_tl,newy_first_tl,newx_first_tl + tetro_size,newy_first_tl - tetro_size);


//第二广场
rect_coords second_coords = coords [second];

int newx_second_tl =(cos(to_radians(angle))* second_coords.top_left_x) - (sin(to_radians(angle))* second_coords.top_left_y);
int newy_second_tl =(sin(to_radians(angle))* second_coords.top_left_x)+(cos(to_radians(angle))* second_coords.top_left_y);

//更改坐标
second-> setCoords(newx_second_tl,newy_second_tl,newx_second_tl - tetro_size,newy_second_tl + tetro_size);

第一第二 QRect 类型。 rect_coords 只是一个 struct ,其中包含四个 int s ,它存储了正方形的坐标。



第一个平方和第二平方的计算结果是不同的,因为我在试图弄清楚它。 b
$ b

我希望有人能帮我解决这个问题吗?

(是的,我可以做得更简单,但我想从中学习)

解决方案

它似乎更像是一个数学问题,而不是一个编程问题。只需插入90度的角度值就可以了。对于90度,点(x,y)被映射到(-y,x)。你可能不想围绕原点旋转,而是围绕某个轴心点c.x,c.y.为此,您需要先翻译,然后旋转,然后再翻译:

 (x,y):=(xc.x ,yc.y)//转换为在c 
(x,y)处的原点系统:=(-y,x)//旋转
(x,y):=(x + cx,y + cy)//翻译成原来的合作系统


I have a class tetronimo (a tetris block) that has four QRect types (named first, second, third, fourth respectively). I draw each tetronimo using a build_tetronimo_L type functions.

These build the tetronimo in a certain direction, but as in tetris you're supposed to be able to rotate the tetronimo's, I'm trying to rotate a tetronimo by rotating each individual square of the tetronimo.

I have found the following formula to apply to each (x, y) coordinate of a particular square.

newx = cos(angle) * oldx - sin(angle) * oldy

newy = sin(angle) * oldx + cos(angle) * oldy

Now, the QRect type of Qt, does only seem to have a setCoords function that takes the (x, y) coordinates of top-left and bottom-right points of the respective square.

I have here an example (which doesn't seem to produce the correct result) of rotating the first two squares in my tetronimo.

Can anyone tell me how I'm supposed to rotate these squares correctly, using runtime rotation calculation?

void tetromino::rotate(double angle) // angle in degrees
{
    std::map<std::string, rect_coords> coords = get_coordinates();
        // FIRST SQUARE
    rect_coords first_coords = coords["first"];

    //top left x and y
    int newx_first_tl = (cos(to_radians(angle)) * first_coords.top_left_x) - (sin(to_radians(angle)) * first_coords.top_left_y);
    int newy_first_tl = (sin(to_radians(angle)) * first_coords.top_left_x) + (cos(to_radians(angle)) * first_coords.top_left_y);

    //bottom right x and y
    int newx_first_bl = (cos(to_radians(angle)) * first_coords.bottom_right_x) - (sin(to_radians(angle)) * first_coords.bottom_right_y);
    int newy_first_bl = (cos(to_radians(angle)) * first_coords.bottom_right_x) + (sin(to_radians(angle)) * first_coords.bottom_right_y);

        //CHANGE COORDINATES
    first->setCoords( newx_first_tl, newy_first_tl, newx_first_tl + tetro_size,newy_first_tl - tetro_size);


        //SECOND SQUARE
    rect_coords second_coords = coords["second"];

    int newx_second_tl = (cos(to_radians(angle)) * second_coords.top_left_x) - (sin(to_radians(angle)) * second_coords.top_left_y);
    int newy_second_tl = (sin(to_radians(angle)) * second_coords.top_left_x) + (cos(to_radians(angle)) * second_coords.top_left_y);

        //CHANGE COORDINATES 
    second->setCoords(newx_second_tl, newy_second_tl, newx_second_tl - tetro_size, newy_second_tl + tetro_size);

first and second are QRect types. rect_coords is just a struct with four ints in it, that store the coordinates of the squares.

The first square and second square calculations are different, as I was playing around trying to figure it out.

I hope someone can help me figure this out?

(Yes, I can do this much simpler, but I'm trying to learn from this)

解决方案

It seems more like a math question than a programming question. Just plug in values like 90 degrees for the angle to figure this out. For 90 degrees, a point (x,y) is mapped to (-y, x). You probably don't want to rotate around the origin but around a certain pivot point c.x, c.y. For that you need to translate first, then rotate, then translate back:

(x,y) := (x-c.x, y-c.y) // translate into coo system w/ origin at c
(x,y) := (-y, x)        // rotate
(x,y) := (x+c.x, y+c.y) // translate into original coo system

这篇关于在运行时旋转俄罗斯方块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆