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)

Heroku

This site is powered by Heroku

Heroku was created by developers, for developers. Get started today and find out why Heroku has been the platform of choice for brands like DEV for over a decade.

Sign Up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay