DEV Community

海前 王
海前 王

Posted on

归一化

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <limits>
#include <sstream>

struct Vertex {
    float x, y, z;
};

std::vector<Vertex> LoadOBJ(const std::string& filename, std::vector<std::vector<int>>& faces) {
    std::ifstream file(filename);
    std::vector<Vertex> vertices;
    std::string line;

    if (!file.is_open()) {
        std::cerr << "Error opening file." << std::endl;
        return vertices;
    }

    while (std::getline(file, line)) {
        std::istringstream ss(line);
        std::string type;
        ss >> type;

        if (type == "v") {
            Vertex v;
            ss >> v.x >> v.y >> v.z;
            vertices.push_back(v);
        } else if (type == "f") {
            std::vector<int> face;
            int index;
            while (ss >> index) {
                face.push_back(index - 1); // OBJ indices start from 1
            }
            faces.push_back(face);
        }
    }

    return vertices;
}

void ComputeBoundingBox(const std::vector<Vertex>& vertices, Vertex& minVertex, Vertex& maxVertex) {
    minVertex = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
    maxVertex = { std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest() };

    for (const Vertex& v : vertices) {
        if (v.x < minVertex.x) minVertex.x = v.x;
        if (v.y < minVertex.y) minVertex.y = v.y;
        if (v.z < minVertex.z) minVertex.z = v.z;

        if (v.x > maxVertex.x) maxVertex.x = v.x;
        if (v.y > maxVertex.y) maxVertex.y = v.y;
        if (v.z > maxVertex.z) maxVertex.z = v.z;
    }
}

void NormalizeVertices(std::vector<Vertex>& vertices, const Vertex& minVertex, const Vertex& maxVertex) {
    for (Vertex& v : vertices) {
        v.x = (v.x - minVertex.x) / (maxVertex.x - minVertex.x);
        v.y = (v.y - minVertex.y) / (maxVertex.y - minVertex.y);
        v.z = (v.z - minVertex.z) / (maxVertex.z - minVertex.z);
    }
}

int main() {
    std::vector<Vertex> vertices;
    std::vector<std::vector<int>> faces;

    // Load the OBJ file
    vertices = LoadOBJ("model.obj", faces);

    if (vertices.empty()) {
        std::cerr << "No vertices loaded." << std::endl;
        return 1;
    }

    // Compute bounding box
    Vertex minVertex, maxVertex;
    ComputeBoundingBox(vertices, minVertex, maxVertex);

    // Normalize vertices
    NormalizeVertices(vertices, minVertex, maxVertex);

    std::cout << "Bounding box min: (" << minVertex.x << ", " << minVertex.y << ", " << minVertex.z << ")" << std::endl;
    std::cout << "Bounding box max: (" << maxVertex.x << ", " << maxVertex.y << ", " << maxVertex.z << ")" << std::endl;

    std::cout << "Vertices normalized:" << std::endl;
    for (const Vertex& v : vertices) {
        std::cout << "(" << v.x << ", " << v.y << ", " << v.z << ")" << std::endl;
    }

    return 0;
}
#include <windows.h>
#include <vector>
#include <limits>

const wchar_t CLASS_NAME[] = L"Sample Window Class";

struct Vertex {
    float x, y, z;
};

// 示例归一化顶点数据
std::vector<Vertex> normalizedVertices = {
    {0.1f, 0.1f, 0.0f},
    {0.9f, 0.1f, 0.0f},
    {0.9f, 0.9f, 0.0f},
    {0.1f, 0.9f, 0.0f}
};

// 窗口过程函数
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    static HDC hdc;

    switch (uMsg) {
    case WM_CREATE:
        hdc = GetDC(hwnd);
        break;

    case WM_PAINT: {
        PAINTSTRUCT ps;
        HDC hdcMem = BeginPaint(hwnd, &ps);

        // 填充背景色
        RECT rect;
        GetClientRect(hwnd, &rect);
        HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255)); // 创建白色画刷
        FillRect(hdcMem, &rect, hBrush); // 用白色填充背景
        DeleteObject(hBrush); // 释放画刷对象

        // 绘制归一化点
        for (const Vertex& v : normalizedVertices) {
            int x = static_cast<int>(v.x * (rect.right - rect.left)); // 映射到窗口宽度
            int y = static_cast<int>(v.y * (rect.bottom - rect.top)); // 映射到窗口高度
            Ellipse(hdcMem, x - 5, y - 5, x + 5, y + 5); // 绘制圆点
        }

        EndPaint(hwnd, &ps);
        break;
    }

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
    // 注册窗口类
    WNDCLASS wc = { };
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    RegisterClass(&wc);

    // 创建窗口
    HWND hwnd = CreateWindowEx(
        0, CLASS_NAME, L"Sample Window",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
        NULL, NULL, hInstance, NULL
    );

    if (hwnd == NULL) {
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 运行消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)