如何将屏幕坐标转换为位图坐标?附实现代码求助
问题分析与代码修正
咱们先明确核心需求:你要把180×180的位图,以屏幕坐标(120,120)为基准(看起来是要以这个点作为位图的中心),正确绘制到320×240的屏幕上,同时支持旋转。先看你现有代码里的几个关键问题:
1. 坐标映射逻辑完全搞反了
你当前计算relx和rely是用位图尺寸除以屏幕尺寸,这会把屏幕坐标“缩小”到位图范围,但实际我们需要的是把位图的每个像素映射到屏幕的对应位置。如果屏幕上的(x,y)是位图的中心,那么屏幕上的绘制坐标应该直接基于这个中心偏移,不需要做反向缩放(除非你有额外的缩放需求,但你的描述里没提到)。
2. 位图像素索引错误
绝大多数位图是行优先存储的(先存第一行所有像素,再存第二行),所以正确的像素索引应该是rotY * w + rotX,你写的rotX*w + rotY是列优先的索引方式,会导致图像错乱。
3. 旋转后的绘制坐标错误
你当前用xgoal + i和ygoal +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));
只要bitmapX和bitmapY在0w-1、0h-1范围内,就是对应的位图像素坐标。
内容的提问来源于stack exchange,提问作者andre




