SFML球体投影出现拉伸变形,求助问题原因及解决方法
问题分析与修复
你的球体出现左右凸起的核心原因是射线生成逻辑错误:代码中错误地将角度变量i、j直接加到了3D点的坐标上,导致每条射线的起点并非相机原点(0,0,0),而是偏移了一个与角度相关的数值,最终造成画面畸变。
关键错误点
射线坐标计算错误:
原代码中生成射线点的代码:S_Point((-cos(i) * l) + i - (PI / 2), (cos(j) * l) - j + (PI / 2), sin(j) * l)这里的
+ i - (PI/2)和- j + (PI/2)完全是多余的,属于将角度值错误地当作位置偏移量,破坏了射线从相机原点出发的逻辑。MUL宏未定义:代码中使用了s_l (6 * MUL)和s_h (6 * MUL),但未定义MUL,会导致编译错误。
修复后的完整代码
#include <stdio.h> #include <math.h> #include "SFML/Graphics.hpp" using namespace sf; #define MUL 100 // 补充定义缩放因子,可根据需求调整 #define s_l (6 * MUL) #define s_h (6 * MUL) // 3d Point in space struct S_Point { double x, y, z; }; // Distance from a point to another point double p_dist(S_Point p, S_Point s) { return sqrt(pow(s.x - p.x, 2) + pow(s.y - p.y, 2) + pow(s.z - p.z, 2)); } int main() { // Main Window RenderWindow window(VideoMode(s_l, s_h), "Conecept", Style::Default); // Sphere position (0,0,100) S_Point sphere{0, 0, 100}; Image image; image.create(s_l, s_h, Color::Black); Texture texture; texture.create(s_l, s_h); Sprite pic; { const double leng = 200.0; const double PI = 3.14159265358979323846; // 水平方向角度:从PI/3到2PI/3(覆盖60度视场) const double angle_step_x = (2 * PI / 3 - PI / 3) / (s_l - 1); // 垂直方向角度:从PI/3到2PI/3 const double angle_step_y = (2 * PI / 3 - PI / 3) / (s_h - 1); for (int x = 0; x < s_l; x++) { double i = PI / 3 + x * angle_step_x; for (int y = 0; y < s_h; y++) { double j = PI / 3 + y * angle_step_y; for (double l = 0; l <= leng; l += 1.0) { // 修正射线生成:从相机原点(0,0,0)出发,沿角度i、j方向延伸 S_Point ray_point{ -cos(i) * l, cos(j) * l, sin(j) * l }; if (p_dist(ray_point, sphere) < 50.0) { // 根据距离设置灰度值 uint8_t brightness = static_cast<uint8_t>((-255.0 / leng * l) + 255); image.setPixel(x, y, Color(brightness, brightness, brightness, 255)); break; } } } } } printf("Done!\n"); texture.update(image); pic.setTexture(texture); // Main Window Loop while (window.isOpen()) { Event event; while (window.pollEvent(event)) { if (event.type == Event::Closed) { window.close(); } } window.clear(); window.draw(pic); window.display(); } return 0; }
额外优化说明
- 将循环变量调整为先遍历像素索引,再计算对应角度,逻辑更清晰,避免原代码中
x++和y++与角度循环绑定的潜在问题。 - 显式计算角度步长,确保像素与角度的映射完全均匀。
- 修正了
Colour为SFML标准的Color(原代码中拼写错误,部分编译器可能不兼容)。 - 将亮度计算转为浮点运算后再强制类型转换,避免整数除法导致的精度丢失。
内容的提问来源于stack exchange,提问作者ItsThatSpicymeme
相关产品推荐
相关产品推荐

