如何使用同质变换在 openGL 中渲染 4D 对象?

How do I render a 4D object in openGL utilizing homogenous transforms?

我想尝试制作一款利用 4D 横截面移动的游戏。我反复查看,但找不到任何提供完整和清晰代码的答案 - 我找到的最接近的是 [ 其中包含我需要的内容,但是,在尝试使用代码时,并未清楚地描述所有架构,例如包含 5x5 矩阵的文件。

4D Reper

我之前没有 post 因为它不适合 30KByte 的限制以及我的其他答案......而且它只是矩阵的基本使用,这对于制作 3D 的人来说应该是显而易见的或更高维向量 gfx ...

它使用了 internaly. And basically reflects my 3D reper class based on all the knowledge of 我这些年的收获。 reper 本身是 class,它存储单个累积齐次矩阵及其倒置矩阵,并自我修复以保持基向量的正交正态性。

//---------------------------------------------------------------------------
//--- Reper 4D: ver 1.000 ---------------------------------------------------
//---------------------------------------------------------------------------
#ifndef _reper4D_h
#define _reper4D_h
//---------------------------------------------------------------------------
#include "nd_math.h"
//---------------------------------------------------------------------------
const double pi   =    M_PI;
const double pi2  =2.0*M_PI;
const double pipol=0.5*M_PI;
const double deg=M_PI/180.0;
const double rad=180.0/M_PI;
const int _reper_max_cnt=16;
//---------------------------------------------------------------------------
class reper4D
    {
/*  xx yx zx wx x0
    xy yy zy wy y0
    xz yz zz wz z0
    xw yw zw ww w0
     0  0  0  0  1  */

public:
    matrix<5> rep,inv;  // 4D uniform 5x5 transform matrix direct, inverse
    int     _rep,_inv;  // is actual ?
    int     cnt;        // dir operation counter

    reper4D()   { reset(); }
    reper4D(reper4D& a) { *this=a; }
    ~reper4D()  {}
    reper4D* operator = (const reper4D *a) { *this=*a; return this; }
    //reper4D* operator = (const reper4D &a) { ...copy... return this; }

    void reset() { rep.unit(); inv.unit(); _rep=1; _inv=1; cnt=0; orto(1); }
    void use_rep();
    void use_inv();
    void use_all();
    void orto(int test=0);                      // kolmost ak treba (podla cnt,alebo hned ak test!=0)
    void g2l    (vector<4> &l,vector<4> &g);    // global xyzw -> local xyzw
    void l2g    (vector<4> &g,vector<4> &l);    // global xyzw <- local xyzw
    void g2l_dir(vector<4> &l,vector<4> &g);    // global xyzw -> local xyzw  , only direction change
    void l2g_dir(vector<4> &g,vector<4> &l);    // global xyzw <- local xyzw  , only direction change
    void g2l_rep(reper4D &l,reper4D g);
    void l2g_rep(reper4D &g,reper4D l);
    void axisx_get(vector<4> &p);
    void axisx_set(vector<4> &p);
    void axisy_get(vector<4> &p);
    void axisy_set(vector<4> &p);
    void axisz_get(vector<4> &p);
    void axisz_set(vector<4> &p);
    void axisw_get(vector<4> &p);
    void axisw_set(vector<4> &p);
    void lpos_get (vector<4> &p);           // get origin in local xyzw (vzdy 0,0,0)
    void lpos_set (vector<4> &p);           // set origin in local xyzw
    void gpos_get (vector<4> &p);           // get origin in global xyzw
    void gpos_set (vector<4> &p);           // set origin in global xyzw
    void gpos_add (vector<4> &p);           // move origin in global xyzw
    void gpos_sub (vector<4> &p);           // move origin in global xyzw

    void rot_rnd();                             // random orientation
    // local rotations paralel to hyper plane
    void lrot_xy(double ang);
    void lrot_yz(double ang);
    void lrot_zx(double ang);
    void lrot_xw(double ang);
    void lrot_yw(double ang);
    void lrot_zw(double ang);
    // global rotations paralel to hyper plane
    void grot_xy(double ang);
    void grot_yz(double ang);
    void grot_zx(double ang);
    void grot_xw(double ang);
    void grot_yw(double ang);
    void grot_zw(double ang);

    void rep2rep(reper4D r0,reper4D r1);        // this=r1<<r0
    void rep_rep(reper4D r0,reper4D r1);        // this=r1>>r0

    void repset(matrix<5> &m);
    void invset(matrix<5> &m);
    void repget(matrix<5> &m);
    void invget(matrix<5> &m);

    void mul_rep_mat(matrix<5> &m) { use_rep(); rep=rep*m; _inv=0; cnt++; orto(); }
    void mul_inv_mat(matrix<5> &m) { use_inv(); inv=inv*m; _rep=0; cnt++; orto(); }
    void mul_mat_rep(matrix<5> &m) { use_rep(); rep=m*rep; _inv=0; cnt++; orto(); }
    void mul_mat_inv(matrix<5> &m) { use_inv(); inv=m*inv; _rep=0; cnt++; orto(); }
    vector<4> mul_mat_vec    (matrix<5> &m,vector<4> &v);
    vector<4> mul_mat_vec_dir(matrix<5> &m,vector<4> &v);
    };
//---------------------------------------------------------------------------
void reper4D::use_rep() { if (!_rep) { rep=inv.inverse(); _rep=1; _inv=1; cnt++; orto(); }
                          if (!_rep) { rep=inv.inverse(); _rep=1; _inv=1; } }
void reper4D::use_inv() { if (!_inv) { inv=rep.inverse(); _rep=1; _inv=1; cnt++; orto(); }
                          if (!_inv) { inv=rep.inverse(); _rep=1; _inv=1; } }
void reper4D::use_all() { use_rep(); use_inv(); }
//---------------------------------------------------------------------------
void reper4D::orto(int test)
    {
    if ((cnt>=_reper_max_cnt)||(test))
        {
        use_rep();
        rep.orthonormal();
        _rep=1; _inv=0; cnt=0;
        }
    }
//---------------------------------------------------------------------------
void reper4D::g2l    (vector<4> &l,vector<4> &g) { use_inv(); l=mul_mat_vec(inv,g); }
void reper4D::l2g    (vector<4> &g,vector<4> &l) { use_rep(); g=mul_mat_vec(rep,l); }
void reper4D::g2l_dir(vector<4> &l,vector<4> &g) { use_inv(); l=mul_mat_vec_dir(inv,g); }
void reper4D::l2g_dir(vector<4> &g,vector<4> &l) { use_rep(); g=mul_mat_vec_dir(rep,l); }
//---------------------------------------------------------------------------
void reper4D::g2l_rep(reper4D &l,reper4D g)
    {
    vector<4> p;
    g.gpos_get(p);  g2l(p,p);     l.gpos_set(p);
    g.axisx_get(p); g2l_dir(p,p); l.axisx_set(p);
    g.axisy_get(p); g2l_dir(p,p); l.axisy_set(p);
    g.axisz_get(p); g2l_dir(p,p); l.axisz_set(p);
    g.axisw_get(p); g2l_dir(p,p); l.axisw_set(p);
    }
//---------------------------------------------------------------------------
void reper4D::l2g_rep(reper4D &g,reper4D l)
    {
    vector<4> p;
    l.gpos_get(p);  l2g(p,p);     g.gpos_set(p);
    l.axisx_get(p); l2g_dir(p,p); g.axisx_set(p);
    l.axisy_get(p); l2g_dir(p,p); g.axisy_set(p);
    l.axisz_get(p); l2g_dir(p,p); g.axisz_set(p);
    l.axisw_get(p); l2g_dir(p,p); g.axisw_set(p);
    }
//---------------------------------------------------------------------------
void reper4D::axisx_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][0];
    p[1]=rep[1][0];
    p[2]=rep[2][0];
    p[3]=rep[3][0];
    }
//---------------------------------------------------------------------------
void reper4D::axisx_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][0]=p[0];
    rep[1][0]=p[1];
    rep[2][0]=p[2];
    rep[3][0]=p[3];
    cnt=_reper_max_cnt;
    }
//---------------------------------------------------------------------------
void reper4D::axisy_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][1];
    p[1]=rep[1][1];
    p[2]=rep[2][1];
    p[3]=rep[3][1];
    }
//---------------------------------------------------------------------------
void reper4D::axisy_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][1]=p[0];
    rep[1][1]=p[1];
    rep[2][1]=p[2];
    rep[3][1]=p[3];
    cnt=_reper_max_cnt;
    }
//---------------------------------------------------------------------------
void reper4D::axisz_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][2];
    p[1]=rep[1][2];
    p[2]=rep[2][2];
    p[3]=rep[3][2];
    }
//---------------------------------------------------------------------------
void reper4D::axisz_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][2]=p[0];
    rep[1][2]=p[1];
    rep[2][2]=p[2];
    rep[3][2]=p[3];
    cnt=_reper_max_cnt;
    }
//---------------------------------------------------------------------------
void reper4D::axisw_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][3];
    p[1]=rep[1][3];
    p[2]=rep[2][3];
    p[3]=rep[3][3];
    }
//---------------------------------------------------------------------------
void reper4D::axisw_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][3]=p[0];
    rep[1][3]=p[1];
    rep[2][3]=p[2];
    rep[3][3]=p[3];
    cnt=_reper_max_cnt;
    }
//---------------------------------------------------------------------------
void reper4D::lpos_get(vector<4> &p)
    {
    p[0]=0;
    p[1]=0;
    p[2]=0;
    p[3]=0;
    }
//---------------------------------------------------------------------------
void reper4D::lpos_set(vector<4> &p)
    {
    vector<4> q;
    l2g(q,p);
    gpos_set(q);
    }
//---------------------------------------------------------------------------
void reper4D::gpos_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][4];
    p[1]=rep[1][4];
    p[2]=rep[2][4];
    p[3]=rep[3][4];
    orto();
    }
//---------------------------------------------------------------------------
void reper4D::gpos_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][4]=p[0];
    rep[1][4]=p[1];
    rep[2][4]=p[2];
    rep[3][4]=p[3];
    orto();
    }
//---------------------------------------------------------------------------
void reper4D::gpos_add(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][4]+=p[0];
    rep[1][4]+=p[1];
    rep[2][4]+=p[2];
    rep[3][4]+=p[3];
    orto();
    }
//---------------------------------------------------------------------------
void reper4D::gpos_sub(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][4]-=p[0];
    rep[1][4]-=p[1];
    rep[2][4]-=p[2];
    rep[3][4]-=p[3];
    orto();
    }
//---------------------------------------------------------------------------
void reper4D::rot_rnd()
    {
    int i,j;
    matrix<4> a;
    a.rnd();
    a.orthonormal();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_xy(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld( c , s ,0.0,0.0);
    b[1].ld(-s , c ,0.0,0.0);
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_yz(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0, c , s ,0.0);
    b[2].ld(0.0,-s , c ,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_zx(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld( c ,0.0,-s ,0.0);
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld( s ,0.0, c ,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_xw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld( c ,0.0,0.0, s );
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(-s ,0.0,0.0, c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_yw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0, c ,0.0,-s );
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(0.0, s ,0.0, c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_zw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld(0.0,0.0, c ,-s );
    b[3].ld(0.0,0.0, s , c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_xy(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld( c , s ,0.0,0.0);
    b[1].ld(-s , c ,0.0,0.0);
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_yz(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0, c , s ,0.0);
    b[2].ld(0.0,-s , c ,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_zx(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld( c ,0.0,-s ,0.0);
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld( s ,0.0, c ,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_xw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld( c ,0.0,0.0, s );
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(-s ,0.0,0.0, c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_yw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0, c ,0.0,-s );
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(0.0, s ,0.0, c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_zw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld(0.0,0.0, c ,-s );
    b[3].ld(0.0,0.0, s , c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::rep2rep(reper4D r0,reper4D r1)
    {
    reset();
    r0.use_inv();
    r1.use_inv();
    inv=r0.inv*r1.inv;
    rep=inv.inverse();
    _rep=1; _inv=1; orto(1);
    }
//---------------------------------------------------------------------------
void reper4D::rep_rep(reper4D r0,reper4D r1)
    {
    reset();
    r0.use_rep();
    r1.use_inv();
    inv=r0.rep*r1.inv;
    rep=inv.inverse();
    _rep=1; _inv=1; orto(1);
    }
//---------------------------------------------------------------------------
void reper4D::repset(matrix<5> &m) { rep=m; _rep=1; _inv=0; }
void reper4D::invset(matrix<5> &m) { inv=m; _rep=0; _inv=1; }
void reper4D::repget(matrix<5> &m) { use_rep(); m=rep; }
void reper4D::invget(matrix<5> &m) { use_inv(); m=inv; }
//---------------------------------------------------------------------------
vector<4> reper4D::mul_mat_vec(matrix<5> &m,vector<4> &v)
    {
    vector<4> p;
    p[0]=(m[0][0]*v[0])+(m[0][1]*v[1])+(m[0][2]*v[2])+(m[0][3]*v[3])+(m[0][4]);
    p[1]=(m[1][0]*v[0])+(m[1][1]*v[1])+(m[1][2]*v[2])+(m[1][3]*v[3])+(m[1][4]);
    p[2]=(m[2][0]*v[0])+(m[2][1]*v[1])+(m[2][2]*v[2])+(m[2][3]*v[3])+(m[2][4]);
    p[3]=(m[3][0]*v[0])+(m[3][1]*v[1])+(m[3][2]*v[2])+(m[3][3]*v[3])+(m[3][4]);
    return p;
    }
//---------------------------------------------------------------------------
vector<4> reper4D::mul_mat_vec_dir(matrix<5> &m,vector<4> &v)
    {
    vector<4> p;
    p[0]=(m[0][0]*v[0])+(m[0][1]*v[1])+(m[0][2]*v[2])+(m[0][3]*v[3]);
    p[1]=(m[1][0]*v[0])+(m[1][1]*v[1])+(m[1][2]*v[2])+(m[1][3]*v[3]);
    p[2]=(m[2][0]*v[0])+(m[2][1]*v[1])+(m[2][2]*v[2])+(m[2][3]*v[3]);
    p[3]=(m[3][0]*v[0])+(m[3][1]*v[1])+(m[3][2]*v[2])+(m[3][3]*v[2]);
    return p;
    }
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------

列表<>模板

它只是一个线性数组容器模板,具有自分配属性,专为多线程和快速列表操作而开发。但是我不能分享它的源代码,因为它是公司代码的一部分...

相反,这是一个模仿 API 的静态模板,因此您可以使用您可以使用的任何线性存储对其进行重新编码,例如 std::vector<> 或其他任何东西,或者只是将其与静态分配一起使用...

//---------------------------------------------------------------------------
//--- static list template class ver 3.00 ----------------------------------
//---------------------------------------------------------------------------
#ifndef _list_static_h
#define _list_static_h
/*---------------------------------------------------------------------------
    Template class/struct must contain these operators/functions to work properly:

    // all inline
    T(){}; T(T& a){ *this=a; }; ~T(){}; T* operator = (const T *a) { *this=*a; return this; }; /*T* operator = (const T &a) { ...copy... return this; };*/
/*
    // inline
    T()     {}
    T(T& a) { *this=a; }
    ~T()    {}
    T* operator = (const T *a) { *this=*a; return this; }
    //T* operator = (const T &a) { ...copy... return this; }

    // header
    T();
    T(T& a);
    ~T();
    T* operator = (const T *a);
    //T* operator = (const T &a);

    // body
T::T()      {}
T::T(T& a)  { *this=a; }
T::~T()     {}
T* T::operator = (const T *a) { *this=*a; return this; }
//T* T::operator = (const T &a) { ..copy... return this; }
//-------------------------------------------------------------------------*/
template <class T,int N=16> class List_static
        {
public: T       dat[N];                 // items array
        int     num,siz;                // items count,allocated size

        int     minsiz;                 // minimal array size
        int     element_size;           // initiate in constructor
        bool    enable_auto_shrink;     // automatic shrink after delete operation ?

        void (__closure *onrealloc)();  // realloc event

        List_static(int _allocate=N);
        ~List_static() { free(); }

        void operator = (const List_static<T> &a);
        T& operator[] (int i);

        void free();
        int  allocate(int _allocate);
        int  reallocate(int _allocate);
        int  shrink();                  // down alloc if possible

        int  ins(int ix);
        int  ins(int ix,T &a);
        int  ins(int ix,const T &a);
        int  del(int ix);
        int  qdel(int ix);
        int  ins_block(int ix,int sz);
        int  del_block(int ix,int sz);
        void shl(int d=1);
        void shr(int d=1);
        int  add() { return ins(num); }
        int  add(T &a) { return ins(num,a); }
        int  add(const T &a) { return ins(num,a); }
        int  add(List_static<T> &a);
        void reset();
        int  save_size();
        void save(int hnd);
        void load(int hnd);
        };
//---------------------------------------------------------------------------
template <class T,int N> List_static<T>::List_static(int _allocate)
        {
        onrealloc=NULL;
        element_size=sizeof(T);
        enable_auto_shrink=false;
        num=0;
        siz=N;
        minsiz=siz;
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::operator = (const List_static<T> &a)
        {
        int     i;
        reset();
        element_size       =a.element_size;
        enable_auto_shrink =a.enable_auto_shrink;
        minsiz             =a.minsiz;
        for (i=0;i<a.num;i++) add(a.dat[i]);
        }
//---------------------------------------------------------------------------
template <class T,int N> T& List_static<T>::operator[] (int i)
        {
        static T empty;
        if (i<   0) return empty;
        if (i>=num) return empty;
        return dat[i];
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::free()
        {
        num=0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::allocate(int _allocate)
        {
        if (_allocate<=siz) return 1; else return 0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::reallocate(int _allocate)
        {
        if (_allocate<=siz) return 1;
        else return 0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::shrink()
        {
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins(int ix)
        {
        int     i;
        if (num<0) num=0;
        if (ix<0) return 0;
        if (ix>num) return 0;
        if (num>=siz) return 0;
        if (ix<num)
         for (i=num;i>ix;i--)
          dat[i]=dat[i-1];
//      dat[ix]=;
        num++;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins(int ix,T &a)
        {
        int     i;
        if (num<0) num=0;
        if (ix<0) return 0;
        if (ix>num) return 0;
        if (num>=siz) return 0;
        if (ix<num)
         for (i=num;i>ix;i--)
          dat[i]=dat[i-1];
        dat[ix]=a;
        num++;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins(int ix,const T &a)
        {
        int     i;
        if (num<0) num=0;
        if (ix<0) return 0;
        if (ix>num) return 0;
        if (num>=siz) return 0;
        if (ix<num)
         for (i=num;i>ix;i--)
          dat[i]=dat[i-1];
        dat[ix]=a;
        num++;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::del(int ix)
        {
        int     i;
        if (num<=0) { num=0; return 0; }
        if (ix<0) return 0;
        if (ix>=num) return 0;
        num--;
        for (i=ix;i<num;i++)
         dat[i]=dat[i+1];
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::qdel(int ix)
        {
        int     i;
        if (num<=0) { num=0; return 0; }
        if (ix<0) return 0;
        if (ix>=num) return 0;
        if (ix<num-1)
         dat[ix]=dat[num-1];
        num--;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins_block(int ix,int sz)
        {
        int     i;
        if (num<0) num=0;
        if (sz<=0) return 0;
        if (ix<0) return 0;
        if (ix>num) return 0;
        if (num+sz>=siz) return 0;
        if (ix<num)
         for (i=num;i>ix;i--)
          dat[i+sz-1]=dat[i-1];
        num+=sz;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::del_block(int ix,int sz)
        {
        int     i;
        if (num<=0) { num=0; return 0; }
        if (sz<=0) return 0;
        if (ix<0) return 0;
        if (ix+sz>num) return 0;
        num-=sz;
        for (i=ix;i<num;i++)
         dat[i]=dat[i+sz];
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::shl(int d)
        {
        int     i;
        if (num<0) num=0;
        if (num<=d) return;
        if (siz<=d) return;
        for (i=0;i<num-d;i++)
         dat[i]=dat[i+d];
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::shr(int d)
        {
        int     i;
        if (num<0) num=0;
        if (num<=d) return;
        if (siz<=d) return;
        for (i=num-d-1;i>=0;i--)
         dat[i+d]=dat[i];
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::reset()
        {
        num=0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::add(List_static<T> &a)
        {
        int     i,n,q;
        q=num;
        n=a.num;
        for (i=0;i<n;i++) add(a.dat[i]);
        if (num==n+q) return 1;
        return 0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>:: save_size()
        {
        return 4+(num*element_size);
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>:: save(int hnd)
        {
        if (hnd<0) return;
        FileWrite(hnd,&num,4);
        FileWrite(hnd,dat,num*element_size);
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>:: load(int hnd)
        {
        int     i,n;
        if (hnd<0) return;
        FileRead(hnd,&n,4); if (n<0) n=0;
        allocate(n); num=n; if (num>siz) num=siz; if (num<0) num=0;
        FileRead(hnd,dat,num*element_size);
        n=n-num;
        if (n>0) FileSeek(hnd,n*element_size,1);
        }
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

并不是所有的东西都被使用,所以要么忽略你不需要的东西,要么将 VCL 相关的东西(文件访问)移植到你的环境中。