C++:空间坐标映射到球面坐标/全景图

记录一下。

描述:有一张全景图,和一个模型,需要求模型中每个点映射到全景图中所对应的坐标。

本来想用PPT画图,嫌太麻烦了,就手画传图了。

 

 

 

 

void calcSphereUV(const Vec3f& V)
{
    //BasePoint为球心坐标
    float x = V[0] - BasePoint[0];
    float y = V[1] - BasePoint[1];
    float z = V[2] - BasePoint[2];
    float R = sqrt(x * x + y * y + z * z);
    float theta = asin(z / R);//-90~90

    float phi = atan(y / x);
    if (x >= 0)
    {
        phi = phi + (3.0 / 2.0 * PI);
    }
    else if (x < 0)
    {
        phi = PI / 2.0 + phi;
    }

    theta = PI / 2.0 - theta;
    //cout << "theta=" << theta / PI * 180.0 << endl;
    //cout << "phi=" << phi / PI * 180.0 << endl;
    Vec2f tmp;
    tmp[0] = phi / PI / 2.0;
    tmp[1] = theta / PI;
    //cout << "U = " << tmp[0] << endl;
    //cout << "V = " << tmp[1] << endl << endl;
}

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现文字映射到VR全景图片任意位置,需要使用以下步骤: 1. 将全景图片加载到内存中。可以使用OpenCV库加载图片。 2. 创建一个虚拟环境,例如OpenGL场景,用于展示全景图片和文字。 3. 将文本转换为纹理,并将其加载到OpenGL中。 4. 将全景图片和文字纹理映射到OpenGL场景中。可以使用OpenGL的纹理映射功能来实现。 下面是一个简单的示例代码,用于将文字映射到VR全景图片的任意位置。这里我们使用OpenGL来创建虚拟环境,并使用FreeType库将文本转换为纹理。 ```c++ #include <iostream> #include <GL/glew.h> #include <GLFW/glfw3.h> #include <opencv2/opencv.hpp> #include <ft2build.h> #include FT_FREETYPE_H using namespace std; using namespace cv; // 顶点着色器 const char* vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "layout (location = 1) in vec2 aTexCoord;\n" "out vec2 TexCoord;\n" "void main()\n" "{\n" " gl_Position = vec4(aPos, 1.0);\n" " TexCoord = vec2(aTexCoord.x, aTexCoord.y);\n" "}\0"; // 片段着色器 const char* fragmentShaderSource = "#version 330 core\n" "in vec2 TexCoord;\n" "out vec4 FragColor;\n" "uniform sampler2D ourTexture;\n" "void main()\n" "{\n" " FragColor = texture(ourTexture, TexCoord);\n" "}\n\0"; // 文本渲染器 class TextRenderer { public: TextRenderer(const char* fontPath, int fontSize) { FT_Init_FreeType(&ft); FT_New_Face(ft, fontPath, 0, &face); FT_Set_Pixel_Sizes(face, 0, fontSize); glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_2D, texId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } void renderText(const char* text, float x, float y, float sx, float sy) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, buffer); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texId); glUniform1i(glGetUniformLocation(shaderProgram, "ourTexture"), 0); GLfloat vertices[] = { x, y + height * sy, 0.0f, 0.0f, x + width * sx, y + height * sy, 1.0f, 0.0f, x + width * sx, y, 1.0f, 1.0f, x, y, 0.0f, 1.0f }; unsigned int indices[] = { 0, 1, 2, 2, 3, 0 }; GLuint VAO, VBO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); } void setText(const char* text) { FT_GlyphSlot g = face->glyph; int w = 0, h = 0; for (int i = 0; i < strlen(text); i++) { FT_Load_Char(face, text[i], FT_LOAD_RENDER); w += g->bitmap.width; h = max(h, g->bitmap.rows); } width = w; height = h; buffer = new unsigned char[width * height]; int x = 0; for (int i = 0; i < strlen(text); i++) { FT_Load_Char(face, text[i], FT_LOAD_RENDER); for (int j = 0; j < g->bitmap.width; j++) { for (int k = 0; k < g->bitmap.rows; k++) { buffer[(k + g->bitmap_top) * width + (x + j)] = g->bitmap.buffer[k * g->bitmap.width + j]; } } x += g->bitmap.width; } } private: FT_Library ft; FT_Face face; unsigned char* buffer; GLuint texId; int width, height; }; int main() { // 初始化OpenGL glfwInit(); GLFWwindow* window = glfwCreateWindow(800, 600, "Text on VR panorama", NULL, NULL); glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; glewInit(); // 加载全景图片 Mat img = imread("panorama.jpg"); if (img.empty()) { cout << "Failed to load image!" << endl; return -1; } // 创建文本渲染器 TextRenderer renderer("arial.ttf", 48); // 创建着色器程序 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // 加载图片到OpenGL中 GLuint textureId; glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.cols, img.rows, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, img.ptr()); // 渲染循环 while (!glfwWindowShouldClose(window)) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); GLfloat vertices[] = { // 顶点坐标 纹理坐标 -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, }; unsigned int indices[] = { 0, 1, 2, 2, 3, 0 }; GLuint VAO, VBO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureId); glUniform1i(glGetUniformLocation(shaderProgram, "ourTexture"), 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // 渲染文本 renderer.setText("Hello, world!"); renderer.renderText("Hello, world!", 400, 300, 0.5, 0.5); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; } ``` 这是一个简单的示例代码,演示了如何将文本映射到VR全景图片的任意位置。您可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值