vertex.h 7.48 KB
/**
 * \file vertex.h
 *
 * \brief Definiert eine Klasse für einen Vertex und eine Klasse fü
 *        einen Vertexliste
 * 
 * Ein Vertex ist bei mir ein transformbares 4-Tupel, das sowohl einen Vektor
 * als auch eine Coordinate darstellen kann. Ich bezeichne beides als Vertex,
 * weil auch der Vektor einen Coordinate darstellen kann (falls man ihn als
 * Ursprungsvektor betrachtet)
 * Eine Vertexliste ist ein Container der Vertexe aufnehmen kann und
 * insbesondere zwei getrennte Sepicherbereiche zur aufnahme von Vertexen hat,
 * über die aber mit dem gleichen Zugriffsmechanismus zugegriffen wird.
 * Die wird gebraucht um leicht Vertexe für das clipping hinzufügen
 * zu können.
 *
 * \author Georg Steffers <georg@steffers.org> [gs]
 *
 * \date 16.12.2003
 *
 * \version ..2002 [gs]: erste Implementation
 * \version 16.12.2003 [gs]: <ul><li>
 *                           Beginn der Dokumentation mir Doxygen
 *                           </li><li>
 *                           Vertexlist zu einer zweiteiligen Liste gemacht,
 *                           damit Sie f&uuml;r clipping geeignet ist.
 *                           </li></ul>
 * \version 19.12.2003 [gs]: Vergleichsoperator hinzugef&uuml;gt und
 *                           clip_2d_mask rausgeshmissen.
 */

/* 
 * Copyright (C)2003 Georg Steffers
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __vertex_h__
#define __vertex_h__

#include "../math/Mmn.h"
#include "../math/V_K4.h"
#include "../helper/container.h"

#define X       0
#define Y       1
#define Z       2
#define W       3
#define O_X     4
#define O_Y     5
#define O_Z     6
#define O_W     7

//! W=0 hei&szlig;t der Vertex stellt einen Vektor dar.
#define VEKTOR  0
//! W=0 hei&szlig;t der Vertex stellt einen Coordinate dar.
#define COORD   1

class vertex {
    private:
        V_K4<double> original;
        V_K4<double> transformed;
        int trans_stage;
//        char clip_mask_2d;

    public:
        vertex() : trans_stage(0) {}
        vertex(double x, double y, double z, double w=VEKTOR) 
            : original(x,y,z,w), transformed(x,y,z,w), 
              trans_stage(0) {}
        vertex(const vertex& v) : original(v.original),
                                  transformed(v.transformed),
                                  trans_stage(v.trans_stage) {}

        const vertex& operator=(const vertex& v);
        const double& operator[](unsigned xyzw) const { 
            if(xyzw < X) { xyzw=X; }
            if(xyzw > O_W) { xyzw=O_W; }

            if(xyzw <= W)
                return transformed.a(xyzw, 0); 
            else
                return original.a(xyzw-O_X, 0);
        }
        double& operator[](unsigned xyzw) {
            if(xyzw < X) { xyzw=X; }
            if(xyzw > O_W) { xyzw=O_W; }

            if(xyzw <= W)
                return transformed.a(xyzw, 0); 
            else
                return original.a(xyzw-O_X, 0);
        }
        vertex operator*(const double&) const;
        friend vertex operator*(const double&, const vertex&);

        double operator% (const vertex&) const;
        vertex operator| (const vertex&) const;
        vertex operator+ (const vertex&) const;
        vertex operator- (const vertex&) const;
        bool operator== (const vertex& v) const {
           if(this->original == v.original &&
              this->transformed == v.transformed &&
              this->trans_stage == v.trans_stage)
              return true;

           return false;
        }

        vertex norm(void) const;
        double betr(void) const;

        void reset(void);
        void set_trans_stage(int p=0) { trans_stage=p; }
        unsigned get_trans_stage(void) const { return trans_stage; }
        V_K4<double> const& get_o(void) const {return original;}
        V_K4<double> const& get_t(void) const {return transformed;}

        void transform(const Mmn<double>&, int=0);
        void project_2d(double lcx, double sw, double sh, 
                        double ph_ar, double sy, int p);

        double unproject_X(double, double, double, double);
        double unproject_Y(double, double, double, double, double, double);
        double unproject_Z(double);
        double unproject_U(double, double, double, double);
        double unproject_V(double, double, double, double, double, double);

        void print() {
           original.print();
           transformed.print();
           cout << "---\n";
        }
};

vertex operator*(const double& a, const vertex& v);

class vertex_list : public container<vertex> {
    protected:
       vertex* variable;
       unsigned var_count;

    public:
        vertex_list() 
           : container<vertex>(), variable(NULL), var_count(0) {}
        vertex_list(const vertex& v) 
           : container<vertex>(v), variable(NULL), var_count(0) {}
        vertex_list(const vertex* idxs, unsigned count) 
           : container<vertex>(idxs, count), variable(NULL), var_count(0) {}
        vertex_list(const vertex_list& v) 
           : container<vertex>(v), var_count(v.var_count) {
            if(var_count > 0)
               variable=new vertex[var_count];
            else
               variable=NULL;
                        
            for(unsigned i=0; i<var_count; i++)
               variable[i]=v.variable[i];
        }
        ~vertex_list() {
            if(variable) {
               delete [] variable;
               variable=NULL;
               var_count=0;
            }
        }

        vertex& operator[](unsigned index) {
           if(index+1 <= count)
              return content[index];
           else
              index-=count-1;

            if(index+1 > var_count) {
                vertex* content_tmp=new vertex[index+1];

                for(unsigned i=0; i<var_count; i++)
                    content_tmp[i]=variable[i];

                delete [] variable;
                variable=content_tmp;
                var_count=index+1;
            }

            return variable[index];
        }

        void resize(unsigned size) {
            if(size < count) {
               if(variable) {
                  delete [] variable;
                  variable=NULL;
                  var_count=0;
               }
               return;
            }
            else
               size-=count;

            vertex* content_tmp;
            if(size>0) {
               content_tmp=new vertex[size];
     
               for(unsigned i=0; i<size<var_count?size:var_count; i++)
                   content_tmp[i]=variable[i];
            }
            else
               content_tmp=NULL;
  
            delete [] variable;
            variable=content_tmp;
            var_count=size;
        }

        unsigned fix_card(void) { return container<vertex>::card(); }
        unsigned var_card(void) { return var_count; }
        unsigned card(void) { return fix_card()+var_card(); }
        void reset(void);
};

#endif // __vertex_h__