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

3D 數學庫簡易實作(C 語言):vmath.h / vmath.c

     編輯:關於C

簡介

本文提供一個輕量級的 3D 數學庫 vmath,以 C 語言實現常用的 4x4 矩陣運算:平移、縮放、旋轉(X/Y/Z 軸)、透視投影與正交投影。採用列主序(Column-major)儲存,適合直接傳遞給 OpenGL glUniformMatrix4fv。

頭文件 vmath.h

#ifndef _VMATH_H
#define _VMATH_H

#ifdef __cplusplus
extern "C" {
#endif

typedef float Matrix44f[16];

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 核心函數

1. 基礎變換矩陣

void translate(Matrix44f M, float x, float y, float z) {
    for (int i=0; i<16; i++) M[i]=0;
    M[3]=x; M[7]=y; M[11]=z; M[15]=1.0;
}

void scale(Matrix44f M, float x, float y, float z) {
    for (int i=0; i<16; i++) M[i]=0;
    M[0]=x; M[5]=y; M[10]=z; M[15]=1.0;
}

void rotateX(Matrix44f M, float rad) {
    for (int i=0; i<16; i++) M[i]=0;
    M[0]=1; M[5]=cos(rad); M[6]=sin(rad);
    M[9]=-sin(rad); M[10]=cos(rad); M[15]=1;
}
// rotateY, rotateZ 同理...

2. 透視投影矩陣 (frustum)

void perspectiveFrustum(Matrix44f M, float l, float r,
                        float t, float b, float n, float f) {
    for (int i=0; i<16; i++) M[i]=0;
    M[0] = 2*n/(r-l);
    M[2] = (r+l)/(r-l);
    M[5] = 2*n/(t-b);
    M[6] = (t+b)/(t-b);
    M[10] = (n+f)/(n-f);
    M[11] = 2*n*f/(n-f);
    M[14] = -1;
}

3. 正交投影矩陣

void orthoPerspect(Matrix44f M, float l, float r,
                   float t, float b, float n, float f) {
    for (int i=0; i<16; i++) M[i]=0;
    M[0] = 2/(r-l);  M[3] = (l+r)/(l-r);
    M[5] = 2/(t-b);  M[7] = (b+t)/(b-t);
    M[10] = 2/(n-f); M[11] = (n+f)/(f-n);
    M[15] = 1;
}

使用範例

Matrix44f proj, view, model, mvp;
perspectiveFrustum(proj, -1, 1, 1, -1, 1, 100);
translate(view, 0, 0, -5);
rotateY(model, 0.5f);
// mvp = proj * view * model  (需自行實現矩陣乘法)
glUniformMatrix4fv(loc, 1, GL_TRUE, mvp);

編譯與連結

gcc -c vmath.c -o vmath.o
ar rcs libvmath.a vmath.o
# 專案中連結 -lvmath

作者提供 VC++2008 編譯好的靜態庫下載。註:rotateXYZ(繞任意軸旋轉)尚未實作。

矩陣索引對照表(列主序)

0123
0M[0]M[4]M[8]M[12]
1M[1]M[5]M[9]M[13]
2M[2]M[6]M[10]M[14]
3M[3]M[7]M[11]M[15]

平移分量位於 M[12], M[13], M[14](即第 4 行),符合 OpenGL 慣例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved