You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将屏幕坐标转换为位图坐标?附实现代码求助

问题分析与代码修正

咱们先明确核心需求:你要把180×180的位图,以屏幕坐标(120,120)为基准(看起来是要以这个点作为位图的中心),正确绘制到320×240的屏幕上,同时支持旋转。先看你现有代码里的几个关键问题:

1. 坐标映射逻辑完全搞反了

你当前计算relxrely是用位图尺寸除以屏幕尺寸,这会把屏幕坐标“缩小”到位图范围,但实际我们需要的是把位图的每个像素映射到屏幕的对应位置。如果屏幕上的(x,y)是位图的中心,那么屏幕上的绘制坐标应该直接基于这个中心偏移,不需要做反向缩放(除非你有额外的缩放需求,但你的描述里没提到)。

2. 位图像素索引错误

绝大多数位图是行优先存储的(先存第一行所有像素,再存第二行),所以正确的像素索引应该是rotY * w + rotX,你写的rotX*w + rotY是列优先的索引方式,会导致图像错乱。

3. 旋转后的绘制坐标错误

你当前用xgoal + iygoal +j设置屏幕像素位置,但xgoal的计算逻辑完全错误,应该直接基于屏幕中心坐标,计算每个位图像素对应的屏幕位置。


修正后的代码

// w, h: width and height of the image
// x, y: center position on the screen coordinates
void Rasterizer::DrawBitmap(int w, int h, int x, int y, float angle) {
    uint16_t pixel;
    float midX = w / 2.0f;
    float midY = h / 2.0f;
    float deltaX, deltaY;
    int rotX, rotY;
    int screenX, screenY;

    for (int i = 0; i < w; i++) {
        for (int j = 0; j < h; j++) {
            // 计算当前位图像素相对于位图中心的偏移
            deltaX = i - midX;
            deltaY = j - midY;

            // 应用旋转变换(如果旋转方向和预期相反,可调整公式里的正负号)
            rotX = static_cast<int>(midX + deltaX * cos(angle) - deltaY * sin(angle));
            rotY = static_cast<int>(midY + deltaX * sin(angle) + deltaY * cos(angle));

            // 确保旋转后的像素在位图范围内
            if (rotX >= 0 && rotX < w && rotY >= 0 && rotY < h) {
                // 计算该位图像素对应的屏幕坐标:屏幕中心 + 位图像素相对于中心的偏移
                screenX = x + (i - static_cast<int>(midX));
                screenY = y + (j - static_cast<int>(midY));

                // 可选:确保屏幕坐标在显示范围内,避免绘制到屏幕外
                if (screenX >= 0 && screenX < 320 && screenY >= 0 && screenY < 240) {
                    // 行优先的位图像素索引
                    pixel = bitmap[rotY * w + rotX];
                    SetPixel(screenX, screenY, pixel);
                }
            }
        }
    }
}

额外需求说明:屏幕坐标转位图坐标

如果你的核心需求是把屏幕上的(120,120)点转换为位图坐标(比如想知道这个屏幕点对应位图里的哪个像素),那逻辑是反过来的:计算屏幕点相对于位图屏幕中心的偏移,再映射到位图坐标系:

// 假设(x_screen, y_screen)是屏幕坐标,x/y是位图在屏幕上的中心坐标(即你传入的120,120)
int bitmapX = static_cast<int>(midX + (x_screen - x));
int bitmapY = static_cast<int>(midY + (y_screen - y));

只要bitmapXbitmapY在0w-1、0h-1范围内,就是对应的位图像素坐标。

内容的提问来源于stack exchange,提问作者andre

火山引擎 最新活动