首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

3D 數學庫極簡實現:矩陣平移、縮放、旋轉、投影 (C 語言)

     編輯:關於C語言

標頭檔 (vmath.h)


#ifndef _VMATH_H
#define _VMATH_H

#ifdef __cplusplus
extern "C" {
#endif

typedef float Matrix44f[16]; // 列主序 (OpenGL 相容)

void translate(Matrix44f M, float x, float y, float z);
void scale(Matrix44f M, float x, float y, float z);
void rotateX(Matrix44f M, float radian);
void rotateY(Matrix44f M, float radian);
void rotateZ(Matrix44f M, float radian);
void rotateXYZ(Matrix44f M, float radian, float x, float y, float z); // 任意軸旋轉 (待實作)
void perspectiveFrustum(Matrix44f M, float left, float right, float top, float bottom, float near, float far);
void orthoPerspect(Matrix44f M, float left, float right, float top, float bottom, float near, float far);

#ifdef __cplusplus
}
#endif
#endif

實作檔 (vmath.c)


#include 
#include 
#include 
#include "vmath.h"

static inline void mat44_identity(Matrix44f M) {
    memset(M, 0, 16 * sizeof(float));
    M[0] = M[5] = M[10] = M[15] = 1.0f;
}

void translate(Matrix44f M, float x, float y, float z) {
    mat44_identity(M);
    M[12] = x; M[13] = y; M[14] = z; // 列主序:第 4 列為平移
}

void scale(Matrix44f M, float x, float y, float z) {
    mat44_identity(M);
    M[0] = x; M[5] = y; M[10] = z;
}

void rotateX(Matrix44f M, float rad) {
    mat44_identity(M);
    float c = cosf(rad), s = sinf(rad);
    M[5] = c;   M[6] = s;
    M[9] = -s;  M[10] = c;
}

void rotateY(Matrix44f M, float rad) {
    mat44_identity(M);
    float c = cosf(rad), s = sinf(rad);
    M[0] = c;   M[2] = -s;
    M[8] = s;   M[10] = c;
}

void rotateZ(Matrix44f M, float rad) {
    mat44_identity(M);
    float c = cosf(rad), s = sinf(rad);
    M[0] = c;   M[1] = -s;
    M[4] = s;   M[5] = c;
}

void perspectiveFrustum(Matrix44f M, float l, float r, float t, float b, float n, float f) {
    memset(M, 0, 16 * sizeof(float));
    M[0] = 2*n/(r-l);  M[4] = 0;          M[8] = (r+l)/(r-l);  M[12] = 0;
    M[1] = 0;          M[5] = 2*n/(t-b);  M[9] = (t+b)/(t-b);  M[13] = 0;
    M[2] = 0;          M[6] = 0;          M[10] = (f+n)/(n-f); M[14] = 2*f*n/(n-f);
    M[3] = 0;          M[7] = 0;          M[11] = -1;          M[15] = 0;
}

void orthoPerspect(Matrix44f M, float l, float r, float t, float b, float n, float f) {
    memset(M, 0, 16 * sizeof(float));
    M[0] = 2/(r-l);  M[4] = 0;         M[8] = 0;           M[12] = -(r+l)/(r-l);
    M[1] = 0;        M[5] = 2/(t-b);   M[9] = 0;           M[13] = -(t+b)/(t-b);
    M[2] = 0;        M[6] = 0;         M[10] = -2/(f-n);   M[14] = -(f+n)/(f-n);
    M[3] = 0;        M[7] = 0;         M[11] = 0;          M[15] = 1;
}

矩陣佈局說明 (列主序 Column-Major)

索引:     0  4  8  12
           1  5  9  13
           2  6  10 14
           3  7  11 15

OpenGL glUniformMatrix4fv(..., GL_FALSE, M) 期望列主序。
平移分量位於 M[12], M[13], M[14]。

使用範例


Matrix44f model, view, proj, mvp;
translate(model, 1.0f, 2.0f, -5.0f);
rotateY(model, 0.5f);
scale(model, 2.0f, 2.0f, 2.0f);

perspectiveFrustum(proj, -1, 1, -1, 1, 1, 100);
// mvp = proj * view * model (需自行實作矩陣乘法)

待補充功能

  • rotateXYZ:羅德里格斯旋轉公式實現任意軸旋轉
  • mat44_mul、mat44_inverse、mat44_transpose
  • 向量運算 (點積、叉積、正規化)
  • 四元數 (Quaternion) 支援球面線性插值 (SLERP)
  • SIMD 優化 (SSE/AVX/NEON)

編譯靜態庫


gcc -c vmath.c -o vmath.o -O2 -march=native
ar rcs libvmath.a vmath.o
# 使用:gcc main.c -lvmath -L.
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved