提问者:小点点

我如何利用同质变换在openGL中渲染一个4D对象?


我想尝试制作一款利用4D横截面运动的游戏。我反复查看,但找不到任何提供完整清晰代码的答案 - 我发现最接近的是[我应该如何在opengl中处理(变形)4D对象?“它包含我需要的内容,但是,在尝试使用代码时,并非所有架构都得到了清晰的描述,例如包含5x5矩阵的文件。


共1个答案

匿名用户

4D 转印器

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

它使用nd_math.h internally。并且基本上反映了我的3D repo课程,基于我多年来获得的4x4同质变换矩阵的所有知识。repo本身是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相关的内容(文件访问)移植到环境中。