Как визуализировать объект 4D в openGL с использованием однородных преобразований? - PullRequest
0 голосов
/ 19 июня 2020

Я хочу попробовать сделать игру, в которой используется движение через 4D-сечения. Я неоднократно просматривал, но не могу найти никаких ответов, представляющих полный и понятный код - ближайший, который я нашел, был [ как мне обрабатывать (преобразовывать) 4D-объекты в opengl? , который содержит то, что мне нужно, однако, на пытаясь использовать код, не вся архитектура была описана четко, например, файл, содержащий матрицу 5x5.

1 Ответ

0 голосов
/ 19 июня 2020

4D Reper

Я не публиковал его раньше, так как он не помещался в лимит 30 КБ вместе с остальными моими ответами ... А также его просто базовое c использование матриц, которые должны быть очевидны любому, кто создает трехмерный вектор или вектор более высокой размерности gfx ...

Он использует nd_math.h internaly. И в основном отражает мой класс 3D-реперов, основанный на всех знаниях 4x4 однородных матриц преобразования , которые я приобрел с годами. Сам 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
//---------------------------------------------------------------------------

List <> template

Это просто шаблон контейнера линейного массива с саморазмещающимися свойствами, специально разработанный для многопоточности и быстрых операций со списком. Однако я не могу поделиться его исходным кодом, потому что это часть корпоративного кода ...

Вместо этого здесь шаблон stati c, который имитирует API, поэтому вы можете перекодировать его, используя любое линейное хранилище, которое есть в вашем распоряжении, например std::vector<> или что-то еще, или просто используйте это с распределением stati c вместо этого ...

//---------------------------------------------------------------------------
//--- 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 материал (доступ к файлам) в вашу среду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...