gpt4 book ai didi

在正方形上使用时的 C++ 旋转矩阵问题

转载 作者:可可西里 更新时间:2023-11-01 11:28:27 25 4
gpt4 key购买 nike

我正在尝试在 C++ 中应用一个旋转矩阵,它围绕指定的原点将正方形的所有点旋转指定的度数。问题在于它基于 win32 控制台,因此每个点都必须对应一对整数,而不是浮点值。如下图所示,旋转正方形的整体形状与预期结果一致,但其中存在多个“孔”。

这是我的源代码:

#include <iostream>
#include <cmath>

using namespace std;

enum {W = 50, H = 50, S = 25}; //Width, Height, Square size

struct Vector2i
{
int x;
int y;
Vector2i() {}
Vector2i(int _x, int _y) : x(_x), y(_y) {}
};

struct Square
{
bool Data[W][H];
Vector2i Origin = Vector2i(W / 2, H / 2);

void clear() {
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x)
Data[x][y] = false;
}
}

void setSquare() {
for (int y = H / 2 - S / 2; y < H / 2 + S / 2; ++y) {
for (int x = W / 2 - S / 2; x < W / 2 + S / 2; ++x)
Data[x][y] = true;
}
}

void draw() {
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x) {
if (y == Origin.y && x == Origin.x) std::cout << '+'; //Marks the origin
else if (Data[x][y]) std::cout << 'X';
else std::cout << '.';
}
std::cout << '\n';
}
}
};

Vector2i newPos(Vector2i old, double theta) {
theta *= 3.14159265d / 180.d; //Converting from degrees to radians

int X = ceil(cos(theta) * old.x - sin(theta) * old.y);
int Y = ceil(sin(theta) * old.x + cos(theta) * old.y);

return Vector2i(X, Y);
}

int main()
{
cout << "Enter an angle (in degrees): ";
double angle = 0;
cin >> angle;

Square One;
One.clear();
One.setSquare();
One.draw();

Square Two;
Two.clear();

///Draw the rotated square as the second square
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x) {
if (One.Data[x][y]) {
Vector2i finalVec = newPos(Vector2i(x - One.Origin.x,
y - One.Origin.y), angle);
Two.Data[finalVec.x + One.Origin.x][finalVec.y + One.Origin.y] = true;
}
}
}

///Copy the second square back into the first
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x)
One.Data[x][y] = Two.Data[x][y];
}

One.draw();

return 0;
}

这是由于 newPos() 函数的准确性造成的,还是由于舍入到 int 值导致的?

此外,有没有办法解决这个问题或预测漏洞的位置?

Before rotation After rotation, with holes.

编辑:已解决!

根据 infgeoax 向后工作的建议,我创建了一个函数来计算原始位置。我会把增强的代码留在这里,以防将来有人遇到类似的问题(感谢大家的帮助![特别是 infgeoax,用于脑波]):

#include <iostream>
#include <cmath>

using namespace std;

enum {W = 50, H = 50, S = 25};

struct Vector2i
{
int x;
int y;
Vector2i() {}
Vector2i(int _x, int _y) : x(_x), y(_y) {}
};

struct Square
{
bool Data[W][H];;
Vector2i Origin = Vector2i(W / 2, H / 2);

void clear() {
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x)
Data[x][y] = false;
}
}

void setSquare() {
for (int y = H / 2 - S / 2; y < H / 2 + S / 2; ++y) {
for (int x = W / 2 - S / 2; x < W / 2 + S / 2; ++x)
Data[x][y] = true;
}
}

void draw() {
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x) {
if (y == Origin.y && x == Origin.x) std::cout << '+'; //Marks the origin
else if (Data[x][y]) std::cout << 'X';
else std::cout << '.';
}
std::cout << '\n';
}
}
};

Vector2i oldPos(Vector2i new_, float theta) {
theta *= 3.14159265f / 180.f; //Converting from degrees to radians
return Vector2i(new_.x * cosf(theta) + new_.y * sinf(theta) + 0.5f,
new_.y * cosf(theta) - new_.x * sinf(theta) + 0.5f);
}

int main()
{
cout << "Enter an angle (in degrees): ";
float angle = 0;
cin >> angle;

Square One;
One.clear();
One.setSquare();
One.draw();

Square Two;
Two.clear();

for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x) {
Vector2i vec = oldPos(Vector2i(x - One.Origin.x, y - One.Origin.y), angle);
vec.x += One.Origin.x;
vec.y += One.Origin.y;
if (vec.x >= 0 && vec.x < W && vec.y >= 0 && vec.y < H)
Two.Data[x][y] = One.Data[vec.x][vec.y];
}
}

Two.draw();

return 0;
}

最佳答案

您的问题与您开发的是控制台应用程序还是 GUI 应用程序无关。图像作为像素矩阵存储和处理。旋转图像时,特定像素的结果位置通常不是整数。

想法是反过来。

  1. 计算旋转正方形的四个角。
  2. 对于旋转正方形中的每个位置(像素),通过将其旋转回原始正方形来计算其颜色。

关于在正方形上使用时的 C++ 旋转矩阵问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27715314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com